Whamcloud - gitweb
LU-15471 tests: use propper facet device
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11671
61         ALWAYS_EXCEPT+=" 45"
62         # bug number:    LU-14067 LU-14067
63         ALWAYS_EXCEPT+=" 400a     400b"
64 fi
65
66 # skip nfs tests on kernels >= 4.12.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
68         # bug number:   LU-12661
69         ALWAYS_EXCEPT+=" 817"
70 fi
71 # skip cgroup tests on RHEL8.1 kernels until they are fixed
72 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
73       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
74         # bug number:   LU-13063
75         ALWAYS_EXCEPT+=" 411"
76 fi
77
78 #skip ACL tests on RHEL8 and SLES15 until tests changed to use other users
79 if (( $(egrep -cw "^bin|^daemon" /etc/passwd) < 2 )); then
80         # bug number:   LU-15259 LU-15259
81         ALWAYS_EXCEPT+=" 103a  125   154a"
82 fi
83
84 #                                  5              12     8   12  15   (min)"
85 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
86
87 if [ "$mds1_FSTYPE" = "zfs" ]; then
88         # bug number for skipped test:
89         ALWAYS_EXCEPT+="              "
90         #                                               13    (min)"
91         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
92 fi
93
94 if [ "$ost1_FSTYPE" = "zfs" ]; then
95         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
96         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
97 fi
98
99 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
100
101 # Get the SLES distro version
102 #
103 # Returns a version string that should only be used in comparing
104 # strings returned by version_code()
105 sles_version_code()
106 {
107         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
108
109         # All SuSE Linux versions have one decimal. version_code expects two
110         local sles_version=$version.0
111         version_code $sles_version
112 }
113
114 # Check if we are running on Ubuntu or SLES so we can make decisions on
115 # what tests to run
116 if [ -r /etc/SuSE-release ]; then
117         sles_version=$(sles_version_code)
118         [ $sles_version -lt $(version_code 11.4.0) ] &&
119                 # bug number for skipped test: LU-4341
120                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
121         [ $sles_version -lt $(version_code 12.0.0) ] &&
122                 # bug number for skipped test: LU-3703
123                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
124 elif [ -r /etc/os-release ]; then
125         if grep -qi ubuntu /etc/os-release; then
126                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
127                                                 -e 's/^VERSION=//p' \
128                                                 /etc/os-release |
129                                                 awk '{ print $1 }'))
130
131                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
132                         # bug number for skipped test:
133                         #                LU-10334 LU-10366
134                         ALWAYS_EXCEPT+=" 103a     410"
135                 fi
136         fi
137 fi
138
139 build_test_filter
140 FAIL_ON_ERROR=false
141
142 cleanup() {
143         echo -n "cln.."
144         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
145         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
146 }
147 setup() {
148         echo -n "mnt.."
149         load_modules
150         setupall || exit 10
151         echo "done"
152 }
153
154 check_swap_layouts_support()
155 {
156         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
157                 skip "Does not support layout lock."
158 }
159
160 check_swap_layout_no_dom()
161 {
162         local FOLDER=$1
163         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
164         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
165 }
166
167 check_and_setup_lustre
168 DIR=${DIR:-$MOUNT}
169 assert_DIR
170
171 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
172
173 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
174 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
175 rm -rf $DIR/[Rdfs][0-9]*
176
177 # $RUNAS_ID may get set incorrectly somewhere else
178 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
179         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
180
181 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
182
183 if [ "${ONLY}" = "MOUNT" ] ; then
184         echo "Lustre is up, please go on"
185         exit
186 fi
187
188 echo "preparing for tests involving mounts"
189 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
190 touch $EXT2_DEV
191 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
192 echo # add a newline after mke2fs.
193
194 umask 077
195
196 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
197 lctl set_param debug=-1 2> /dev/null || true
198 test_0a() {
199         touch $DIR/$tfile
200         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
201         rm $DIR/$tfile
202         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
203 }
204 run_test 0a "touch; rm ====================="
205
206 test_0b() {
207         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
208         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
209 }
210 run_test 0b "chmod 0755 $DIR ============================="
211
212 test_0c() {
213         $LCTL get_param mdc.*.import | grep "state: FULL" ||
214                 error "import not FULL"
215         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
216                 error "bad target"
217 }
218 run_test 0c "check import proc"
219
220 test_0d() { # LU-3397
221         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
222                 skip "proc exports not supported before 2.10.57"
223
224         local mgs_exp="mgs.MGS.exports"
225         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
226         local exp_client_nid
227         local exp_client_version
228         local exp_val
229         local imp_val
230         local temp_imp=$DIR/$tfile.import
231         local temp_exp=$DIR/$tfile.export
232
233         # save mgc import file to $temp_imp
234         $LCTL get_param mgc.*.import | tee $temp_imp
235         # Check if client uuid is found in MGS export
236         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
237                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
238                         $client_uuid ] &&
239                         break;
240         done
241         # save mgs export file to $temp_exp
242         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
243
244         # Compare the value of field "connect_flags"
245         imp_val=$(grep "connect_flags" $temp_imp)
246         exp_val=$(grep "connect_flags" $temp_exp)
247         [ "$exp_val" == "$imp_val" ] ||
248                 error "export flags '$exp_val' != import flags '$imp_val'"
249
250         # Compare client versions.  Only compare top-3 fields for compatibility
251         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
252         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
253         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
254         [ "$exp_val" == "$imp_val" ] ||
255                 error "exp version '$exp_client_version'($exp_val) != " \
256                         "'$(lustre_build_version client)'($imp_val)"
257 }
258 run_test 0d "check export proc ============================="
259
260 test_0e() { # LU-13417
261         (( $MDSCOUNT > 1 )) ||
262                 skip "We need at least 2 MDTs for this test"
263
264         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
265                 skip "Need server version at least 2.14.51"
266
267         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
268         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
269
270         [ $default_lmv_count -eq 1 ] ||
271                 error "$MOUNT default stripe count $default_lmv_count"
272
273         [ $default_lmv_index -eq -1 ] ||
274                 error "$MOUNT default stripe index $default_lmv_index"
275
276         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
277         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
278
279         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
280         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
281
282         [ $mdt_index1 -eq $mdt_index2 ] &&
283                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
284
285         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
286 }
287 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
288
289 test_1() {
290         test_mkdir $DIR/$tdir
291         test_mkdir $DIR/$tdir/d2
292         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
293         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
294         rmdir $DIR/$tdir/d2
295         rmdir $DIR/$tdir
296         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
297 }
298 run_test 1 "mkdir; remkdir; rmdir"
299
300 test_2() {
301         test_mkdir $DIR/$tdir
302         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
303         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
304         rm -r $DIR/$tdir
305         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
306 }
307 run_test 2 "mkdir; touch; rmdir; check file"
308
309 test_3() {
310         test_mkdir $DIR/$tdir
311         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
312         touch $DIR/$tdir/$tfile
313         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
314         rm -r $DIR/$tdir
315         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
316 }
317 run_test 3 "mkdir; touch; rmdir; check dir"
318
319 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
320 test_4() {
321         test_mkdir -i 1 $DIR/$tdir
322
323         touch $DIR/$tdir/$tfile ||
324                 error "Create file under remote directory failed"
325
326         rmdir $DIR/$tdir &&
327                 error "Expect error removing in-use dir $DIR/$tdir"
328
329         test -d $DIR/$tdir || error "Remote directory disappeared"
330
331         rm -rf $DIR/$tdir || error "remove remote dir error"
332 }
333 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
334
335 test_5() {
336         test_mkdir $DIR/$tdir
337         test_mkdir $DIR/$tdir/d2
338         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
339         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
340         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
341 }
342 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
343
344 test_6a() {
345         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
346         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
347         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
348                 error "$tfile does not have perm 0666 or UID $UID"
349         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
350         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
351                 error "$tfile should be 0666 and owned by UID $UID"
352 }
353 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
354
355 test_6c() {
356         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
357
358         touch $DIR/$tfile
359         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
360         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
361                 error "$tfile should be owned by UID $RUNAS_ID"
362         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
363         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
364                 error "$tfile should be owned by UID $RUNAS_ID"
365 }
366 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
367
368 test_6e() {
369         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
370
371         touch $DIR/$tfile
372         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
373         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
374                 error "$tfile should be owned by GID $UID"
375         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
376         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
377                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
378 }
379 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
380
381 test_6g() {
382         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
383
384         test_mkdir $DIR/$tdir
385         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
386         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
387         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
388         test_mkdir $DIR/$tdir/d/subdir
389         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
390                 error "$tdir/d/subdir should be GID $RUNAS_GID"
391         if [[ $MDSCOUNT -gt 1 ]]; then
392                 # check remote dir sgid inherite
393                 $LFS mkdir -i 0 $DIR/$tdir.local ||
394                         error "mkdir $tdir.local failed"
395                 chmod g+s $DIR/$tdir.local ||
396                         error "chmod $tdir.local failed"
397                 chgrp $RUNAS_GID $DIR/$tdir.local ||
398                         error "chgrp $tdir.local failed"
399                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
400                         error "mkdir $tdir.remote failed"
401                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
402                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
403                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
404                         error "$tdir.remote should be mode 02755"
405         fi
406 }
407 run_test 6g "verify new dir in sgid dir inherits group"
408
409 test_6h() { # bug 7331
410         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
411
412         touch $DIR/$tfile || error "touch failed"
413         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
414         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
415                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
416         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
417                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
418 }
419 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
420
421 test_7a() {
422         test_mkdir $DIR/$tdir
423         $MCREATE $DIR/$tdir/$tfile
424         chmod 0666 $DIR/$tdir/$tfile
425         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
426                 error "$tdir/$tfile should be mode 0666"
427 }
428 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
429
430 test_7b() {
431         if [ ! -d $DIR/$tdir ]; then
432                 test_mkdir $DIR/$tdir
433         fi
434         $MCREATE $DIR/$tdir/$tfile
435         echo -n foo > $DIR/$tdir/$tfile
436         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
437         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
438 }
439 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
440
441 test_8() {
442         test_mkdir $DIR/$tdir
443         touch $DIR/$tdir/$tfile
444         chmod 0666 $DIR/$tdir/$tfile
445         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
446                 error "$tfile mode not 0666"
447 }
448 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
449
450 test_9() {
451         test_mkdir $DIR/$tdir
452         test_mkdir $DIR/$tdir/d2
453         test_mkdir $DIR/$tdir/d2/d3
454         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
455 }
456 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
457
458 test_10() {
459         test_mkdir $DIR/$tdir
460         test_mkdir $DIR/$tdir/d2
461         touch $DIR/$tdir/d2/$tfile
462         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
463                 error "$tdir/d2/$tfile not a file"
464 }
465 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
466
467 test_11() {
468         test_mkdir $DIR/$tdir
469         test_mkdir $DIR/$tdir/d2
470         chmod 0666 $DIR/$tdir/d2
471         chmod 0705 $DIR/$tdir/d2
472         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
473                 error "$tdir/d2 mode not 0705"
474 }
475 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
476
477 test_12() {
478         test_mkdir $DIR/$tdir
479         touch $DIR/$tdir/$tfile
480         chmod 0666 $DIR/$tdir/$tfile
481         chmod 0654 $DIR/$tdir/$tfile
482         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
483                 error "$tdir/d2 mode not 0654"
484 }
485 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
486
487 test_13() {
488         test_mkdir $DIR/$tdir
489         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
490         >  $DIR/$tdir/$tfile
491         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
492                 error "$tdir/$tfile size not 0 after truncate"
493 }
494 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
495
496 test_14() {
497         test_mkdir $DIR/$tdir
498         touch $DIR/$tdir/$tfile
499         rm $DIR/$tdir/$tfile
500         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
501 }
502 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
503
504 test_15() {
505         test_mkdir $DIR/$tdir
506         touch $DIR/$tdir/$tfile
507         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
508         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
509                 error "$tdir/${tfile_2} not a file after rename"
510         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
511 }
512 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
513
514 test_16() {
515         test_mkdir $DIR/$tdir
516         touch $DIR/$tdir/$tfile
517         rm -rf $DIR/$tdir/$tfile
518         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
519 }
520 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
521
522 test_17a() {
523         test_mkdir $DIR/$tdir
524         touch $DIR/$tdir/$tfile
525         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
526         ls -l $DIR/$tdir
527         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
528                 error "$tdir/l-exist not a symlink"
529         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
530                 error "$tdir/l-exist not referencing a file"
531         rm -f $DIR/$tdir/l-exist
532         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
533 }
534 run_test 17a "symlinks: create, remove (real)"
535
536 test_17b() {
537         test_mkdir $DIR/$tdir
538         ln -s no-such-file $DIR/$tdir/l-dangle
539         ls -l $DIR/$tdir
540         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
541                 error "$tdir/l-dangle not referencing no-such-file"
542         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
543                 error "$tdir/l-dangle not referencing non-existent file"
544         rm -f $DIR/$tdir/l-dangle
545         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
546 }
547 run_test 17b "symlinks: create, remove (dangling)"
548
549 test_17c() { # bug 3440 - don't save failed open RPC for replay
550         test_mkdir $DIR/$tdir
551         ln -s foo $DIR/$tdir/$tfile
552         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
553 }
554 run_test 17c "symlinks: open dangling (should return error)"
555
556 test_17d() {
557         test_mkdir $DIR/$tdir
558         ln -s foo $DIR/$tdir/$tfile
559         touch $DIR/$tdir/$tfile || error "creating to new symlink"
560 }
561 run_test 17d "symlinks: create dangling"
562
563 test_17e() {
564         test_mkdir $DIR/$tdir
565         local foo=$DIR/$tdir/$tfile
566         ln -s $foo $foo || error "create symlink failed"
567         ls -l $foo || error "ls -l failed"
568         ls $foo && error "ls not failed" || true
569 }
570 run_test 17e "symlinks: create recursive symlink (should return error)"
571
572 test_17f() {
573         test_mkdir $DIR/$tdir
574         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
575         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
576         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
577         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
578         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
579         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
580         ls -l  $DIR/$tdir
581 }
582 run_test 17f "symlinks: long and very long symlink name"
583
584 # str_repeat(S, N) generate a string that is string S repeated N times
585 str_repeat() {
586         local s=$1
587         local n=$2
588         local ret=''
589         while [ $((n -= 1)) -ge 0 ]; do
590                 ret=$ret$s
591         done
592         echo $ret
593 }
594
595 # Long symlinks and LU-2241
596 test_17g() {
597         test_mkdir $DIR/$tdir
598         local TESTS="59 60 61 4094 4095"
599
600         # Fix for inode size boundary in 2.1.4
601         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
602                 TESTS="4094 4095"
603
604         # Patch not applied to 2.2 or 2.3 branches
605         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
606         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
607                 TESTS="4094 4095"
608
609         for i in $TESTS; do
610                 local SYMNAME=$(str_repeat 'x' $i)
611                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
612                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
613         done
614 }
615 run_test 17g "symlinks: really long symlink name and inode boundaries"
616
617 test_17h() { #bug 17378
618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
619         remote_mds_nodsh && skip "remote MDS with nodsh"
620
621         local mdt_idx
622
623         test_mkdir $DIR/$tdir
624         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
625         $LFS setstripe -c -1 $DIR/$tdir
626         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
627         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
628         touch $DIR/$tdir/$tfile || true
629 }
630 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
631
632 test_17i() { #bug 20018
633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
634         remote_mds_nodsh && skip "remote MDS with nodsh"
635
636         local foo=$DIR/$tdir/$tfile
637         local mdt_idx
638
639         test_mkdir -c1 $DIR/$tdir
640         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
641         ln -s $foo $foo || error "create symlink failed"
642 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
643         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
644         ls -l $foo && error "error not detected"
645         return 0
646 }
647 run_test 17i "don't panic on short symlink (should return error)"
648
649 test_17k() { #bug 22301
650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
651         [[ -z "$(which rsync 2>/dev/null)" ]] &&
652                 skip "no rsync command"
653         rsync --help | grep -q xattr ||
654                 skip_env "$(rsync --version | head -n1) does not support xattrs"
655         test_mkdir $DIR/$tdir
656         test_mkdir $DIR/$tdir.new
657         touch $DIR/$tdir/$tfile
658         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
659         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
660                 error "rsync failed with xattrs enabled"
661 }
662 run_test 17k "symlinks: rsync with xattrs enabled"
663
664 test_17l() { # LU-279
665         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
666                 skip "no getfattr command"
667
668         test_mkdir $DIR/$tdir
669         touch $DIR/$tdir/$tfile
670         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
671         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
672                 # -h to not follow symlinks. -m '' to list all the xattrs.
673                 # grep to remove first line: '# file: $path'.
674                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
675                 do
676                         lgetxattr_size_check $path $xattr ||
677                                 error "lgetxattr_size_check $path $xattr failed"
678                 done
679         done
680 }
681 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
682
683 # LU-1540
684 test_17m() {
685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
686         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
687         remote_mds_nodsh && skip "remote MDS with nodsh"
688         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
689         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
690                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
691
692         local short_sym="0123456789"
693         local wdir=$DIR/$tdir
694         local i
695
696         test_mkdir $wdir
697         long_sym=$short_sym
698         # create a long symlink file
699         for ((i = 0; i < 4; ++i)); do
700                 long_sym=${long_sym}${long_sym}
701         done
702
703         echo "create 512 short and long symlink files under $wdir"
704         for ((i = 0; i < 256; ++i)); do
705                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
706                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
707         done
708
709         echo "erase them"
710         rm -f $wdir/*
711         sync
712         wait_delete_completed
713
714         echo "recreate the 512 symlink files with a shorter string"
715         for ((i = 0; i < 512; ++i)); do
716                 # rewrite the symlink file with a shorter string
717                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
718                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
719         done
720
721         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
722
723         echo "stop and checking mds${mds_index}:"
724         # e2fsck should not return error
725         stop mds${mds_index}
726         local devname=$(mdsdevname $mds_index)
727         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
728         rc=$?
729
730         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
731                 error "start mds${mds_index} failed"
732         df $MOUNT > /dev/null 2>&1
733         [ $rc -eq 0 ] ||
734                 error "e2fsck detected error for short/long symlink: rc=$rc"
735         rm -f $wdir/*
736 }
737 run_test 17m "run e2fsck against MDT which contains short/long symlink"
738
739 check_fs_consistency_17n() {
740         local mdt_index
741         local rc=0
742
743         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
744         # so it only check MDT1/MDT2 instead of all of MDTs.
745         for mdt_index in 1 2; do
746                 # e2fsck should not return error
747                 stop mds${mdt_index}
748                 local devname=$(mdsdevname $mdt_index)
749                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
750                         rc=$((rc + $?))
751
752                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
753                         error "mount mds$mdt_index failed"
754                 df $MOUNT > /dev/null 2>&1
755         done
756         return $rc
757 }
758
759 test_17n() {
760         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
762         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
763         remote_mds_nodsh && skip "remote MDS with nodsh"
764         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
765         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
766                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
767
768         local i
769
770         test_mkdir $DIR/$tdir
771         for ((i=0; i<10; i++)); do
772                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
773                         error "create remote dir error $i"
774                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
775                         error "create files under remote dir failed $i"
776         done
777
778         check_fs_consistency_17n ||
779                 error "e2fsck report error after create files under remote dir"
780
781         for ((i = 0; i < 10; i++)); do
782                 rm -rf $DIR/$tdir/remote_dir_${i} ||
783                         error "destroy remote dir error $i"
784         done
785
786         check_fs_consistency_17n ||
787                 error "e2fsck report error after unlink files under remote dir"
788
789         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
790                 skip "lustre < 2.4.50 does not support migrate mv"
791
792         for ((i = 0; i < 10; i++)); do
793                 mkdir -p $DIR/$tdir/remote_dir_${i}
794                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
795                         error "create files under remote dir failed $i"
796                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
797                         error "migrate remote dir error $i"
798         done
799         check_fs_consistency_17n || error "e2fsck report error after migration"
800
801         for ((i = 0; i < 10; i++)); do
802                 rm -rf $DIR/$tdir/remote_dir_${i} ||
803                         error "destroy remote dir error $i"
804         done
805
806         check_fs_consistency_17n || error "e2fsck report error after unlink"
807 }
808 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
809
810 test_17o() {
811         remote_mds_nodsh && skip "remote MDS with nodsh"
812         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
813                 skip "Need MDS version at least 2.3.64"
814
815         local wdir=$DIR/${tdir}o
816         local mdt_index
817         local rc=0
818
819         test_mkdir $wdir
820         touch $wdir/$tfile
821         mdt_index=$($LFS getstripe -m $wdir/$tfile)
822         mdt_index=$((mdt_index + 1))
823
824         cancel_lru_locks mdc
825         #fail mds will wait the failover finish then set
826         #following fail_loc to avoid interfer the recovery process.
827         fail mds${mdt_index}
828
829         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
830         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
831         ls -l $wdir/$tfile && rc=1
832         do_facet mds${mdt_index} lctl set_param fail_loc=0
833         [[ $rc -eq 0 ]] || error "stat file should fail"
834 }
835 run_test 17o "stat file with incompat LMA feature"
836
837 test_18() {
838         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
839         ls $DIR || error "Failed to ls $DIR: $?"
840 }
841 run_test 18 "touch .../f ; ls ... =============================="
842
843 test_19a() {
844         touch $DIR/$tfile
845         ls -l $DIR
846         rm $DIR/$tfile
847         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
848 }
849 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
850
851 test_19b() {
852         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
853 }
854 run_test 19b "ls -l .../f19 (should return error) =============="
855
856 test_19c() {
857         [ $RUNAS_ID -eq $UID ] &&
858                 skip_env "RUNAS_ID = UID = $UID -- skipping"
859
860         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
861 }
862 run_test 19c "$RUNAS touch .../f19 (should return error) =="
863
864 test_19d() {
865         cat $DIR/f19 && error || true
866 }
867 run_test 19d "cat .../f19 (should return error) =============="
868
869 test_20() {
870         touch $DIR/$tfile
871         rm $DIR/$tfile
872         touch $DIR/$tfile
873         rm $DIR/$tfile
874         touch $DIR/$tfile
875         rm $DIR/$tfile
876         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
877 }
878 run_test 20 "touch .../f ; ls -l ..."
879
880 test_21() {
881         test_mkdir $DIR/$tdir
882         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
883         ln -s dangle $DIR/$tdir/link
884         echo foo >> $DIR/$tdir/link
885         cat $DIR/$tdir/dangle
886         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
887         $CHECKSTAT -f -t file $DIR/$tdir/link ||
888                 error "$tdir/link not linked to a file"
889 }
890 run_test 21 "write to dangling link"
891
892 test_22() {
893         local wdir=$DIR/$tdir
894         test_mkdir $wdir
895         chown $RUNAS_ID:$RUNAS_GID $wdir
896         (cd $wdir || error "cd $wdir failed";
897                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
898                 $RUNAS tar xf -)
899         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
900         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
901         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
902                 error "checkstat -u failed"
903 }
904 run_test 22 "unpack tar archive as non-root user"
905
906 # was test_23
907 test_23a() {
908         test_mkdir $DIR/$tdir
909         local file=$DIR/$tdir/$tfile
910
911         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
912         openfile -f O_CREAT:O_EXCL $file &&
913                 error "$file recreate succeeded" || true
914 }
915 run_test 23a "O_CREAT|O_EXCL in subdir"
916
917 test_23b() { # bug 18988
918         test_mkdir $DIR/$tdir
919         local file=$DIR/$tdir/$tfile
920
921         rm -f $file
922         echo foo > $file || error "write filed"
923         echo bar >> $file || error "append filed"
924         $CHECKSTAT -s 8 $file || error "wrong size"
925         rm $file
926 }
927 run_test 23b "O_APPEND check"
928
929 # LU-9409, size with O_APPEND and tiny writes
930 test_23c() {
931         local file=$DIR/$tfile
932
933         # single dd
934         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
935         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
936         rm -f $file
937
938         # racing tiny writes
939         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
940         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
941         wait
942         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
943         rm -f $file
944
945         #racing tiny & normal writes
946         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
947         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
948         wait
949         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
950         rm -f $file
951
952         #racing tiny & normal writes 2, ugly numbers
953         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
954         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
955         wait
956         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
957         rm -f $file
958 }
959 run_test 23c "O_APPEND size checks for tiny writes"
960
961 # LU-11069 file offset is correct after appending writes
962 test_23d() {
963         local file=$DIR/$tfile
964         local offset
965
966         echo CentaurHauls > $file
967         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
968         if ((offset != 26)); then
969                 error "wrong offset, expected 26, got '$offset'"
970         fi
971 }
972 run_test 23d "file offset is correct after appending writes"
973
974 # rename sanity
975 test_24a() {
976         echo '-- same directory rename'
977         test_mkdir $DIR/$tdir
978         touch $DIR/$tdir/$tfile.1
979         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
980         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
981 }
982 run_test 24a "rename file to non-existent target"
983
984 test_24b() {
985         test_mkdir $DIR/$tdir
986         touch $DIR/$tdir/$tfile.{1,2}
987         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
988         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
989         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
990 }
991 run_test 24b "rename file to existing target"
992
993 test_24c() {
994         test_mkdir $DIR/$tdir
995         test_mkdir $DIR/$tdir/d$testnum.1
996         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
997         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
998         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
999 }
1000 run_test 24c "rename directory to non-existent target"
1001
1002 test_24d() {
1003         test_mkdir -c1 $DIR/$tdir
1004         test_mkdir -c1 $DIR/$tdir/d$testnum.1
1005         test_mkdir -c1 $DIR/$tdir/d$testnum.2
1006         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1007         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1008         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1009 }
1010 run_test 24d "rename directory to existing target"
1011
1012 test_24e() {
1013         echo '-- cross directory renames --'
1014         test_mkdir $DIR/R5a
1015         test_mkdir $DIR/R5b
1016         touch $DIR/R5a/f
1017         mv $DIR/R5a/f $DIR/R5b/g
1018         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1019         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1020 }
1021 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1022
1023 test_24f() {
1024         test_mkdir $DIR/R6a
1025         test_mkdir $DIR/R6b
1026         touch $DIR/R6a/f $DIR/R6b/g
1027         mv $DIR/R6a/f $DIR/R6b/g
1028         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1029         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1030 }
1031 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1032
1033 test_24g() {
1034         test_mkdir $DIR/R7a
1035         test_mkdir $DIR/R7b
1036         test_mkdir $DIR/R7a/d
1037         mv $DIR/R7a/d $DIR/R7b/e
1038         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1039         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1040 }
1041 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1042
1043 test_24h() {
1044         test_mkdir -c1 $DIR/R8a
1045         test_mkdir -c1 $DIR/R8b
1046         test_mkdir -c1 $DIR/R8a/d
1047         test_mkdir -c1 $DIR/R8b/e
1048         mrename $DIR/R8a/d $DIR/R8b/e
1049         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1050         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1051 }
1052 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1053
1054 test_24i() {
1055         echo "-- rename error cases"
1056         test_mkdir $DIR/R9
1057         test_mkdir $DIR/R9/a
1058         touch $DIR/R9/f
1059         mrename $DIR/R9/f $DIR/R9/a
1060         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1061         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1062         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1063 }
1064 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1065
1066 test_24j() {
1067         test_mkdir $DIR/R10
1068         mrename $DIR/R10/f $DIR/R10/g
1069         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1070         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1071         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1072 }
1073 run_test 24j "source does not exist ============================"
1074
1075 test_24k() {
1076         test_mkdir $DIR/R11a
1077         test_mkdir $DIR/R11a/d
1078         touch $DIR/R11a/f
1079         mv $DIR/R11a/f $DIR/R11a/d
1080         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1081         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1082 }
1083 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1084
1085 # bug 2429 - rename foo foo foo creates invalid file
1086 test_24l() {
1087         f="$DIR/f24l"
1088         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1089 }
1090 run_test 24l "Renaming a file to itself ========================"
1091
1092 test_24m() {
1093         f="$DIR/f24m"
1094         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1095         # on ext3 this does not remove either the source or target files
1096         # though the "expected" operation would be to remove the source
1097         $CHECKSTAT -t file ${f} || error "${f} missing"
1098         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1099 }
1100 run_test 24m "Renaming a file to a hard link to itself ========="
1101
1102 test_24n() {
1103     f="$DIR/f24n"
1104     # this stats the old file after it was renamed, so it should fail
1105     touch ${f}
1106     $CHECKSTAT ${f} || error "${f} missing"
1107     mv ${f} ${f}.rename
1108     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1109     $CHECKSTAT -a ${f} || error "${f} exists"
1110 }
1111 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1112
1113 test_24o() {
1114         test_mkdir $DIR/$tdir
1115         rename_many -s random -v -n 10 $DIR/$tdir
1116 }
1117 run_test 24o "rename of files during htree split"
1118
1119 test_24p() {
1120         test_mkdir $DIR/R12a
1121         test_mkdir $DIR/R12b
1122         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1123         mrename $DIR/R12a $DIR/R12b
1124         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1125         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1126         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1127         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1128 }
1129 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1130
1131 cleanup_multiop_pause() {
1132         trap 0
1133         kill -USR1 $MULTIPID
1134 }
1135
1136 test_24q() {
1137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1138
1139         test_mkdir $DIR/R13a
1140         test_mkdir $DIR/R13b
1141         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1142         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1143         MULTIPID=$!
1144
1145         trap cleanup_multiop_pause EXIT
1146         mrename $DIR/R13a $DIR/R13b
1147         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1148         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1149         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1150         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1151         cleanup_multiop_pause
1152         wait $MULTIPID || error "multiop close failed"
1153 }
1154 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1155
1156 test_24r() { #bug 3789
1157         test_mkdir $DIR/R14a
1158         test_mkdir $DIR/R14a/b
1159         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1160         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1161         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1162 }
1163 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1164
1165 test_24s() {
1166         test_mkdir $DIR/R15a
1167         test_mkdir $DIR/R15a/b
1168         test_mkdir $DIR/R15a/b/c
1169         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1170         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1171         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1172 }
1173 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1174 test_24t() {
1175         test_mkdir $DIR/R16a
1176         test_mkdir $DIR/R16a/b
1177         test_mkdir $DIR/R16a/b/c
1178         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1179         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1180         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1181 }
1182 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1183
1184 test_24u() { # bug12192
1185         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1186         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1187 }
1188 run_test 24u "create stripe file"
1189
1190 simple_cleanup_common() {
1191         local createmany=$1
1192         local rc=0
1193
1194         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1195
1196         local start=$SECONDS
1197
1198         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1199         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1200         rc=$?
1201         wait_delete_completed
1202         echo "cleanup time $((SECONDS - start))"
1203         return $rc
1204 }
1205
1206 max_pages_per_rpc() {
1207         local mdtname="$(printf "MDT%04x" ${1:-0})"
1208         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1209 }
1210
1211 test_24v() {
1212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1213
1214         local nrfiles=${COUNT:-100000}
1215         local fname="$DIR/$tdir/$tfile"
1216
1217         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1218         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1219
1220         test_mkdir "$(dirname $fname)"
1221         # assume MDT0000 has the fewest inodes
1222         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1223         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1224         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1225
1226         stack_trap "simple_cleanup_common $nrfiles"
1227
1228         createmany -m "$fname" $nrfiles
1229
1230         cancel_lru_locks mdc
1231         lctl set_param mdc.*.stats clear
1232
1233         # was previously test_24D: LU-6101
1234         # readdir() returns correct number of entries after cursor reload
1235         local num_ls=$(ls $DIR/$tdir | wc -l)
1236         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1237         local num_all=$(ls -a $DIR/$tdir | wc -l)
1238         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1239                 [ $num_all -ne $((nrfiles + 2)) ]; then
1240                         error "Expected $nrfiles files, got $num_ls " \
1241                                 "($num_uniq unique $num_all .&..)"
1242         fi
1243         # LU-5 large readdir
1244         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1245         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1246         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1247         # take into account of overhead in lu_dirpage header and end mark in
1248         # each page, plus one in rpc_num calculation.
1249         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1250         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1251         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1252         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1253         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1254         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1255         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1256         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1257                 error "large readdir doesn't take effect: " \
1258                       "$mds_readpage should be about $rpc_max"
1259 }
1260 run_test 24v "list large directory (test hash collision, b=17560)"
1261
1262 test_24w() { # bug21506
1263         SZ1=234852
1264         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1265         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1266         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1267         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1268         [[ "$SZ1" -eq "$SZ2" ]] ||
1269                 error "Error reading at the end of the file $tfile"
1270 }
1271 run_test 24w "Reading a file larger than 4Gb"
1272
1273 test_24x() {
1274         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1276         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1277                 skip "Need MDS version at least 2.7.56"
1278
1279         local MDTIDX=1
1280         local remote_dir=$DIR/$tdir/remote_dir
1281
1282         test_mkdir $DIR/$tdir
1283         $LFS mkdir -i $MDTIDX $remote_dir ||
1284                 error "create remote directory failed"
1285
1286         test_mkdir $DIR/$tdir/src_dir
1287         touch $DIR/$tdir/src_file
1288         test_mkdir $remote_dir/tgt_dir
1289         touch $remote_dir/tgt_file
1290
1291         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1292                 error "rename dir cross MDT failed!"
1293
1294         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1295                 error "rename file cross MDT failed!"
1296
1297         touch $DIR/$tdir/ln_file
1298         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1299                 error "ln file cross MDT failed"
1300
1301         rm -rf $DIR/$tdir || error "Can not delete directories"
1302 }
1303 run_test 24x "cross MDT rename/link"
1304
1305 test_24y() {
1306         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1308
1309         local remote_dir=$DIR/$tdir/remote_dir
1310         local mdtidx=1
1311
1312         test_mkdir $DIR/$tdir
1313         $LFS mkdir -i $mdtidx $remote_dir ||
1314                 error "create remote directory failed"
1315
1316         test_mkdir $remote_dir/src_dir
1317         touch $remote_dir/src_file
1318         test_mkdir $remote_dir/tgt_dir
1319         touch $remote_dir/tgt_file
1320
1321         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1322                 error "rename subdir in the same remote dir failed!"
1323
1324         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1325                 error "rename files in the same remote dir failed!"
1326
1327         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1328                 error "link files in the same remote dir failed!"
1329
1330         rm -rf $DIR/$tdir || error "Can not delete directories"
1331 }
1332 run_test 24y "rename/link on the same dir should succeed"
1333
1334 test_24z() {
1335         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1336         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1337                 skip "Need MDS version at least 2.12.51"
1338
1339         local index
1340
1341         for index in 0 1; do
1342                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1343                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1344         done
1345
1346         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1347
1348         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1349         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1350
1351         local mdts=$(comma_list $(mdts_nodes))
1352
1353         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1354         stack_trap "do_nodes $mdts $LCTL \
1355                 set_param mdt.*.enable_remote_rename=1" EXIT
1356
1357         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1358
1359         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1360         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1361 }
1362 run_test 24z "cross-MDT rename is done as cp"
1363
1364 test_24A() { # LU-3182
1365         local NFILES=5000
1366
1367         test_mkdir $DIR/$tdir
1368         stack_trap "simple_cleanup_common $NFILES"
1369         createmany -m $DIR/$tdir/$tfile $NFILES
1370         local t=$(ls $DIR/$tdir | wc -l)
1371         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1372         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1373
1374         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1375                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1376 }
1377 run_test 24A "readdir() returns correct number of entries."
1378
1379 test_24B() { # LU-4805
1380         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1381
1382         local count
1383
1384         test_mkdir $DIR/$tdir
1385         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1386                 error "create striped dir failed"
1387
1388         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1389         [ $count -eq 2 ] || error "Expected 2, got $count"
1390
1391         touch $DIR/$tdir/striped_dir/a
1392
1393         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1394         [ $count -eq 3 ] || error "Expected 3, got $count"
1395
1396         touch $DIR/$tdir/striped_dir/.f
1397
1398         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1399         [ $count -eq 4 ] || error "Expected 4, got $count"
1400
1401         rm -rf $DIR/$tdir || error "Can not delete directories"
1402 }
1403 run_test 24B "readdir for striped dir return correct number of entries"
1404
1405 test_24C() {
1406         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1407
1408         mkdir $DIR/$tdir
1409         mkdir $DIR/$tdir/d0
1410         mkdir $DIR/$tdir/d1
1411
1412         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1413                 error "create striped dir failed"
1414
1415         cd $DIR/$tdir/d0/striped_dir
1416
1417         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1418         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1419         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1420
1421         [ "$d0_ino" = "$parent_ino" ] ||
1422                 error ".. wrong, expect $d0_ino, get $parent_ino"
1423
1424         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1425                 error "mv striped dir failed"
1426
1427         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1428
1429         [ "$d1_ino" = "$parent_ino" ] ||
1430                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1431 }
1432 run_test 24C "check .. in striped dir"
1433
1434 test_24E() {
1435         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1437
1438         mkdir -p $DIR/$tdir
1439         mkdir $DIR/$tdir/src_dir
1440         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1441                 error "create remote source failed"
1442
1443         touch $DIR/$tdir/src_dir/src_child/a
1444
1445         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1446                 error "create remote target dir failed"
1447
1448         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1449                 error "create remote target child failed"
1450
1451         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1452                 error "rename dir cross MDT failed!"
1453
1454         find $DIR/$tdir
1455
1456         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1457                 error "src_child still exists after rename"
1458
1459         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1460                 error "missing file(a) after rename"
1461
1462         rm -rf $DIR/$tdir || error "Can not delete directories"
1463 }
1464 run_test 24E "cross MDT rename/link"
1465
1466 test_24F () {
1467         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1468
1469         local repeats=1000
1470         [ "$SLOW" = "no" ] && repeats=100
1471
1472         mkdir -p $DIR/$tdir
1473
1474         echo "$repeats repeats"
1475         for ((i = 0; i < repeats; i++)); do
1476                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1477                 touch $DIR/$tdir/test/a || error "touch fails"
1478                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1479                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1480         done
1481
1482         true
1483 }
1484 run_test 24F "hash order vs readdir (LU-11330)"
1485
1486 test_24G () {
1487         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1488
1489         local ino1
1490         local ino2
1491
1492         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1493         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1494         touch $DIR/$tdir-0/f1 || error "touch f1"
1495         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1496         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1497         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1498         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1499         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1500 }
1501 run_test 24G "migrate symlink in rename"
1502
1503 test_24H() {
1504         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1505         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1506                 skip "MDT1 should be on another node"
1507
1508         test_mkdir -i 1 -c 1 $DIR/$tdir
1509 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1510         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1511         touch $DIR/$tdir/$tfile || error "touch failed"
1512 }
1513 run_test 24H "repeat FLD_QUERY rpc"
1514
1515 test_25a() {
1516         echo '== symlink sanity ============================================='
1517
1518         test_mkdir $DIR/d25
1519         ln -s d25 $DIR/s25
1520         touch $DIR/s25/foo ||
1521                 error "File creation in symlinked directory failed"
1522 }
1523 run_test 25a "create file in symlinked directory ==============="
1524
1525 test_25b() {
1526         [ ! -d $DIR/d25 ] && test_25a
1527         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1528 }
1529 run_test 25b "lookup file in symlinked directory ==============="
1530
1531 test_26a() {
1532         test_mkdir $DIR/d26
1533         test_mkdir $DIR/d26/d26-2
1534         ln -s d26/d26-2 $DIR/s26
1535         touch $DIR/s26/foo || error "File creation failed"
1536 }
1537 run_test 26a "multiple component symlink ======================="
1538
1539 test_26b() {
1540         test_mkdir -p $DIR/$tdir/d26-2
1541         ln -s $tdir/d26-2/foo $DIR/s26-2
1542         touch $DIR/s26-2 || error "File creation failed"
1543 }
1544 run_test 26b "multiple component symlink at end of lookup ======"
1545
1546 test_26c() {
1547         test_mkdir $DIR/d26.2
1548         touch $DIR/d26.2/foo
1549         ln -s d26.2 $DIR/s26.2-1
1550         ln -s s26.2-1 $DIR/s26.2-2
1551         ln -s s26.2-2 $DIR/s26.2-3
1552         chmod 0666 $DIR/s26.2-3/foo
1553 }
1554 run_test 26c "chain of symlinks"
1555
1556 # recursive symlinks (bug 439)
1557 test_26d() {
1558         ln -s d26-3/foo $DIR/d26-3
1559 }
1560 run_test 26d "create multiple component recursive symlink"
1561
1562 test_26e() {
1563         [ ! -h $DIR/d26-3 ] && test_26d
1564         rm $DIR/d26-3
1565 }
1566 run_test 26e "unlink multiple component recursive symlink"
1567
1568 # recursive symlinks (bug 7022)
1569 test_26f() {
1570         test_mkdir $DIR/$tdir
1571         test_mkdir $DIR/$tdir/$tfile
1572         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1573         test_mkdir -p lndir/bar1
1574         test_mkdir $DIR/$tdir/$tfile/$tfile
1575         cd $tfile                || error "cd $tfile failed"
1576         ln -s .. dotdot          || error "ln dotdot failed"
1577         ln -s dotdot/lndir lndir || error "ln lndir failed"
1578         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1579         output=`ls $tfile/$tfile/lndir/bar1`
1580         [ "$output" = bar1 ] && error "unexpected output"
1581         rm -r $tfile             || error "rm $tfile failed"
1582         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1583 }
1584 run_test 26f "rm -r of a directory which has recursive symlink"
1585
1586 test_27a() {
1587         test_mkdir $DIR/$tdir
1588         $LFS getstripe $DIR/$tdir
1589         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1590         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1591         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1592 }
1593 run_test 27a "one stripe file"
1594
1595 test_27b() {
1596         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1597
1598         test_mkdir $DIR/$tdir
1599         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1600         $LFS getstripe -c $DIR/$tdir/$tfile
1601         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1602                 error "two-stripe file doesn't have two stripes"
1603
1604         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1605 }
1606 run_test 27b "create and write to two stripe file"
1607
1608 # 27c family tests specific striping, setstripe -o
1609 test_27ca() {
1610         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1611         test_mkdir -p $DIR/$tdir
1612         local osts="1"
1613
1614         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1615         $LFS getstripe -i $DIR/$tdir/$tfile
1616         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1617                 error "stripe not on specified OST"
1618
1619         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1620 }
1621 run_test 27ca "one stripe on specified OST"
1622
1623 test_27cb() {
1624         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1625         test_mkdir -p $DIR/$tdir
1626         local osts="1,0"
1627         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1628         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1629         echo "$getstripe"
1630
1631         # Strip getstripe output to a space separated list of OSTs
1632         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1633                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1634         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1635                 error "stripes not on specified OSTs"
1636
1637         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1638 }
1639 run_test 27cb "two stripes on specified OSTs"
1640
1641 test_27cc() {
1642         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1643         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1644                 skip "server does not support overstriping"
1645
1646         test_mkdir -p $DIR/$tdir
1647         local osts="0,0"
1648         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1649         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1650         echo "$getstripe"
1651
1652         # Strip getstripe output to a space separated list of OSTs
1653         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1654                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1655         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1656                 error "stripes not on specified OSTs"
1657
1658         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1659 }
1660 run_test 27cc "two stripes on the same OST"
1661
1662 test_27cd() {
1663         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1664         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1665                 skip "server does not support overstriping"
1666         test_mkdir -p $DIR/$tdir
1667         local osts="0,1,1,0"
1668         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1669         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1670         echo "$getstripe"
1671
1672         # Strip getstripe output to a space separated list of OSTs
1673         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1674                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1675         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1676                 error "stripes not on specified OSTs"
1677
1678         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1679 }
1680 run_test 27cd "four stripes on two OSTs"
1681
1682 test_27ce() {
1683         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1684                 skip_env "too many osts, skipping"
1685         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1686                 skip "server does not support overstriping"
1687         # We do one more stripe than we have OSTs
1688         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1689                 skip_env "ea_inode feature disabled"
1690
1691         test_mkdir -p $DIR/$tdir
1692         local osts=""
1693         for i in $(seq 0 $OSTCOUNT);
1694         do
1695                 osts=$osts"0"
1696                 if [ $i -ne $OSTCOUNT ]; then
1697                         osts=$osts","
1698                 fi
1699         done
1700         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1701         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1702         echo "$getstripe"
1703
1704         # Strip getstripe output to a space separated list of OSTs
1705         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1706                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1707         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1708                 error "stripes not on specified OSTs"
1709
1710         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1711 }
1712 run_test 27ce "more stripes than OSTs with -o"
1713
1714 test_27cf() {
1715         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1716         local pid=0
1717
1718         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1719         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1720         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1721         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1722                 error "failed to set $osp_proc=0"
1723
1724         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1725         pid=$!
1726         sleep 1
1727         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1728         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1729                 error "failed to set $osp_proc=1"
1730         wait $pid
1731         [[ $pid -ne 0 ]] ||
1732                 error "should return error due to $osp_proc=0"
1733 }
1734 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1735
1736 test_27d() {
1737         test_mkdir $DIR/$tdir
1738         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1739                 error "setstripe failed"
1740         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1741         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1742 }
1743 run_test 27d "create file with default settings"
1744
1745 test_27e() {
1746         # LU-5839 adds check for existed layout before setting it
1747         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1748                 skip "Need MDS version at least 2.7.56"
1749
1750         test_mkdir $DIR/$tdir
1751         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1752         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1753         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1754 }
1755 run_test 27e "setstripe existing file (should return error)"
1756
1757 test_27f() {
1758         test_mkdir $DIR/$tdir
1759         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1760                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1761         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1762                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1763         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1764         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1765 }
1766 run_test 27f "setstripe with bad stripe size (should return error)"
1767
1768 test_27g() {
1769         test_mkdir $DIR/$tdir
1770         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1771         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1772                 error "$DIR/$tdir/$tfile has object"
1773 }
1774 run_test 27g "$LFS getstripe with no objects"
1775
1776 test_27ga() {
1777         test_mkdir $DIR/$tdir
1778         touch $DIR/$tdir/$tfile || error "touch failed"
1779         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1780         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1781         local rc=$?
1782         (( rc == 2 )) || error "getstripe did not return ENOENT"
1783 }
1784 run_test 27ga "$LFS getstripe with missing file (should return error)"
1785
1786 test_27i() {
1787         test_mkdir $DIR/$tdir
1788         touch $DIR/$tdir/$tfile || error "touch failed"
1789         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1790                 error "missing objects"
1791 }
1792 run_test 27i "$LFS getstripe with some objects"
1793
1794 test_27j() {
1795         test_mkdir $DIR/$tdir
1796         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1797                 error "setstripe failed" || true
1798 }
1799 run_test 27j "setstripe with bad stripe offset (should return error)"
1800
1801 test_27k() { # bug 2844
1802         test_mkdir $DIR/$tdir
1803         local file=$DIR/$tdir/$tfile
1804         local ll_max_blksize=$((4 * 1024 * 1024))
1805         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1806         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1807         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1808         dd if=/dev/zero of=$file bs=4k count=1
1809         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1810         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1811 }
1812 run_test 27k "limit i_blksize for broken user apps"
1813
1814 test_27l() {
1815         mcreate $DIR/$tfile || error "creating file"
1816         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1817                 error "setstripe should have failed" || true
1818 }
1819 run_test 27l "check setstripe permissions (should return error)"
1820
1821 test_27m() {
1822         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1823
1824         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1825                 skip_env "multiple clients -- skipping"
1826
1827         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1828                    head -n1)
1829         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1830                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1831         fi
1832         stack_trap simple_cleanup_common
1833         test_mkdir $DIR/$tdir
1834         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1835         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1836                 error "dd should fill OST0"
1837         i=2
1838         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1839                 i=$((i + 1))
1840                 [ $i -gt 256 ] && break
1841         done
1842         i=$((i + 1))
1843         touch $DIR/$tdir/$tfile.$i
1844         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1845             awk '{print $1}'| grep -w "0") ] &&
1846                 error "OST0 was full but new created file still use it"
1847         i=$((i + 1))
1848         touch $DIR/$tdir/$tfile.$i
1849         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1850             awk '{print $1}'| grep -w "0") ] &&
1851                 error "OST0 was full but new created file still use it" || true
1852 }
1853 run_test 27m "create file while OST0 was full"
1854
1855 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1856 # if the OST isn't full anymore.
1857 reset_enospc() {
1858         local ostidx=${1:-""}
1859         local delay
1860         local ready
1861         local get_prealloc
1862
1863         local list=$(comma_list $(osts_nodes))
1864         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1865
1866         do_nodes $list lctl set_param fail_loc=0
1867         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1868         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1869                 awk '{print $1 * 2;exit;}')
1870         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1871                         grep -v \"^0$\""
1872         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1873 }
1874
1875 test_27n() {
1876         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1878         remote_mds_nodsh && skip "remote MDS with nodsh"
1879         remote_ost_nodsh && skip "remote OST with nodsh"
1880
1881         reset_enospc
1882         rm -f $DIR/$tdir/$tfile
1883         exhaust_precreations 0 0x80000215
1884         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1885         touch $DIR/$tdir/$tfile || error "touch failed"
1886         $LFS getstripe $DIR/$tdir/$tfile
1887         reset_enospc
1888 }
1889 run_test 27n "create file with some full OSTs"
1890
1891 test_27o() {
1892         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1894         remote_mds_nodsh && skip "remote MDS with nodsh"
1895         remote_ost_nodsh && skip "remote OST with nodsh"
1896
1897         reset_enospc
1898         rm -f $DIR/$tdir/$tfile
1899         exhaust_all_precreations 0x215
1900
1901         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1902
1903         reset_enospc
1904         rm -rf $DIR/$tdir/*
1905 }
1906 run_test 27o "create file with all full OSTs (should error)"
1907
1908 function create_and_checktime() {
1909         local fname=$1
1910         local loops=$2
1911         local i
1912
1913         for ((i=0; i < $loops; i++)); do
1914                 local start=$SECONDS
1915                 multiop $fname-$i Oc
1916                 ((SECONDS-start < TIMEOUT)) ||
1917                         error "creation took " $((SECONDS-$start)) && return 1
1918         done
1919 }
1920
1921 test_27oo() {
1922         local mdts=$(comma_list $(mdts_nodes))
1923
1924         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1925                 skip "Need MDS version at least 2.13.57"
1926
1927         local f0=$DIR/${tfile}-0
1928         local f1=$DIR/${tfile}-1
1929
1930         wait_delete_completed
1931
1932         # refill precreated objects
1933         $LFS setstripe -i0 -c1 $f0
1934
1935         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1936         # force QoS allocation policy
1937         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1938         stack_trap "do_nodes $mdts $LCTL set_param \
1939                 lov.*.qos_threshold_rr=$saved" EXIT
1940         sleep_maxage
1941
1942         # one OST is unavailable, but still have few objects preallocated
1943         stop ost1
1944         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1945                 rm -rf $f1 $DIR/$tdir*" EXIT
1946
1947         for ((i=0; i < 7; i++)); do
1948                 mkdir $DIR/$tdir$i || error "can't create dir"
1949                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1950                         error "can't set striping"
1951         done
1952         for ((i=0; i < 7; i++)); do
1953                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1954         done
1955         wait
1956 }
1957 run_test 27oo "don't let few threads to reserve too many objects"
1958
1959 test_27p() {
1960         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1962         remote_mds_nodsh && skip "remote MDS with nodsh"
1963         remote_ost_nodsh && skip "remote OST with nodsh"
1964
1965         reset_enospc
1966         rm -f $DIR/$tdir/$tfile
1967         test_mkdir $DIR/$tdir
1968
1969         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1970         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1971         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1972
1973         exhaust_precreations 0 0x80000215
1974         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1975         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1976         $LFS getstripe $DIR/$tdir/$tfile
1977
1978         reset_enospc
1979 }
1980 run_test 27p "append to a truncated file with some full OSTs"
1981
1982 test_27q() {
1983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1985         remote_mds_nodsh && skip "remote MDS with nodsh"
1986         remote_ost_nodsh && skip "remote OST with nodsh"
1987
1988         reset_enospc
1989         rm -f $DIR/$tdir/$tfile
1990
1991         mkdir_on_mdt0 $DIR/$tdir
1992         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1993         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1994                 error "truncate $DIR/$tdir/$tfile failed"
1995         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1996
1997         exhaust_all_precreations 0x215
1998
1999         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2000         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2001
2002         reset_enospc
2003 }
2004 run_test 27q "append to truncated file with all OSTs full (should error)"
2005
2006 test_27r() {
2007         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2009         remote_mds_nodsh && skip "remote MDS with nodsh"
2010         remote_ost_nodsh && skip "remote OST with nodsh"
2011
2012         reset_enospc
2013         rm -f $DIR/$tdir/$tfile
2014         exhaust_precreations 0 0x80000215
2015
2016         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2017
2018         reset_enospc
2019 }
2020 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2021
2022 test_27s() { # bug 10725
2023         test_mkdir $DIR/$tdir
2024         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2025         local stripe_count=0
2026         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2027         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2028                 error "stripe width >= 2^32 succeeded" || true
2029
2030 }
2031 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2032
2033 test_27t() { # bug 10864
2034         WDIR=$(pwd)
2035         WLFS=$(which lfs)
2036         cd $DIR
2037         touch $tfile
2038         $WLFS getstripe $tfile
2039         cd $WDIR
2040 }
2041 run_test 27t "check that utils parse path correctly"
2042
2043 test_27u() { # bug 4900
2044         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2045         remote_mds_nodsh && skip "remote MDS with nodsh"
2046
2047         local index
2048         local list=$(comma_list $(mdts_nodes))
2049
2050 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2051         do_nodes $list $LCTL set_param fail_loc=0x139
2052         test_mkdir -p $DIR/$tdir
2053         stack_trap "simple_cleanup_common 1000"
2054         createmany -o $DIR/$tdir/$tfile 1000
2055         do_nodes $list $LCTL set_param fail_loc=0
2056
2057         TLOG=$TMP/$tfile.getstripe
2058         $LFS getstripe $DIR/$tdir > $TLOG
2059         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2060         [[ $OBJS -gt 0 ]] &&
2061                 error "$OBJS objects created on OST-0. See $TLOG" ||
2062                 rm -f $TLOG
2063 }
2064 run_test 27u "skip object creation on OSC w/o objects"
2065
2066 test_27v() { # bug 4900
2067         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2069         remote_mds_nodsh && skip "remote MDS with nodsh"
2070         remote_ost_nodsh && skip "remote OST with nodsh"
2071
2072         exhaust_all_precreations 0x215
2073         reset_enospc
2074
2075         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2076
2077         touch $DIR/$tdir/$tfile
2078         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2079         # all except ost1
2080         for (( i=1; i < OSTCOUNT; i++ )); do
2081                 do_facet ost$i lctl set_param fail_loc=0x705
2082         done
2083         local START=`date +%s`
2084         createmany -o $DIR/$tdir/$tfile 32
2085
2086         local FINISH=`date +%s`
2087         local TIMEOUT=`lctl get_param -n timeout`
2088         local PROCESS=$((FINISH - START))
2089         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2090                error "$FINISH - $START >= $TIMEOUT / 2"
2091         sleep $((TIMEOUT / 2 - PROCESS))
2092         reset_enospc
2093 }
2094 run_test 27v "skip object creation on slow OST"
2095
2096 test_27w() { # bug 10997
2097         test_mkdir $DIR/$tdir
2098         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2099         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2100                 error "stripe size $size != 65536" || true
2101         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2102                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2103 }
2104 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2105
2106 test_27wa() {
2107         [[ $OSTCOUNT -lt 2 ]] &&
2108                 skip_env "skipping multiple stripe count/offset test"
2109
2110         test_mkdir $DIR/$tdir
2111         for i in $(seq 1 $OSTCOUNT); do
2112                 offset=$((i - 1))
2113                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2114                         error "setstripe -c $i -i $offset failed"
2115                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2116                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2117                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2118                 [ $index -ne $offset ] &&
2119                         error "stripe offset $index != $offset" || true
2120         done
2121 }
2122 run_test 27wa "check $LFS setstripe -c -i options"
2123
2124 test_27x() {
2125         remote_ost_nodsh && skip "remote OST with nodsh"
2126         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2128
2129         OFFSET=$(($OSTCOUNT - 1))
2130         OSTIDX=0
2131         local OST=$(ostname_from_index $OSTIDX)
2132
2133         test_mkdir $DIR/$tdir
2134         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2135         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2136         sleep_maxage
2137         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2138         for i in $(seq 0 $OFFSET); do
2139                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2140                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2141                 error "OST0 was degraded but new created file still use it"
2142         done
2143         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2144 }
2145 run_test 27x "create files while OST0 is degraded"
2146
2147 test_27y() {
2148         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2149         remote_mds_nodsh && skip "remote MDS with nodsh"
2150         remote_ost_nodsh && skip "remote OST with nodsh"
2151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2152
2153         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2154         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2155                 osp.$mdtosc.prealloc_last_id)
2156         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2157                 osp.$mdtosc.prealloc_next_id)
2158         local fcount=$((last_id - next_id))
2159         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2160         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2161
2162         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2163                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2164         local OST_DEACTIVE_IDX=-1
2165         local OSC
2166         local OSTIDX
2167         local OST
2168
2169         for OSC in $MDS_OSCS; do
2170                 OST=$(osc_to_ost $OSC)
2171                 OSTIDX=$(index_from_ostuuid $OST)
2172                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2173                         OST_DEACTIVE_IDX=$OSTIDX
2174                 fi
2175                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2176                         echo $OSC "is Deactivated:"
2177                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2178                 fi
2179         done
2180
2181         OSTIDX=$(index_from_ostuuid $OST)
2182         test_mkdir $DIR/$tdir
2183         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2184
2185         for OSC in $MDS_OSCS; do
2186                 OST=$(osc_to_ost $OSC)
2187                 OSTIDX=$(index_from_ostuuid $OST)
2188                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2189                         echo $OST "is degraded:"
2190                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2191                                                 obdfilter.$OST.degraded=1
2192                 fi
2193         done
2194
2195         sleep_maxage
2196         createmany -o $DIR/$tdir/$tfile $fcount
2197
2198         for OSC in $MDS_OSCS; do
2199                 OST=$(osc_to_ost $OSC)
2200                 OSTIDX=$(index_from_ostuuid $OST)
2201                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2202                         echo $OST "is recovered from degraded:"
2203                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2204                                                 obdfilter.$OST.degraded=0
2205                 else
2206                         do_facet $SINGLEMDS lctl --device %$OSC activate
2207                 fi
2208         done
2209
2210         # all osp devices get activated, hence -1 stripe count restored
2211         local stripe_count=0
2212
2213         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2214         # devices get activated.
2215         sleep_maxage
2216         $LFS setstripe -c -1 $DIR/$tfile
2217         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2218         rm -f $DIR/$tfile
2219         [ $stripe_count -ne $OSTCOUNT ] &&
2220                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2221         return 0
2222 }
2223 run_test 27y "create files while OST0 is degraded and the rest inactive"
2224
2225 check_seq_oid()
2226 {
2227         log "check file $1"
2228
2229         lmm_count=$($LFS getstripe -c $1)
2230         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2231         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2232
2233         local old_ifs="$IFS"
2234         IFS=$'[:]'
2235         fid=($($LFS path2fid $1))
2236         IFS="$old_ifs"
2237
2238         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2239         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2240
2241         # compare lmm_seq and lu_fid->f_seq
2242         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2243         # compare lmm_object_id and lu_fid->oid
2244         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2245
2246         # check the trusted.fid attribute of the OST objects of the file
2247         local have_obdidx=false
2248         local stripe_nr=0
2249         $LFS getstripe $1 | while read obdidx oid hex seq; do
2250                 # skip lines up to and including "obdidx"
2251                 [ -z "$obdidx" ] && break
2252                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2253                 $have_obdidx || continue
2254
2255                 local ost=$((obdidx + 1))
2256                 local dev=$(ostdevname $ost)
2257                 local oid_hex
2258
2259                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2260
2261                 seq=$(echo $seq | sed -e "s/^0x//g")
2262                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2263                         oid_hex=$(echo $oid)
2264                 else
2265                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2266                 fi
2267                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2268
2269                 local ff=""
2270                 #
2271                 # Don't unmount/remount the OSTs if we don't need to do that.
2272                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2273                 # update too, until that use mount/ll_decode_filter_fid/mount.
2274                 # Re-enable when debugfs will understand new filter_fid.
2275                 #
2276                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2277                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2278                                 $dev 2>/dev/null" | grep "parent=")
2279                 fi
2280                 if [ -z "$ff" ]; then
2281                         stop ost$ost
2282                         mount_fstype ost$ost
2283                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2284                                 $(facet_mntpt ost$ost)/$obj_file)
2285                         unmount_fstype ost$ost
2286                         start ost$ost $dev $OST_MOUNT_OPTS
2287                         clients_up
2288                 fi
2289
2290                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2291
2292                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2293
2294                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2295                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2296                 #
2297                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2298                 #       stripe_size=1048576 component_id=1 component_start=0 \
2299                 #       component_end=33554432
2300                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2301                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2302                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2303                 local ff_pstripe
2304                 if grep -q 'stripe=' <<<$ff; then
2305                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2306                 else
2307                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2308                         # into f_ver in this case.  See comment on ff_parent.
2309                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2310                 fi
2311
2312                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2313                 [ $ff_pseq = $lmm_seq ] ||
2314                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2315                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2316                 [ $ff_poid = $lmm_oid ] ||
2317                         error "FF parent OID $ff_poid != $lmm_oid"
2318                 (($ff_pstripe == $stripe_nr)) ||
2319                         error "FF stripe $ff_pstripe != $stripe_nr"
2320
2321                 stripe_nr=$((stripe_nr + 1))
2322                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2323                         continue
2324                 if grep -q 'stripe_count=' <<<$ff; then
2325                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2326                                             -e 's/ .*//' <<<$ff)
2327                         [ $lmm_count = $ff_scnt ] ||
2328                                 error "FF stripe count $lmm_count != $ff_scnt"
2329                 fi
2330         done
2331 }
2332
2333 test_27z() {
2334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2335         remote_ost_nodsh && skip "remote OST with nodsh"
2336
2337         test_mkdir $DIR/$tdir
2338         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2339                 { error "setstripe -c -1 failed"; return 1; }
2340         # We need to send a write to every object to get parent FID info set.
2341         # This _should_ also work for setattr, but does not currently.
2342         # touch $DIR/$tdir/$tfile-1 ||
2343         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2344                 { error "dd $tfile-1 failed"; return 2; }
2345         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2346                 { error "setstripe -c -1 failed"; return 3; }
2347         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2348                 { error "dd $tfile-2 failed"; return 4; }
2349
2350         # make sure write RPCs have been sent to OSTs
2351         sync; sleep 5; sync
2352
2353         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2354         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2355 }
2356 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2357
2358 test_27A() { # b=19102
2359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2360
2361         save_layout_restore_at_exit $MOUNT
2362         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2363         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2364                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2365         local default_size=$($LFS getstripe -S $MOUNT)
2366         local default_offset=$($LFS getstripe -i $MOUNT)
2367         local dsize=$(do_facet $SINGLEMDS \
2368                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2369         [ $default_size -eq $dsize ] ||
2370                 error "stripe size $default_size != $dsize"
2371         [ $default_offset -eq -1 ] ||
2372                 error "stripe offset $default_offset != -1"
2373 }
2374 run_test 27A "check filesystem-wide default LOV EA values"
2375
2376 test_27B() { # LU-2523
2377         test_mkdir $DIR/$tdir
2378         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2379         touch $DIR/$tdir/f0
2380         # open f1 with O_LOV_DELAY_CREATE
2381         # rename f0 onto f1
2382         # call setstripe ioctl on open file descriptor for f1
2383         # close
2384         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2385                 $DIR/$tdir/f0
2386
2387         rm -f $DIR/$tdir/f1
2388         # open f1 with O_LOV_DELAY_CREATE
2389         # unlink f1
2390         # call setstripe ioctl on open file descriptor for f1
2391         # close
2392         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2393
2394         # Allow multiop to fail in imitation of NFS's busted semantics.
2395         true
2396 }
2397 run_test 27B "call setstripe on open unlinked file/rename victim"
2398
2399 # 27C family tests full striping and overstriping
2400 test_27Ca() { #LU-2871
2401         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2402
2403         declare -a ost_idx
2404         local index
2405         local found
2406         local i
2407         local j
2408
2409         test_mkdir $DIR/$tdir
2410         cd $DIR/$tdir
2411         for i in $(seq 0 $((OSTCOUNT - 1))); do
2412                 # set stripe across all OSTs starting from OST$i
2413                 $LFS setstripe -i $i -c -1 $tfile$i
2414                 # get striping information
2415                 ost_idx=($($LFS getstripe $tfile$i |
2416                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2417                 echo ${ost_idx[@]}
2418
2419                 # check the layout
2420                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2421                         error "${#ost_idx[@]} != $OSTCOUNT"
2422
2423                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2424                         found=0
2425                         for j in $(echo ${ost_idx[@]}); do
2426                                 if [ $index -eq $j ]; then
2427                                         found=1
2428                                         break
2429                                 fi
2430                         done
2431                         [ $found = 1 ] ||
2432                                 error "Can not find $index in ${ost_idx[@]}"
2433                 done
2434         done
2435 }
2436 run_test 27Ca "check full striping across all OSTs"
2437
2438 test_27Cb() {
2439         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2440                 skip "server does not support overstriping"
2441         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2442                 skip_env "too many osts, skipping"
2443
2444         test_mkdir -p $DIR/$tdir
2445         local setcount=$(($OSTCOUNT * 2))
2446         [ $setcount -lt 160 ] || large_xattr_enabled ||
2447                 skip_env "ea_inode feature disabled"
2448
2449         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2450                 error "setstripe failed"
2451
2452         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2453         [ $count -eq $setcount ] ||
2454                 error "stripe count $count, should be $setcount"
2455
2456         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2457                 error "overstriped should be set in pattern"
2458
2459         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2460                 error "dd failed"
2461 }
2462 run_test 27Cb "more stripes than OSTs with -C"
2463
2464 test_27Cc() {
2465         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2466                 skip "server does not support overstriping"
2467         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2468
2469         test_mkdir -p $DIR/$tdir
2470         local setcount=$(($OSTCOUNT - 1))
2471
2472         [ $setcount -lt 160 ] || large_xattr_enabled ||
2473                 skip_env "ea_inode feature disabled"
2474
2475         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2476                 error "setstripe failed"
2477
2478         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2479         [ $count -eq $setcount ] ||
2480                 error "stripe count $count, should be $setcount"
2481
2482         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2483                 error "overstriped should not be set in pattern"
2484
2485         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2486                 error "dd failed"
2487 }
2488 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2489
2490 test_27Cd() {
2491         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2492                 skip "server does not support overstriping"
2493         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2494         large_xattr_enabled || skip_env "ea_inode feature disabled"
2495
2496         test_mkdir -p $DIR/$tdir
2497         local setcount=$LOV_MAX_STRIPE_COUNT
2498
2499         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2500                 error "setstripe failed"
2501
2502         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2503         [ $count -eq $setcount ] ||
2504                 error "stripe count $count, should be $setcount"
2505
2506         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2507                 error "overstriped should be set in pattern"
2508
2509         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2510                 error "dd failed"
2511
2512         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2513 }
2514 run_test 27Cd "test maximum stripe count"
2515
2516 test_27Ce() {
2517         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2518                 skip "server does not support overstriping"
2519         test_mkdir -p $DIR/$tdir
2520
2521         pool_add $TESTNAME || error "Pool creation failed"
2522         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2523
2524         local setcount=8
2525
2526         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2527                 error "setstripe failed"
2528
2529         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2530         [ $count -eq $setcount ] ||
2531                 error "stripe count $count, should be $setcount"
2532
2533         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2534                 error "overstriped should be set in pattern"
2535
2536         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2537                 error "dd failed"
2538
2539         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2540 }
2541 run_test 27Ce "test pool with overstriping"
2542
2543 test_27Cf() {
2544         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2545                 skip "server does not support overstriping"
2546         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2547                 skip_env "too many osts, skipping"
2548
2549         test_mkdir -p $DIR/$tdir
2550
2551         local setcount=$(($OSTCOUNT * 2))
2552         [ $setcount -lt 160 ] || large_xattr_enabled ||
2553                 skip_env "ea_inode feature disabled"
2554
2555         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2556                 error "setstripe failed"
2557
2558         echo 1 > $DIR/$tdir/$tfile
2559
2560         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2561         [ $count -eq $setcount ] ||
2562                 error "stripe count $count, should be $setcount"
2563
2564         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2565                 error "overstriped should be set in pattern"
2566
2567         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2568                 error "dd failed"
2569
2570         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2571 }
2572 run_test 27Cf "test default inheritance with overstriping"
2573
2574 test_27D() {
2575         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2576         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2577         remote_mds_nodsh && skip "remote MDS with nodsh"
2578
2579         local POOL=${POOL:-testpool}
2580         local first_ost=0
2581         local last_ost=$(($OSTCOUNT - 1))
2582         local ost_step=1
2583         local ost_list=$(seq $first_ost $ost_step $last_ost)
2584         local ost_range="$first_ost $last_ost $ost_step"
2585
2586         test_mkdir $DIR/$tdir
2587         pool_add $POOL || error "pool_add failed"
2588         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2589
2590         local skip27D
2591         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2592                 skip27D+="-s 29"
2593         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2594                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2595                         skip27D+=" -s 30,31"
2596         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2597           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2598                 skip27D+=" -s 32,33"
2599         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2600                 skip27D+=" -s 34"
2601         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2602                 error "llapi_layout_test failed"
2603
2604         destroy_test_pools || error "destroy test pools failed"
2605 }
2606 run_test 27D "validate llapi_layout API"
2607
2608 # Verify that default_easize is increased from its initial value after
2609 # accessing a widely striped file.
2610 test_27E() {
2611         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2612         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2613                 skip "client does not have LU-3338 fix"
2614
2615         # 72 bytes is the minimum space required to store striping
2616         # information for a file striped across one OST:
2617         # (sizeof(struct lov_user_md_v3) +
2618         #  sizeof(struct lov_user_ost_data_v1))
2619         local min_easize=72
2620         $LCTL set_param -n llite.*.default_easize $min_easize ||
2621                 error "lctl set_param failed"
2622         local easize=$($LCTL get_param -n llite.*.default_easize)
2623
2624         [ $easize -eq $min_easize ] ||
2625                 error "failed to set default_easize"
2626
2627         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2628                 error "setstripe failed"
2629         # In order to ensure stat() call actually talks to MDS we need to
2630         # do something drastic to this file to shake off all lock, e.g.
2631         # rename it (kills lookup lock forcing cache cleaning)
2632         mv $DIR/$tfile $DIR/${tfile}-1
2633         ls -l $DIR/${tfile}-1
2634         rm $DIR/${tfile}-1
2635
2636         easize=$($LCTL get_param -n llite.*.default_easize)
2637
2638         [ $easize -gt $min_easize ] ||
2639                 error "default_easize not updated"
2640 }
2641 run_test 27E "check that default extended attribute size properly increases"
2642
2643 test_27F() { # LU-5346/LU-7975
2644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2645         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2646         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2647                 skip "Need MDS version at least 2.8.51"
2648         remote_ost_nodsh && skip "remote OST with nodsh"
2649
2650         test_mkdir $DIR/$tdir
2651         rm -f $DIR/$tdir/f0
2652         $LFS setstripe -c 2 $DIR/$tdir
2653
2654         # stop all OSTs to reproduce situation for LU-7975 ticket
2655         for num in $(seq $OSTCOUNT); do
2656                 stop ost$num
2657         done
2658
2659         # open/create f0 with O_LOV_DELAY_CREATE
2660         # truncate f0 to a non-0 size
2661         # close
2662         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2663
2664         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2665         # open/write it again to force delayed layout creation
2666         cat /etc/hosts > $DIR/$tdir/f0 &
2667         catpid=$!
2668
2669         # restart OSTs
2670         for num in $(seq $OSTCOUNT); do
2671                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2672                         error "ost$num failed to start"
2673         done
2674
2675         wait $catpid || error "cat failed"
2676
2677         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2678         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2679                 error "wrong stripecount"
2680
2681 }
2682 run_test 27F "Client resend delayed layout creation with non-zero size"
2683
2684 test_27G() { #LU-10629
2685         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2686                 skip "Need MDS version at least 2.11.51"
2687         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2688         remote_mds_nodsh && skip "remote MDS with nodsh"
2689         local POOL=${POOL:-testpool}
2690         local ostrange="0 0 1"
2691
2692         test_mkdir $DIR/$tdir
2693         touch $DIR/$tdir/$tfile.nopool
2694         pool_add $POOL || error "pool_add failed"
2695         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2696         $LFS setstripe -p $POOL $DIR/$tdir
2697
2698         local pool=$($LFS getstripe -p $DIR/$tdir)
2699
2700         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2701         touch $DIR/$tdir/$tfile.default
2702         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2703         $LFS find $DIR/$tdir -type f --pool $POOL
2704         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2705         [[ "$found" == "2" ]] ||
2706                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2707
2708         $LFS setstripe -d $DIR/$tdir
2709
2710         pool=$($LFS getstripe -p -d $DIR/$tdir)
2711
2712         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2713 }
2714 run_test 27G "Clear OST pool from stripe"
2715
2716 test_27H() {
2717         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2718                 skip "Need MDS version newer than 2.11.54"
2719         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2720         test_mkdir $DIR/$tdir
2721         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2722         touch $DIR/$tdir/$tfile
2723         $LFS getstripe -c $DIR/$tdir/$tfile
2724         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2725                 error "two-stripe file doesn't have two stripes"
2726
2727         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2728         $LFS getstripe -y $DIR/$tdir/$tfile
2729         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2730              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2731                 error "expected l_ost_idx: [02]$ not matched"
2732
2733         # make sure ost list has been cleared
2734         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2735         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2736                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2737         touch $DIR/$tdir/f3
2738         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2739 }
2740 run_test 27H "Set specific OSTs stripe"
2741
2742 test_27I() {
2743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2744         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2745         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2746                 skip "Need MDS version newer than 2.12.52"
2747         local pool=$TESTNAME
2748         local ostrange="1 1 1"
2749
2750         save_layout_restore_at_exit $MOUNT
2751         $LFS setstripe -c 2 -i 0 $MOUNT
2752         pool_add $pool || error "pool_add failed"
2753         pool_add_targets $pool $ostrange ||
2754                 error "pool_add_targets failed"
2755         test_mkdir $DIR/$tdir
2756         $LFS setstripe -p $pool $DIR/$tdir
2757         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2758         $LFS getstripe $DIR/$tdir/$tfile
2759 }
2760 run_test 27I "check that root dir striping does not break parent dir one"
2761
2762 test_27J() {
2763         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2764                 skip "Need MDS version newer than 2.12.51"
2765
2766         test_mkdir $DIR/$tdir
2767         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2768         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2769
2770         # create foreign file (raw way)
2771         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2772                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2773
2774         ! $LFS setstripe --foreign --flags foo \
2775                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2776                         error "creating $tfile with '--flags foo' should fail"
2777
2778         ! $LFS setstripe --foreign --flags 0xffffffff \
2779                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2780                         error "creating $tfile w/ 0xffffffff flags should fail"
2781
2782         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2783                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2784
2785         # verify foreign file (raw way)
2786         parse_foreign_file -f $DIR/$tdir/$tfile |
2787                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2788                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2789         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2790                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2791         parse_foreign_file -f $DIR/$tdir/$tfile |
2792                 grep "lov_foreign_size: 73" ||
2793                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2794         parse_foreign_file -f $DIR/$tdir/$tfile |
2795                 grep "lov_foreign_type: 1" ||
2796                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2797         parse_foreign_file -f $DIR/$tdir/$tfile |
2798                 grep "lov_foreign_flags: 0x0000DA08" ||
2799                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2800         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2801                 grep "lov_foreign_value: 0x" |
2802                 sed -e 's/lov_foreign_value: 0x//')
2803         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2804         [[ $lov = ${lov2// /} ]] ||
2805                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2806
2807         # create foreign file (lfs + API)
2808         $LFS setstripe --foreign=none --flags 0xda08 \
2809                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2810                 error "$DIR/$tdir/${tfile}2: create failed"
2811
2812         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2813                 grep "lfm_magic:.*0x0BD70BD0" ||
2814                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2815         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2816         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2817                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2818         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2819                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2820         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2821                 grep "lfm_flags:.*0x0000DA08" ||
2822                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2823         $LFS getstripe $DIR/$tdir/${tfile}2 |
2824                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2825                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2826
2827         # modify striping should fail
2828         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2829                 error "$DIR/$tdir/$tfile: setstripe should fail"
2830         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2831                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2832
2833         # R/W should fail
2834         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2835         cat $DIR/$tdir/${tfile}2 &&
2836                 error "$DIR/$tdir/${tfile}2: read should fail"
2837         cat /etc/passwd > $DIR/$tdir/$tfile &&
2838                 error "$DIR/$tdir/$tfile: write should fail"
2839         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2840                 error "$DIR/$tdir/${tfile}2: write should fail"
2841
2842         # chmod should work
2843         chmod 222 $DIR/$tdir/$tfile ||
2844                 error "$DIR/$tdir/$tfile: chmod failed"
2845         chmod 222 $DIR/$tdir/${tfile}2 ||
2846                 error "$DIR/$tdir/${tfile}2: chmod failed"
2847
2848         # chown should work
2849         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2850                 error "$DIR/$tdir/$tfile: chown failed"
2851         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2852                 error "$DIR/$tdir/${tfile}2: chown failed"
2853
2854         # rename should work
2855         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2856                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2857         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2858                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2859
2860         #remove foreign file
2861         rm $DIR/$tdir/${tfile}.new ||
2862                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2863         rm $DIR/$tdir/${tfile}2.new ||
2864                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2865 }
2866 run_test 27J "basic ops on file with foreign LOV"
2867
2868 test_27K() {
2869         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2870                 skip "Need MDS version newer than 2.12.49"
2871
2872         test_mkdir $DIR/$tdir
2873         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2874         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2875
2876         # create foreign dir (raw way)
2877         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2878                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2879
2880         ! $LFS setdirstripe --foreign --flags foo \
2881                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2882                         error "creating $tdir with '--flags foo' should fail"
2883
2884         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2885                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2886                         error "creating $tdir w/ 0xffffffff flags should fail"
2887
2888         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2889                 error "create_foreign_dir FAILED"
2890
2891         # verify foreign dir (raw way)
2892         parse_foreign_dir -d $DIR/$tdir/$tdir |
2893                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2894                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2895         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2896                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2897         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2898                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2899         parse_foreign_dir -d $DIR/$tdir/$tdir |
2900                 grep "lmv_foreign_flags: 55813$" ||
2901                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2902         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2903                 grep "lmv_foreign_value: 0x" |
2904                 sed 's/lmv_foreign_value: 0x//')
2905         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2906                 sed 's/ //g')
2907         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2908
2909         # create foreign dir (lfs + API)
2910         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2911                 $DIR/$tdir/${tdir}2 ||
2912                 error "$DIR/$tdir/${tdir}2: create failed"
2913
2914         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2915                 grep "lfm_magic:.*0x0CD50CD0" ||
2916                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2917         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2918         # - sizeof(lfm_type) - sizeof(lfm_flags)
2919         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2920                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2921         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2922                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2923         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2924                 grep "lfm_flags:.*0x0000DA05" ||
2925                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2926         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2927                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2928                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2929
2930         # file create in dir should fail
2931         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2932         touch $DIR/$tdir/${tdir}2/$tfile &&
2933                 error "$DIR/${tdir}2: file create should fail"
2934
2935         # chmod should work
2936         chmod 777 $DIR/$tdir/$tdir ||
2937                 error "$DIR/$tdir: chmod failed"
2938         chmod 777 $DIR/$tdir/${tdir}2 ||
2939                 error "$DIR/${tdir}2: chmod failed"
2940
2941         # chown should work
2942         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2943                 error "$DIR/$tdir: chown failed"
2944         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2945                 error "$DIR/${tdir}2: chown failed"
2946
2947         # rename should work
2948         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2949                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2950         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2951                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2952
2953         #remove foreign dir
2954         rmdir $DIR/$tdir/${tdir}.new ||
2955                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2956         rmdir $DIR/$tdir/${tdir}2.new ||
2957                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2958 }
2959 run_test 27K "basic ops on dir with foreign LMV"
2960
2961 test_27L() {
2962         remote_mds_nodsh && skip "remote MDS with nodsh"
2963
2964         local POOL=${POOL:-$TESTNAME}
2965
2966         pool_add $POOL || error "pool_add failed"
2967
2968         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2969                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2970                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2971 }
2972 run_test 27L "lfs pool_list gives correct pool name"
2973
2974 test_27M() {
2975         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2976                 skip "Need MDS version >= than 2.12.57"
2977         remote_mds_nodsh && skip "remote MDS with nodsh"
2978         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2979
2980         test_mkdir $DIR/$tdir
2981
2982         # Set default striping on directory
2983         local setcount=4
2984         local stripe_opt
2985
2986         # if we run against a 2.12 server which lacks overstring support
2987         # then the connect_flag will not report overstriping, even if client
2988         # is 2.14+
2989         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2990                 stripe_opt="-C $setcount"
2991         elif (( $OSTCOUNT >= $setcount )); then
2992                 stripe_opt="-c $setcount"
2993         else
2994                 skip "server does not support overstriping"
2995         fi
2996         $LFS setstripe $stripe_opt $DIR/$tdir
2997
2998         echo 1 > $DIR/$tdir/${tfile}.1
2999         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3000         [ $count -eq $setcount ] ||
3001                 error "(1) stripe count $count, should be $setcount"
3002
3003         # Capture existing append_stripe_count setting for restore
3004         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3005         local mdts=$(comma_list $(mdts_nodes))
3006         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
3007
3008         local appendcount=$orig_count
3009         echo 1 >> $DIR/$tdir/${tfile}.2_append
3010         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3011         [ $count -eq $appendcount ] ||
3012                 error "(2)stripe count $count, should be $appendcount for append"
3013
3014         # Disable O_APPEND striping, verify it works
3015         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3016
3017         # Should now get the default striping, which is 4
3018         setcount=4
3019         echo 1 >> $DIR/$tdir/${tfile}.3_append
3020         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3021         [ $count -eq $setcount ] ||
3022                 error "(3) stripe count $count, should be $setcount"
3023
3024         # Try changing the stripe count for append files
3025         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3026
3027         # Append striping is now 2 (directory default is still 4)
3028         appendcount=2
3029         echo 1 >> $DIR/$tdir/${tfile}.4_append
3030         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3031         [ $count -eq $appendcount ] ||
3032                 error "(4) stripe count $count, should be $appendcount for append"
3033
3034         # Test append stripe count of -1
3035         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3036         appendcount=$OSTCOUNT
3037         echo 1 >> $DIR/$tdir/${tfile}.5
3038         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3039         [ $count -eq $appendcount ] ||
3040                 error "(5) stripe count $count, should be $appendcount for append"
3041
3042         # Set append striping back to default of 1
3043         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3044
3045         # Try a new default striping, PFL + DOM
3046         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3047
3048         # Create normal DOM file, DOM returns stripe count == 0
3049         setcount=0
3050         touch $DIR/$tdir/${tfile}.6
3051         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3052         [ $count -eq $setcount ] ||
3053                 error "(6) stripe count $count, should be $setcount"
3054
3055         # Show
3056         appendcount=1
3057         echo 1 >> $DIR/$tdir/${tfile}.7_append
3058         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3059         [ $count -eq $appendcount ] ||
3060                 error "(7) stripe count $count, should be $appendcount for append"
3061
3062         # Clean up DOM layout
3063         $LFS setstripe -d $DIR/$tdir
3064
3065         save_layout_restore_at_exit $MOUNT
3066         # Now test that append striping works when layout is from root
3067         $LFS setstripe -c 2 $MOUNT
3068         # Make a special directory for this
3069         mkdir $DIR/${tdir}/${tdir}.2
3070
3071         # Verify for normal file
3072         setcount=2
3073         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3074         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3075         [ $count -eq $setcount ] ||
3076                 error "(8) stripe count $count, should be $setcount"
3077
3078         appendcount=1
3079         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3080         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3081         [ $count -eq $appendcount ] ||
3082                 error "(9) stripe count $count, should be $appendcount for append"
3083
3084         # Now test O_APPEND striping with pools
3085         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3086         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3087
3088         # Create the pool
3089         pool_add $TESTNAME || error "pool creation failed"
3090         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3091
3092         echo 1 >> $DIR/$tdir/${tfile}.10_append
3093
3094         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3095         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3096
3097         # Check that count is still correct
3098         appendcount=1
3099         echo 1 >> $DIR/$tdir/${tfile}.11_append
3100         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3101         [ $count -eq $appendcount ] ||
3102                 error "(11) stripe count $count, should be $appendcount for append"
3103
3104         # Disable O_APPEND stripe count, verify pool works separately
3105         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3106
3107         echo 1 >> $DIR/$tdir/${tfile}.12_append
3108
3109         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3110         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3111
3112         # Remove pool setting, verify it's not applied
3113         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3114
3115         echo 1 >> $DIR/$tdir/${tfile}.13_append
3116
3117         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3118         [ "$pool" = "" ] || error "(13) pool found: $pool"
3119 }
3120 run_test 27M "test O_APPEND striping"
3121
3122 test_27N() {
3123         combined_mgs_mds && skip "needs separate MGS/MDT"
3124
3125         pool_add $TESTNAME || error "pool_add failed"
3126         do_facet mgs "$LCTL pool_list $FSNAME" |
3127                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3128                 error "lctl pool_list on MGS failed"
3129 }
3130 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3131
3132 clean_foreign_symlink() {
3133         trap 0
3134         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3135         for i in $DIR/$tdir/* ; do
3136                 $LFS unlink_foreign $i || true
3137         done
3138 }
3139
3140 test_27O() {
3141         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3142                 skip "Need MDS version newer than 2.12.51"
3143
3144         test_mkdir $DIR/$tdir
3145         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3146         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3147
3148         trap clean_foreign_symlink EXIT
3149
3150         # enable foreign_symlink behaviour
3151         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3152
3153         # foreign symlink LOV format is a partial path by default
3154
3155         # create foreign file (lfs + API)
3156         $LFS setstripe --foreign=symlink --flags 0xda05 \
3157                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3158                 error "$DIR/$tdir/${tfile}: create failed"
3159
3160         $LFS getstripe -v $DIR/$tdir/${tfile} |
3161                 grep "lfm_magic:.*0x0BD70BD0" ||
3162                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3163         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3164                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3165         $LFS getstripe -v $DIR/$tdir/${tfile} |
3166                 grep "lfm_flags:.*0x0000DA05" ||
3167                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3168         $LFS getstripe $DIR/$tdir/${tfile} |
3169                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3170                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3171
3172         # modify striping should fail
3173         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3174                 error "$DIR/$tdir/$tfile: setstripe should fail"
3175
3176         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3177         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3178         cat /etc/passwd > $DIR/$tdir/$tfile &&
3179                 error "$DIR/$tdir/$tfile: write should fail"
3180
3181         # rename should succeed
3182         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3183                 error "$DIR/$tdir/$tfile: rename has failed"
3184
3185         #remove foreign_symlink file should fail
3186         rm $DIR/$tdir/${tfile}.new &&
3187                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3188
3189         #test fake symlink
3190         mkdir /tmp/${uuid1} ||
3191                 error "/tmp/${uuid1}: mkdir has failed"
3192         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3193                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3194         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3195         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3197         #read should succeed now
3198         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3199                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3200         #write should succeed now
3201         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3202                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3203         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3204                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3205         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3206                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3207
3208         #check that getstripe still works
3209         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3210                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3211
3212         # chmod should still succeed
3213         chmod 644 $DIR/$tdir/${tfile}.new ||
3214                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3215
3216         # chown should still succeed
3217         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3218                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3219
3220         # rename should still succeed
3221         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3222                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3223
3224         #remove foreign_symlink file should still fail
3225         rm $DIR/$tdir/${tfile} &&
3226                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3227
3228         #use special ioctl() to unlink foreign_symlink file
3229         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3230                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3231
3232 }
3233 run_test 27O "basic ops on foreign file of symlink type"
3234
3235 test_27P() {
3236         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3237                 skip "Need MDS version newer than 2.12.49"
3238
3239         test_mkdir $DIR/$tdir
3240         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3241         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3242
3243         trap clean_foreign_symlink EXIT
3244
3245         # enable foreign_symlink behaviour
3246         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3247
3248         # foreign symlink LMV format is a partial path by default
3249
3250         # create foreign dir (lfs + API)
3251         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3252                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3253                 error "$DIR/$tdir/${tdir}: create failed"
3254
3255         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3256                 grep "lfm_magic:.*0x0CD50CD0" ||
3257                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3258         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3259                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3260         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3261                 grep "lfm_flags:.*0x0000DA05" ||
3262                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3263         $LFS getdirstripe $DIR/$tdir/${tdir} |
3264                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3265                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3266
3267         # file create in dir should fail
3268         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3269         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3270
3271         # rename should succeed
3272         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3273                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3274
3275         #remove foreign_symlink dir should fail
3276         rmdir $DIR/$tdir/${tdir}.new &&
3277                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3278
3279         #test fake symlink
3280         mkdir -p /tmp/${uuid1}/${uuid2} ||
3281                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3282         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3283                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3284         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3285         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3286                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3287         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3288                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3289
3290         #check that getstripe fails now that foreign_symlink enabled
3291         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3292                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3293
3294         # file create in dir should work now
3295         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3296                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3297         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3298                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3299         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3300                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3301
3302         # chmod should still succeed
3303         chmod 755 $DIR/$tdir/${tdir}.new ||
3304                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3305
3306         # chown should still succeed
3307         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3308                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3309
3310         # rename should still succeed
3311         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3312                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3313
3314         #remove foreign_symlink dir should still fail
3315         rmdir $DIR/$tdir/${tdir} &&
3316                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3317
3318         #use special ioctl() to unlink foreign_symlink file
3319         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3320                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3321
3322         #created file should still exist
3323         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3324                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3325         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3326                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3327 }
3328 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3329
3330 test_27Q() {
3331         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3332         stack_trap "rm -f $TMP/$tfile*"
3333
3334         test_mkdir $DIR/$tdir-1
3335         test_mkdir $DIR/$tdir-2
3336
3337         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3338         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3339
3340         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3341         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3342
3343         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3344         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3345
3346         # Create some bad symlinks and ensure that we don't loop
3347         # forever or something. These should return ELOOP (40) and
3348         # ENOENT (2) but I don't want to test for that because there's
3349         # always some weirdo architecture that needs to ruin
3350         # everything by defining these error numbers differently.
3351
3352         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3353         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3354
3355         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3356         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3357
3358         return 0
3359 }
3360 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3361
3362 test_27R() {
3363         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3364                 skip "need MDS 2.14.55 or later"
3365         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3366
3367         local testdir="$DIR/$tdir"
3368         test_mkdir -p $testdir
3369         stack_trap "rm -rf $testdir"
3370         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3371
3372         local f1="$testdir/f1"
3373         touch $f1 || error "failed to touch $f1"
3374         local count=$($LFS getstripe -c $f1)
3375         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3376
3377         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3378         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3379
3380         local maxcount=$(($OSTCOUNT - 1))
3381         local mdts=$(comma_list $(mdts_nodes))
3382         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3383         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3384
3385         local f2="$testdir/f2"
3386         touch $f2 || error "failed to touch $f2"
3387         local count=$($LFS getstripe -c $f2)
3388         (( $count == $maxcount )) || error "wrong stripe count"
3389 }
3390 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3391
3392 test_27S() {
3393         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
3394                 skip "Need MDS version at least 2.14.54"
3395         [[ "$(facet_host mds1)" != "$(facet_host ost1)" ]] ||
3396                 skip "needs different host for mdt1 ost1"
3397
3398         local count=$(precreated_ost_obj_count 0 0)
3399
3400         echo "precreate count $count"
3401         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
3402         $LFS setstripe -i 0 -c 1 $DIR/$tdir || error "setstripe $tdir failed"
3403         #define OBD_FAIL_OSP_GET_LAST_FID       0x2109
3404         do_facet mds1 $LCTL set_param fail_loc=0x2109
3405         #define OBD_FAIL_OST_GET_LAST_FID       0x252
3406         do_facet ost1 $LCTL set_param fail_loc=0x252
3407         createmany -o $DIR/$tdir/f $count &
3408         pid=$!
3409         echo "precreate count $(precreated_ost_obj_count 0 0)"
3410         do_facet mds1 $LCTL set_param fail_loc=0
3411         do_facet ost1 $LCTL set_param fail_loc=0
3412         wait $pid || error "createmany failed"
3413         echo "precreate count $(precreated_ost_obj_count 0 0)"
3414 }
3415 run_test 27S "don't deactivate OSP on network issue"
3416
3417 # createtest also checks that device nodes are created and
3418 # then visible correctly (#2091)
3419 test_28() { # bug 2091
3420         test_mkdir $DIR/d28
3421         $CREATETEST $DIR/d28/ct || error "createtest failed"
3422 }
3423 run_test 28 "create/mknod/mkdir with bad file types ============"
3424
3425 test_29() {
3426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3427
3428         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3429                 disable_opencache
3430                 stack_trap "restore_opencache"
3431         }
3432
3433         sync; sleep 1; sync # flush out any dirty pages from previous tests
3434         cancel_lru_locks
3435         test_mkdir $DIR/d29
3436         touch $DIR/d29/foo
3437         log 'first d29'
3438         ls -l $DIR/d29
3439
3440         declare -i LOCKCOUNTORIG=0
3441         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3442                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3443         done
3444         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3445
3446         declare -i LOCKUNUSEDCOUNTORIG=0
3447         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3448                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3449         done
3450
3451         log 'second d29'
3452         ls -l $DIR/d29
3453         log 'done'
3454
3455         declare -i LOCKCOUNTCURRENT=0
3456         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3457                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3458         done
3459
3460         declare -i LOCKUNUSEDCOUNTCURRENT=0
3461         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3462                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3463         done
3464
3465         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3466                 $LCTL set_param -n ldlm.dump_namespaces ""
3467                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3468                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3469                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3470                 return 2
3471         fi
3472         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3473                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3474                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3475                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3476                 return 3
3477         fi
3478 }
3479 run_test 29 "IT_GETATTR regression  ============================"
3480
3481 test_30a() { # was test_30
3482         cp $(which ls) $DIR || cp /bin/ls $DIR
3483         $DIR/ls / || error "Can't execute binary from lustre"
3484         rm $DIR/ls
3485 }
3486 run_test 30a "execute binary from Lustre (execve) =============="
3487
3488 test_30b() {
3489         cp `which ls` $DIR || cp /bin/ls $DIR
3490         chmod go+rx $DIR/ls
3491         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3492         rm $DIR/ls
3493 }
3494 run_test 30b "execute binary from Lustre as non-root ==========="
3495
3496 test_30c() { # b=22376
3497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3498
3499         cp $(which ls) $DIR || cp /bin/ls $DIR
3500         chmod a-rw $DIR/ls
3501         cancel_lru_locks mdc
3502         cancel_lru_locks osc
3503         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3504         rm -f $DIR/ls
3505 }
3506 run_test 30c "execute binary from Lustre without read perms ===="
3507
3508 test_30d() {
3509         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3510
3511         for i in {1..10}; do
3512                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3513                 local PID=$!
3514                 sleep 1
3515                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3516                 wait $PID || error "executing dd from Lustre failed"
3517                 rm -f $DIR/$tfile
3518         done
3519
3520         rm -f $DIR/dd
3521 }
3522 run_test 30d "execute binary from Lustre while clear locks"
3523
3524 test_31a() {
3525         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3526         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3527 }
3528 run_test 31a "open-unlink file =================================="
3529
3530 test_31b() {
3531         touch $DIR/f31 || error "touch $DIR/f31 failed"
3532         ln $DIR/f31 $DIR/f31b || error "ln failed"
3533         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3534         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3535 }
3536 run_test 31b "unlink file with multiple links while open ======="
3537
3538 test_31c() {
3539         touch $DIR/f31 || error "touch $DIR/f31 failed"
3540         ln $DIR/f31 $DIR/f31c || error "ln failed"
3541         multiop_bg_pause $DIR/f31 O_uc ||
3542                 error "multiop_bg_pause for $DIR/f31 failed"
3543         MULTIPID=$!
3544         $MULTIOP $DIR/f31c Ouc
3545         kill -USR1 $MULTIPID
3546         wait $MULTIPID
3547 }
3548 run_test 31c "open-unlink file with multiple links ============="
3549
3550 test_31d() {
3551         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3552         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3553 }
3554 run_test 31d "remove of open directory ========================="
3555
3556 test_31e() { # bug 2904
3557         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3558 }
3559 run_test 31e "remove of open non-empty directory ==============="
3560
3561 test_31f() { # bug 4554
3562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3563
3564         set -vx
3565         test_mkdir $DIR/d31f
3566         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3567         cp /etc/hosts $DIR/d31f
3568         ls -l $DIR/d31f
3569         $LFS getstripe $DIR/d31f/hosts
3570         multiop_bg_pause $DIR/d31f D_c || return 1
3571         MULTIPID=$!
3572
3573         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3574         test_mkdir $DIR/d31f
3575         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3576         cp /etc/hosts $DIR/d31f
3577         ls -l $DIR/d31f
3578         $LFS getstripe $DIR/d31f/hosts
3579         multiop_bg_pause $DIR/d31f D_c || return 1
3580         MULTIPID2=$!
3581
3582         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3583         wait $MULTIPID || error "first opendir $MULTIPID failed"
3584
3585         sleep 6
3586
3587         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3588         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3589         set +vx
3590 }
3591 run_test 31f "remove of open directory with open-unlink file ==="
3592
3593 test_31g() {
3594         echo "-- cross directory link --"
3595         test_mkdir -c1 $DIR/${tdir}ga
3596         test_mkdir -c1 $DIR/${tdir}gb
3597         touch $DIR/${tdir}ga/f
3598         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3599         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3600         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3601         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3602         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3603 }
3604 run_test 31g "cross directory link==============="
3605
3606 test_31h() {
3607         echo "-- cross directory link --"
3608         test_mkdir -c1 $DIR/${tdir}
3609         test_mkdir -c1 $DIR/${tdir}/dir
3610         touch $DIR/${tdir}/f
3611         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3612         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3613         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3614         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3615         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3616 }
3617 run_test 31h "cross directory link under child==============="
3618
3619 test_31i() {
3620         echo "-- cross directory link --"
3621         test_mkdir -c1 $DIR/$tdir
3622         test_mkdir -c1 $DIR/$tdir/dir
3623         touch $DIR/$tdir/dir/f
3624         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3625         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3626         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3627         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3628         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3629 }
3630 run_test 31i "cross directory link under parent==============="
3631
3632 test_31j() {
3633         test_mkdir -c1 -p $DIR/$tdir
3634         test_mkdir -c1 -p $DIR/$tdir/dir1
3635         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3636         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3637         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3638         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3639         return 0
3640 }
3641 run_test 31j "link for directory==============="
3642
3643 test_31k() {
3644         test_mkdir -c1 -p $DIR/$tdir
3645         touch $DIR/$tdir/s
3646         touch $DIR/$tdir/exist
3647         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3648         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3649         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3650         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3651         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3652         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3653         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3654         return 0
3655 }
3656 run_test 31k "link to file: the same, non-existing, dir==============="
3657
3658 test_31m() {
3659         mkdir $DIR/d31m
3660         touch $DIR/d31m/s
3661         mkdir $DIR/d31m2
3662         touch $DIR/d31m2/exist
3663         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3664         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3665         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3666         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3667         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3668         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3669         return 0
3670 }
3671 run_test 31m "link to file: the same, non-existing, dir==============="
3672
3673 test_31n() {
3674         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3675         nlink=$(stat --format=%h $DIR/$tfile)
3676         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3677         local fd=$(free_fd)
3678         local cmd="exec $fd<$DIR/$tfile"
3679         eval $cmd
3680         cmd="exec $fd<&-"
3681         trap "eval $cmd" EXIT
3682         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3683         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3684         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3685         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3686         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3687         eval $cmd
3688 }
3689 run_test 31n "check link count of unlinked file"
3690
3691 link_one() {
3692         local tempfile=$(mktemp $1_XXXXXX)
3693         mlink $tempfile $1 2> /dev/null &&
3694                 echo "$BASHPID: link $tempfile to $1 succeeded"
3695         munlink $tempfile
3696 }
3697
3698 test_31o() { # LU-2901
3699         test_mkdir $DIR/$tdir
3700         for LOOP in $(seq 100); do
3701                 rm -f $DIR/$tdir/$tfile*
3702                 for THREAD in $(seq 8); do
3703                         link_one $DIR/$tdir/$tfile.$LOOP &
3704                 done
3705                 wait
3706                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3707                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3708                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3709                         break || true
3710         done
3711 }
3712 run_test 31o "duplicate hard links with same filename"
3713
3714 test_31p() {
3715         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3716
3717         test_mkdir $DIR/$tdir
3718         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3719         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3720
3721         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3722                 error "open unlink test1 failed"
3723         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3724                 error "open unlink test2 failed"
3725
3726         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3727                 error "test1 still exists"
3728         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3729                 error "test2 still exists"
3730 }
3731 run_test 31p "remove of open striped directory"
3732
3733 test_31q() {
3734         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3735
3736         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3737         index=$($LFS getdirstripe -i $DIR/$tdir)
3738         [ $index -eq 3 ] || error "first stripe index $index != 3"
3739         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3740         [ $index -eq 1 ] || error "second stripe index $index != 1"
3741
3742         # when "-c <stripe_count>" is set, the number of MDTs specified after
3743         # "-i" should equal to the stripe count
3744         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3745 }
3746 run_test 31q "create striped directory on specific MDTs"
3747
3748 #LU-14949
3749 test_31r() {
3750         touch $DIR/$tfile.target
3751         touch $DIR/$tfile.source
3752
3753         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3754         $LCTL set_param fail_loc=0x1419 fail_val=3
3755         cat $DIR/$tfile.target &
3756         CATPID=$!
3757
3758         # Guarantee open is waiting before we get here
3759         sleep 1
3760         mv $DIR/$tfile.source $DIR/$tfile.target
3761
3762         wait $CATPID
3763         RC=$?
3764         if [[ $RC -ne 0 ]]; then
3765                 error "open with cat failed, rc=$RC"
3766         fi
3767 }
3768 run_test 31r "open-rename(replace) race"
3769
3770 cleanup_test32_mount() {
3771         local rc=0
3772         trap 0
3773         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3774         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3775         losetup -d $loopdev || true
3776         rm -rf $DIR/$tdir
3777         return $rc
3778 }
3779
3780 test_32a() {
3781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3782
3783         echo "== more mountpoints and symlinks ================="
3784         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3785         trap cleanup_test32_mount EXIT
3786         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3787         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3788                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3789         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3790                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3791         cleanup_test32_mount
3792 }
3793 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3794
3795 test_32b() {
3796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3797
3798         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3799         trap cleanup_test32_mount EXIT
3800         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3801         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3802                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3803         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3804                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3805         cleanup_test32_mount
3806 }
3807 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3808
3809 test_32c() {
3810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3811
3812         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3813         trap cleanup_test32_mount EXIT
3814         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3815         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3816                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3817         test_mkdir -p $DIR/$tdir/d2/test_dir
3818         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3819                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3820         cleanup_test32_mount
3821 }
3822 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3823
3824 test_32d() {
3825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3826
3827         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3828         trap cleanup_test32_mount EXIT
3829         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3830         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3831                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3832         test_mkdir -p $DIR/$tdir/d2/test_dir
3833         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3834                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3835         cleanup_test32_mount
3836 }
3837 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3838
3839 test_32e() {
3840         rm -fr $DIR/$tdir
3841         test_mkdir -p $DIR/$tdir/tmp
3842         local tmp_dir=$DIR/$tdir/tmp
3843         ln -s $DIR/$tdir $tmp_dir/symlink11
3844         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3845         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3846         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3847 }
3848 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3849
3850 test_32f() {
3851         rm -fr $DIR/$tdir
3852         test_mkdir -p $DIR/$tdir/tmp
3853         local tmp_dir=$DIR/$tdir/tmp
3854         ln -s $DIR/$tdir $tmp_dir/symlink11
3855         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3856         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3857         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3858 }
3859 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3860
3861 test_32g() {
3862         local tmp_dir=$DIR/$tdir/tmp
3863         test_mkdir -p $tmp_dir
3864         test_mkdir $DIR/${tdir}2
3865         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3866         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3867         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3868         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3869         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3870         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3871 }
3872 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3873
3874 test_32h() {
3875         rm -fr $DIR/$tdir $DIR/${tdir}2
3876         tmp_dir=$DIR/$tdir/tmp
3877         test_mkdir -p $tmp_dir
3878         test_mkdir $DIR/${tdir}2
3879         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3880         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3881         ls $tmp_dir/symlink12 || error "listing symlink12"
3882         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3883 }
3884 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3885
3886 test_32i() {
3887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3888
3889         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3890         trap cleanup_test32_mount EXIT
3891         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3892         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3893                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3894         touch $DIR/$tdir/test_file
3895         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3896                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3897         cleanup_test32_mount
3898 }
3899 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3900
3901 test_32j() {
3902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3903
3904         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3905         trap cleanup_test32_mount EXIT
3906         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3907         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3908                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3909         touch $DIR/$tdir/test_file
3910         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3911                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3912         cleanup_test32_mount
3913 }
3914 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3915
3916 test_32k() {
3917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3918
3919         rm -fr $DIR/$tdir
3920         trap cleanup_test32_mount EXIT
3921         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3922         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3923                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3924         test_mkdir -p $DIR/$tdir/d2
3925         touch $DIR/$tdir/d2/test_file || error "touch failed"
3926         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3927                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3928         cleanup_test32_mount
3929 }
3930 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3931
3932 test_32l() {
3933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3934
3935         rm -fr $DIR/$tdir
3936         trap cleanup_test32_mount EXIT
3937         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3938         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3939                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3940         test_mkdir -p $DIR/$tdir/d2
3941         touch $DIR/$tdir/d2/test_file || error "touch failed"
3942         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3943                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3944         cleanup_test32_mount
3945 }
3946 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3947
3948 test_32m() {
3949         rm -fr $DIR/d32m
3950         test_mkdir -p $DIR/d32m/tmp
3951         TMP_DIR=$DIR/d32m/tmp
3952         ln -s $DIR $TMP_DIR/symlink11
3953         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3954         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3955                 error "symlink11 not a link"
3956         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3957                 error "symlink01 not a link"
3958 }
3959 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3960
3961 test_32n() {
3962         rm -fr $DIR/d32n
3963         test_mkdir -p $DIR/d32n/tmp
3964         TMP_DIR=$DIR/d32n/tmp
3965         ln -s $DIR $TMP_DIR/symlink11
3966         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3967         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3968         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3969 }
3970 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3971
3972 test_32o() {
3973         touch $DIR/$tfile
3974         test_mkdir -p $DIR/d32o/tmp
3975         TMP_DIR=$DIR/d32o/tmp
3976         ln -s $DIR/$tfile $TMP_DIR/symlink12
3977         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3978         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3979                 error "symlink12 not a link"
3980         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3981         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3982                 error "$DIR/d32o/tmp/symlink12 not file type"
3983         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3984                 error "$DIR/d32o/symlink02 not file type"
3985 }
3986 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3987
3988 test_32p() {
3989         log 32p_1
3990         rm -fr $DIR/d32p
3991         log 32p_2
3992         rm -f $DIR/$tfile
3993         log 32p_3
3994         touch $DIR/$tfile
3995         log 32p_4
3996         test_mkdir -p $DIR/d32p/tmp
3997         log 32p_5
3998         TMP_DIR=$DIR/d32p/tmp
3999         log 32p_6
4000         ln -s $DIR/$tfile $TMP_DIR/symlink12
4001         log 32p_7
4002         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4003         log 32p_8
4004         cat $DIR/d32p/tmp/symlink12 ||
4005                 error "Can't open $DIR/d32p/tmp/symlink12"
4006         log 32p_9
4007         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4008         log 32p_10
4009 }
4010 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4011
4012 test_32q() {
4013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4014
4015         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4016         trap cleanup_test32_mount EXIT
4017         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4018         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4019         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4020                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4021         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4022         cleanup_test32_mount
4023 }
4024 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4025
4026 test_32r() {
4027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4028
4029         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4030         trap cleanup_test32_mount EXIT
4031         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4032         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4033         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4034                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4035         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4036         cleanup_test32_mount
4037 }
4038 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4039
4040 test_33aa() {
4041         rm -f $DIR/$tfile
4042         touch $DIR/$tfile
4043         chmod 444 $DIR/$tfile
4044         chown $RUNAS_ID $DIR/$tfile
4045         log 33_1
4046         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4047         log 33_2
4048 }
4049 run_test 33aa "write file with mode 444 (should return error)"
4050
4051 test_33a() {
4052         rm -fr $DIR/$tdir
4053         test_mkdir $DIR/$tdir
4054         chown $RUNAS_ID $DIR/$tdir
4055         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4056                 error "$RUNAS create $tdir/$tfile failed"
4057         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4058                 error "open RDWR" || true
4059 }
4060 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4061
4062 test_33b() {
4063         rm -fr $DIR/$tdir
4064         test_mkdir $DIR/$tdir
4065         chown $RUNAS_ID $DIR/$tdir
4066         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4067 }
4068 run_test 33b "test open file with malformed flags (No panic)"
4069
4070 test_33c() {
4071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4072         remote_ost_nodsh && skip "remote OST with nodsh"
4073
4074         local ostnum
4075         local ostname
4076         local write_bytes
4077         local all_zeros
4078
4079         all_zeros=true
4080         test_mkdir $DIR/$tdir
4081         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4082
4083         sync
4084         for ostnum in $(seq $OSTCOUNT); do
4085                 # test-framework's OST numbering is one-based, while Lustre's
4086                 # is zero-based
4087                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4088                 # check if at least some write_bytes stats are counted
4089                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4090                               obdfilter.$ostname.stats |
4091                               awk '/^write_bytes/ {print $7}' )
4092                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4093                 if (( ${write_bytes:-0} > 0 )); then
4094                         all_zeros=false
4095                         break
4096                 fi
4097         done
4098
4099         $all_zeros || return 0
4100
4101         # Write four bytes
4102         echo foo > $DIR/$tdir/bar
4103         # Really write them
4104         sync
4105
4106         # Total up write_bytes after writing.  We'd better find non-zeros.
4107         for ostnum in $(seq $OSTCOUNT); do
4108                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4109                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4110                               obdfilter/$ostname/stats |
4111                               awk '/^write_bytes/ {print $7}' )
4112                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4113                 if (( ${write_bytes:-0} > 0 )); then
4114                         all_zeros=false
4115                         break
4116                 fi
4117         done
4118
4119         if $all_zeros; then
4120                 for ostnum in $(seq $OSTCOUNT); do
4121                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4122                         echo "Check write_bytes is in obdfilter.*.stats:"
4123                         do_facet ost$ostnum lctl get_param -n \
4124                                 obdfilter.$ostname.stats
4125                 done
4126                 error "OST not keeping write_bytes stats (b=22312)"
4127         fi
4128 }
4129 run_test 33c "test write_bytes stats"
4130
4131 test_33d() {
4132         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4134
4135         local MDTIDX=1
4136         local remote_dir=$DIR/$tdir/remote_dir
4137
4138         test_mkdir $DIR/$tdir
4139         $LFS mkdir -i $MDTIDX $remote_dir ||
4140                 error "create remote directory failed"
4141
4142         touch $remote_dir/$tfile
4143         chmod 444 $remote_dir/$tfile
4144         chown $RUNAS_ID $remote_dir/$tfile
4145
4146         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4147
4148         chown $RUNAS_ID $remote_dir
4149         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4150                                         error "create" || true
4151         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4152                                     error "open RDWR" || true
4153         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4154 }
4155 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4156
4157 test_33e() {
4158         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4159
4160         mkdir $DIR/$tdir
4161
4162         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4163         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4164         mkdir $DIR/$tdir/local_dir
4165
4166         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4167         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4168         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4169
4170         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4171                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4172
4173         rmdir $DIR/$tdir/* || error "rmdir failed"
4174
4175         umask 777
4176         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4177         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4178         mkdir $DIR/$tdir/local_dir
4179
4180         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4181         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4182         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4183
4184         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4185                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4186
4187         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4188
4189         umask 000
4190         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4191         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4192         mkdir $DIR/$tdir/local_dir
4193
4194         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4195         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4196         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4197
4198         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4199                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4200 }
4201 run_test 33e "mkdir and striped directory should have same mode"
4202
4203 cleanup_33f() {
4204         trap 0
4205         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4206 }
4207
4208 test_33f() {
4209         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4210         remote_mds_nodsh && skip "remote MDS with nodsh"
4211
4212         mkdir $DIR/$tdir
4213         chmod go+rwx $DIR/$tdir
4214         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4215         trap cleanup_33f EXIT
4216
4217         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4218                 error "cannot create striped directory"
4219
4220         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4221                 error "cannot create files in striped directory"
4222
4223         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4224                 error "cannot remove files in striped directory"
4225
4226         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4227                 error "cannot remove striped directory"
4228
4229         cleanup_33f
4230 }
4231 run_test 33f "nonroot user can create, access, and remove a striped directory"
4232
4233 test_33g() {
4234         mkdir -p $DIR/$tdir/dir2
4235
4236         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4237         echo $err
4238         [[ $err =~ "exists" ]] || error "Not exists error"
4239 }
4240 run_test 33g "nonroot user create already existing root created file"
4241
4242 test_33h() {
4243         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4244         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4245                 skip "Need MDS version at least 2.13.50"
4246
4247         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4248                 error "mkdir $tdir failed"
4249         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4250
4251         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4252         local index2
4253
4254         for fname in $DIR/$tdir/$tfile.bak \
4255                      $DIR/$tdir/$tfile.SAV \
4256                      $DIR/$tdir/$tfile.orig \
4257                      $DIR/$tdir/$tfile~; do
4258                 touch $fname  || error "touch $fname failed"
4259                 index2=$($LFS getstripe -m $fname)
4260                 [ $index -eq $index2 ] ||
4261                         error "$fname MDT index mismatch $index != $index2"
4262         done
4263
4264         local failed=0
4265         for i in {1..250}; do
4266                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4267                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4268                         touch $fname  || error "touch $fname failed"
4269                         index2=$($LFS getstripe -m $fname)
4270                         if [[ $index != $index2 ]]; then
4271                                 failed=$((failed + 1))
4272                                 echo "$fname MDT index mismatch $index != $index2"
4273                         fi
4274                 done
4275         done
4276         echo "$failed MDT index mismatches"
4277         (( failed < 20 )) || error "MDT index mismatch $failed times"
4278
4279 }
4280 run_test 33h "temp file is located on the same MDT as target"
4281
4282 test_33i()
4283 {
4284         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4285
4286         local FNAME=$(str_repeat 'f' 250)
4287
4288         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4289         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4290
4291         local count
4292         local total
4293
4294         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4295
4296         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4297
4298         lctl --device %$MDC deactivate
4299         stack_trap "lctl --device %$MDC activate"
4300         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4301         total=$(\ls -l $DIR/$tdir | wc -l)
4302         # "ls -l" will list total in the first line
4303         total=$((total - 1))
4304         (( total + count == 1000 )) ||
4305                 error "ls list $total files, $count files on MDT1"
4306 }
4307 run_test 33i "striped directory can be accessed when one MDT is down"
4308
4309 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4310 test_34a() {
4311         rm -f $DIR/f34
4312         $MCREATE $DIR/f34 || error "mcreate failed"
4313         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4314                 error "getstripe failed"
4315         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4316         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4317                 error "getstripe failed"
4318         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4319                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4320 }
4321 run_test 34a "truncate file that has not been opened ==========="
4322
4323 test_34b() {
4324         [ ! -f $DIR/f34 ] && test_34a
4325         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4326                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4327         $OPENFILE -f O_RDONLY $DIR/f34
4328         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4329                 error "getstripe failed"
4330         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4331                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4332 }
4333 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4334
4335 test_34c() {
4336         [ ! -f $DIR/f34 ] && test_34a
4337         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4338                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4339         $OPENFILE -f O_RDWR $DIR/f34
4340         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4341                 error "$LFS getstripe failed"
4342         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4343                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4344 }
4345 run_test 34c "O_RDWR opening file-with-size works =============="
4346
4347 test_34d() {
4348         [ ! -f $DIR/f34 ] && test_34a
4349         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4350                 error "dd failed"
4351         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4352                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4353         rm $DIR/f34
4354 }
4355 run_test 34d "write to sparse file ============================="
4356
4357 test_34e() {
4358         rm -f $DIR/f34e
4359         $MCREATE $DIR/f34e || error "mcreate failed"
4360         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4361         $CHECKSTAT -s 1000 $DIR/f34e ||
4362                 error "Size of $DIR/f34e not equal to 1000 bytes"
4363         $OPENFILE -f O_RDWR $DIR/f34e
4364         $CHECKSTAT -s 1000 $DIR/f34e ||
4365                 error "Size of $DIR/f34e not equal to 1000 bytes"
4366 }
4367 run_test 34e "create objects, some with size and some without =="
4368
4369 test_34f() { # bug 6242, 6243
4370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4371
4372         SIZE34F=48000
4373         rm -f $DIR/f34f
4374         $MCREATE $DIR/f34f || error "mcreate failed"
4375         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4376         dd if=$DIR/f34f of=$TMP/f34f
4377         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4378         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4379         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4380         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4381         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4382 }
4383 run_test 34f "read from a file with no objects until EOF ======="
4384
4385 test_34g() {
4386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4387
4388         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4389                 error "dd failed"
4390         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4391         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4392                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4393         cancel_lru_locks osc
4394         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4395                 error "wrong size after lock cancel"
4396
4397         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4398         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4399                 error "expanding truncate failed"
4400         cancel_lru_locks osc
4401         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4402                 error "wrong expanded size after lock cancel"
4403 }
4404 run_test 34g "truncate long file ==============================="
4405
4406 test_34h() {
4407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4408
4409         local gid=10
4410         local sz=1000
4411
4412         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4413         sync # Flush the cache so that multiop below does not block on cache
4414              # flush when getting the group lock
4415         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4416         MULTIPID=$!
4417
4418         # Since just timed wait is not good enough, let's do a sync write
4419         # that way we are sure enough time for a roundtrip + processing
4420         # passed + 2 seconds of extra margin.
4421         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4422         rm $DIR/${tfile}-1
4423         sleep 2
4424
4425         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4426                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4427                 kill -9 $MULTIPID
4428         fi
4429         wait $MULTIPID
4430         local nsz=`stat -c %s $DIR/$tfile`
4431         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4432 }
4433 run_test 34h "ftruncate file under grouplock should not block"
4434
4435 test_35a() {
4436         cp /bin/sh $DIR/f35a
4437         chmod 444 $DIR/f35a
4438         chown $RUNAS_ID $DIR/f35a
4439         $RUNAS $DIR/f35a && error || true
4440         rm $DIR/f35a
4441 }
4442 run_test 35a "exec file with mode 444 (should return and not leak)"
4443
4444 test_36a() {
4445         rm -f $DIR/f36
4446         utime $DIR/f36 || error "utime failed for MDS"
4447 }
4448 run_test 36a "MDS utime check (mknod, utime)"
4449
4450 test_36b() {
4451         echo "" > $DIR/f36
4452         utime $DIR/f36 || error "utime failed for OST"
4453 }
4454 run_test 36b "OST utime check (open, utime)"
4455
4456 test_36c() {
4457         rm -f $DIR/d36/f36
4458         test_mkdir $DIR/d36
4459         chown $RUNAS_ID $DIR/d36
4460         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4461 }
4462 run_test 36c "non-root MDS utime check (mknod, utime)"
4463
4464 test_36d() {
4465         [ ! -d $DIR/d36 ] && test_36c
4466         echo "" > $DIR/d36/f36
4467         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4468 }
4469 run_test 36d "non-root OST utime check (open, utime)"
4470
4471 test_36e() {
4472         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4473
4474         test_mkdir $DIR/$tdir
4475         touch $DIR/$tdir/$tfile
4476         $RUNAS utime $DIR/$tdir/$tfile &&
4477                 error "utime worked, expected failure" || true
4478 }
4479 run_test 36e "utime on non-owned file (should return error)"
4480
4481 subr_36fh() {
4482         local fl="$1"
4483         local LANG_SAVE=$LANG
4484         local LC_LANG_SAVE=$LC_LANG
4485         export LANG=C LC_LANG=C # for date language
4486
4487         DATESTR="Dec 20  2000"
4488         test_mkdir $DIR/$tdir
4489         lctl set_param fail_loc=$fl
4490         date; date +%s
4491         cp /etc/hosts $DIR/$tdir/$tfile
4492         sync & # write RPC generated with "current" inode timestamp, but delayed
4493         sleep 1
4494         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4495         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4496         cancel_lru_locks $OSC
4497         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4498         date; date +%s
4499         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4500                 echo "BEFORE: $LS_BEFORE" && \
4501                 echo "AFTER : $LS_AFTER" && \
4502                 echo "WANT  : $DATESTR" && \
4503                 error "$DIR/$tdir/$tfile timestamps changed" || true
4504
4505         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4506 }
4507
4508 test_36f() {
4509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4510
4511         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4512         subr_36fh "0x80000214"
4513 }
4514 run_test 36f "utime on file racing with OST BRW write =========="
4515
4516 test_36g() {
4517         remote_ost_nodsh && skip "remote OST with nodsh"
4518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4519         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4520                 skip "Need MDS version at least 2.12.51"
4521
4522         local fmd_max_age
4523         local fmd
4524         local facet="ost1"
4525         local tgt="obdfilter"
4526
4527         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4528
4529         test_mkdir $DIR/$tdir
4530         fmd_max_age=$(do_facet $facet \
4531                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4532                 head -n 1")
4533
4534         echo "FMD max age: ${fmd_max_age}s"
4535         touch $DIR/$tdir/$tfile
4536         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4537                 gawk '{cnt=cnt+$1}  END{print cnt}')
4538         echo "FMD before: $fmd"
4539         [[ $fmd == 0 ]] &&
4540                 error "FMD wasn't create by touch"
4541         sleep $((fmd_max_age + 12))
4542         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4543                 gawk '{cnt=cnt+$1}  END{print cnt}')
4544         echo "FMD after: $fmd"
4545         [[ $fmd == 0 ]] ||
4546                 error "FMD wasn't expired by ping"
4547 }
4548 run_test 36g "FMD cache expiry ====================="
4549
4550 test_36h() {
4551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4552
4553         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4554         subr_36fh "0x80000227"
4555 }
4556 run_test 36h "utime on file racing with OST BRW write =========="
4557
4558 test_36i() {
4559         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4560
4561         test_mkdir $DIR/$tdir
4562         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4563
4564         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4565         local new_mtime=$((mtime + 200))
4566
4567         #change Modify time of striped dir
4568         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4569                         error "change mtime failed"
4570
4571         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4572
4573         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4574 }
4575 run_test 36i "change mtime on striped directory"
4576
4577 # test_37 - duplicate with tests 32q 32r
4578
4579 test_38() {
4580         local file=$DIR/$tfile
4581         touch $file
4582         openfile -f O_DIRECTORY $file
4583         local RC=$?
4584         local ENOTDIR=20
4585         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4586         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4587 }
4588 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4589
4590 test_39a() { # was test_39
4591         touch $DIR/$tfile
4592         touch $DIR/${tfile}2
4593 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4594 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4595 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4596         sleep 2
4597         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4598         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4599                 echo "mtime"
4600                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4601                 echo "atime"
4602                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4603                 echo "ctime"
4604                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4605                 error "O_TRUNC didn't change timestamps"
4606         fi
4607 }
4608 run_test 39a "mtime changed on create"
4609
4610 test_39b() {
4611         test_mkdir -c1 $DIR/$tdir
4612         cp -p /etc/passwd $DIR/$tdir/fopen
4613         cp -p /etc/passwd $DIR/$tdir/flink
4614         cp -p /etc/passwd $DIR/$tdir/funlink
4615         cp -p /etc/passwd $DIR/$tdir/frename
4616         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4617
4618         sleep 1
4619         echo "aaaaaa" >> $DIR/$tdir/fopen
4620         echo "aaaaaa" >> $DIR/$tdir/flink
4621         echo "aaaaaa" >> $DIR/$tdir/funlink
4622         echo "aaaaaa" >> $DIR/$tdir/frename
4623
4624         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4625         local link_new=`stat -c %Y $DIR/$tdir/flink`
4626         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4627         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4628
4629         cat $DIR/$tdir/fopen > /dev/null
4630         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4631         rm -f $DIR/$tdir/funlink2
4632         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4633
4634         for (( i=0; i < 2; i++ )) ; do
4635                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4636                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4637                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4638                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4639
4640                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4641                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4642                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4643                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4644
4645                 cancel_lru_locks $OSC
4646                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4647         done
4648 }
4649 run_test 39b "mtime change on open, link, unlink, rename  ======"
4650
4651 # this should be set to past
4652 TEST_39_MTIME=`date -d "1 year ago" +%s`
4653
4654 # bug 11063
4655 test_39c() {
4656         touch $DIR1/$tfile
4657         sleep 2
4658         local mtime0=`stat -c %Y $DIR1/$tfile`
4659
4660         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4661         local mtime1=`stat -c %Y $DIR1/$tfile`
4662         [ "$mtime1" = $TEST_39_MTIME ] || \
4663                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4664
4665         local d1=`date +%s`
4666         echo hello >> $DIR1/$tfile
4667         local d2=`date +%s`
4668         local mtime2=`stat -c %Y $DIR1/$tfile`
4669         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4670                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4671
4672         mv $DIR1/$tfile $DIR1/$tfile-1
4673
4674         for (( i=0; i < 2; i++ )) ; do
4675                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4676                 [ "$mtime2" = "$mtime3" ] || \
4677                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4678
4679                 cancel_lru_locks $OSC
4680                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4681         done
4682 }
4683 run_test 39c "mtime change on rename ==========================="
4684
4685 # bug 21114
4686 test_39d() {
4687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4688
4689         touch $DIR1/$tfile
4690         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4691
4692         for (( i=0; i < 2; i++ )) ; do
4693                 local mtime=`stat -c %Y $DIR1/$tfile`
4694                 [ $mtime = $TEST_39_MTIME ] || \
4695                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4696
4697                 cancel_lru_locks $OSC
4698                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4699         done
4700 }
4701 run_test 39d "create, utime, stat =============================="
4702
4703 # bug 21114
4704 test_39e() {
4705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4706
4707         touch $DIR1/$tfile
4708         local mtime1=`stat -c %Y $DIR1/$tfile`
4709
4710         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4711
4712         for (( i=0; i < 2; i++ )) ; do
4713                 local mtime2=`stat -c %Y $DIR1/$tfile`
4714                 [ $mtime2 = $TEST_39_MTIME ] || \
4715                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4716
4717                 cancel_lru_locks $OSC
4718                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4719         done
4720 }
4721 run_test 39e "create, stat, utime, stat ========================"
4722
4723 # bug 21114
4724 test_39f() {
4725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4726
4727         touch $DIR1/$tfile
4728         mtime1=`stat -c %Y $DIR1/$tfile`
4729
4730         sleep 2
4731         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4732
4733         for (( i=0; i < 2; i++ )) ; do
4734                 local mtime2=`stat -c %Y $DIR1/$tfile`
4735                 [ $mtime2 = $TEST_39_MTIME ] || \
4736                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4737
4738                 cancel_lru_locks $OSC
4739                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4740         done
4741 }
4742 run_test 39f "create, stat, sleep, utime, stat ================="
4743
4744 # bug 11063
4745 test_39g() {
4746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4747
4748         echo hello >> $DIR1/$tfile
4749         local mtime1=`stat -c %Y $DIR1/$tfile`
4750
4751         sleep 2
4752         chmod o+r $DIR1/$tfile
4753
4754         for (( i=0; i < 2; i++ )) ; do
4755                 local mtime2=`stat -c %Y $DIR1/$tfile`
4756                 [ "$mtime1" = "$mtime2" ] || \
4757                         error "lost mtime: $mtime2, should be $mtime1"
4758
4759                 cancel_lru_locks $OSC
4760                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4761         done
4762 }
4763 run_test 39g "write, chmod, stat ==============================="
4764
4765 # bug 11063
4766 test_39h() {
4767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4768
4769         touch $DIR1/$tfile
4770         sleep 1
4771
4772         local d1=`date`
4773         echo hello >> $DIR1/$tfile
4774         local mtime1=`stat -c %Y $DIR1/$tfile`
4775
4776         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4777         local d2=`date`
4778         if [ "$d1" != "$d2" ]; then
4779                 echo "write and touch not within one second"
4780         else
4781                 for (( i=0; i < 2; i++ )) ; do
4782                         local mtime2=`stat -c %Y $DIR1/$tfile`
4783                         [ "$mtime2" = $TEST_39_MTIME ] || \
4784                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4785
4786                         cancel_lru_locks $OSC
4787                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4788                 done
4789         fi
4790 }
4791 run_test 39h "write, utime within one second, stat ============="
4792
4793 test_39i() {
4794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4795
4796         touch $DIR1/$tfile
4797         sleep 1
4798
4799         echo hello >> $DIR1/$tfile
4800         local mtime1=`stat -c %Y $DIR1/$tfile`
4801
4802         mv $DIR1/$tfile $DIR1/$tfile-1
4803
4804         for (( i=0; i < 2; i++ )) ; do
4805                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4806
4807                 [ "$mtime1" = "$mtime2" ] || \
4808                         error "lost mtime: $mtime2, should be $mtime1"
4809
4810                 cancel_lru_locks $OSC
4811                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4812         done
4813 }
4814 run_test 39i "write, rename, stat =============================="
4815
4816 test_39j() {
4817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4818
4819         start_full_debug_logging
4820         touch $DIR1/$tfile
4821         sleep 1
4822
4823         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4824         lctl set_param fail_loc=0x80000412
4825         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4826                 error "multiop failed"
4827         local multipid=$!
4828         local mtime1=`stat -c %Y $DIR1/$tfile`
4829
4830         mv $DIR1/$tfile $DIR1/$tfile-1
4831
4832         kill -USR1 $multipid
4833         wait $multipid || error "multiop close failed"
4834
4835         for (( i=0; i < 2; i++ )) ; do
4836                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4837                 [ "$mtime1" = "$mtime2" ] ||
4838                         error "mtime is lost on close: $mtime2, " \
4839                               "should be $mtime1"
4840
4841                 cancel_lru_locks
4842                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4843         done
4844         lctl set_param fail_loc=0
4845         stop_full_debug_logging
4846 }
4847 run_test 39j "write, rename, close, stat ======================="
4848
4849 test_39k() {
4850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4851
4852         touch $DIR1/$tfile
4853         sleep 1
4854
4855         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4856         local multipid=$!
4857         local mtime1=`stat -c %Y $DIR1/$tfile`
4858
4859         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4860
4861         kill -USR1 $multipid
4862         wait $multipid || error "multiop close failed"
4863
4864         for (( i=0; i < 2; i++ )) ; do
4865                 local mtime2=`stat -c %Y $DIR1/$tfile`
4866
4867                 [ "$mtime2" = $TEST_39_MTIME ] || \
4868                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4869
4870                 cancel_lru_locks
4871                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4872         done
4873 }
4874 run_test 39k "write, utime, close, stat ========================"
4875
4876 # this should be set to future
4877 TEST_39_ATIME=`date -d "1 year" +%s`
4878
4879 test_39l() {
4880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4881         remote_mds_nodsh && skip "remote MDS with nodsh"
4882
4883         local atime_diff=$(do_facet $SINGLEMDS \
4884                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4885         rm -rf $DIR/$tdir
4886         mkdir_on_mdt0 $DIR/$tdir
4887
4888         # test setting directory atime to future
4889         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4890         local atime=$(stat -c %X $DIR/$tdir)
4891         [ "$atime" = $TEST_39_ATIME ] ||
4892                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4893
4894         # test setting directory atime from future to now
4895         local now=$(date +%s)
4896         touch -a -d @$now $DIR/$tdir
4897
4898         atime=$(stat -c %X $DIR/$tdir)
4899         [ "$atime" -eq "$now"  ] ||
4900                 error "atime is not updated from future: $atime, $now"
4901
4902         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4903         sleep 3
4904
4905         # test setting directory atime when now > dir atime + atime_diff
4906         local d1=$(date +%s)
4907         ls $DIR/$tdir
4908         local d2=$(date +%s)
4909         cancel_lru_locks mdc
4910         atime=$(stat -c %X $DIR/$tdir)
4911         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4912                 error "atime is not updated  : $atime, should be $d2"
4913
4914         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4915         sleep 3
4916
4917         # test not setting directory atime when now < dir atime + atime_diff
4918         ls $DIR/$tdir
4919         cancel_lru_locks mdc
4920         atime=$(stat -c %X $DIR/$tdir)
4921         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4922                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4923
4924         do_facet $SINGLEMDS \
4925                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4926 }
4927 run_test 39l "directory atime update ==========================="
4928
4929 test_39m() {
4930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4931
4932         touch $DIR1/$tfile
4933         sleep 2
4934         local far_past_mtime=$(date -d "May 29 1953" +%s)
4935         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4936
4937         touch -m -d @$far_past_mtime $DIR1/$tfile
4938         touch -a -d @$far_past_atime $DIR1/$tfile
4939
4940         for (( i=0; i < 2; i++ )) ; do
4941                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4942                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4943                         error "atime or mtime set incorrectly"
4944
4945                 cancel_lru_locks $OSC
4946                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4947         done
4948 }
4949 run_test 39m "test atime and mtime before 1970"
4950
4951 test_39n() { # LU-3832
4952         remote_mds_nodsh && skip "remote MDS with nodsh"
4953
4954         local atime_diff=$(do_facet $SINGLEMDS \
4955                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4956         local atime0
4957         local atime1
4958         local atime2
4959
4960         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4961
4962         rm -rf $DIR/$tfile
4963         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4964         atime0=$(stat -c %X $DIR/$tfile)
4965
4966         sleep 5
4967         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4968         atime1=$(stat -c %X $DIR/$tfile)
4969
4970         sleep 5
4971         cancel_lru_locks mdc
4972         cancel_lru_locks osc
4973         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4974         atime2=$(stat -c %X $DIR/$tfile)
4975
4976         do_facet $SINGLEMDS \
4977                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4978
4979         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4980         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4981 }
4982 run_test 39n "check that O_NOATIME is honored"
4983
4984 test_39o() {
4985         TESTDIR=$DIR/$tdir/$tfile
4986         [ -e $TESTDIR ] && rm -rf $TESTDIR
4987         mkdir -p $TESTDIR
4988         cd $TESTDIR
4989         links1=2
4990         ls
4991         mkdir a b
4992         ls
4993         links2=$(stat -c %h .)
4994         [ $(($links1 + 2)) != $links2 ] &&
4995                 error "wrong links count $(($links1 + 2)) != $links2"
4996         rmdir b
4997         links3=$(stat -c %h .)
4998         [ $(($links1 + 1)) != $links3 ] &&
4999                 error "wrong links count $links1 != $links3"
5000         return 0
5001 }
5002 run_test 39o "directory cached attributes updated after create"
5003
5004 test_39p() {
5005         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5006
5007         local MDTIDX=1
5008         TESTDIR=$DIR/$tdir/$tdir
5009         [ -e $TESTDIR ] && rm -rf $TESTDIR
5010         test_mkdir -p $TESTDIR
5011         cd $TESTDIR
5012         links1=2
5013         ls
5014         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5015         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5016         ls
5017         links2=$(stat -c %h .)
5018         [ $(($links1 + 2)) != $links2 ] &&
5019                 error "wrong links count $(($links1 + 2)) != $links2"
5020         rmdir remote_dir2
5021         links3=$(stat -c %h .)
5022         [ $(($links1 + 1)) != $links3 ] &&
5023                 error "wrong links count $links1 != $links3"
5024         return 0
5025 }
5026 run_test 39p "remote directory cached attributes updated after create ========"
5027
5028 test_39r() {
5029         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5030                 skip "no atime update on old OST"
5031         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5032                 skip_env "ldiskfs only test"
5033         fi
5034
5035         local saved_adiff
5036         saved_adiff=$(do_facet ost1 \
5037                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5038         stack_trap "do_facet ost1 \
5039                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5040
5041         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5042
5043         $LFS setstripe -i 0 $DIR/$tfile
5044         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5045                 error "can't write initial file"
5046         cancel_lru_locks osc
5047
5048         # exceed atime_diff and access file
5049         sleep 6
5050         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5051                 error "can't udpate atime"
5052
5053         local atime_cli=$(stat -c %X $DIR/$tfile)
5054         echo "client atime: $atime_cli"
5055         # allow atime update to be written to device
5056         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5057         sleep 5
5058
5059         local ostdev=$(ostdevname 1)
5060         local fid=($(lfs getstripe -y $DIR/$tfile |
5061                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5062         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5063         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5064
5065         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5066         local atime_ost=$(do_facet ost1 "$cmd" |&
5067                           awk -F'[: ]' '/atime:/ { print $4 }')
5068         (( atime_cli == atime_ost )) ||
5069                 error "atime on client $atime_cli != ost $atime_ost"
5070 }
5071 run_test 39r "lazy atime update on OST"
5072
5073 test_39q() { # LU-8041
5074         local testdir=$DIR/$tdir
5075         mkdir -p $testdir
5076         multiop_bg_pause $testdir D_c || error "multiop failed"
5077         local multipid=$!
5078         cancel_lru_locks mdc
5079         kill -USR1 $multipid
5080         local atime=$(stat -c %X $testdir)
5081         [ "$atime" -ne 0 ] || error "atime is zero"
5082 }
5083 run_test 39q "close won't zero out atime"
5084
5085 test_40() {
5086         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5087         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5088                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5089         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5090                 error "$tfile is not 4096 bytes in size"
5091 }
5092 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5093
5094 test_41() {
5095         # bug 1553
5096         small_write $DIR/f41 18
5097 }
5098 run_test 41 "test small file write + fstat ====================="
5099
5100 count_ost_writes() {
5101         lctl get_param -n ${OSC}.*.stats |
5102                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5103                         END { printf("%0.0f", writes) }'
5104 }
5105
5106 # decent default
5107 WRITEBACK_SAVE=500
5108 DIRTY_RATIO_SAVE=40
5109 MAX_DIRTY_RATIO=50
5110 BG_DIRTY_RATIO_SAVE=10
5111 MAX_BG_DIRTY_RATIO=25
5112
5113 start_writeback() {
5114         trap 0
5115         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5116         # dirty_ratio, dirty_background_ratio
5117         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5118                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5119                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5120                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5121         else
5122                 # if file not here, we are a 2.4 kernel
5123                 kill -CONT `pidof kupdated`
5124         fi
5125 }
5126
5127 stop_writeback() {
5128         # setup the trap first, so someone cannot exit the test at the
5129         # exact wrong time and mess up a machine
5130         trap start_writeback EXIT
5131         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5132         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5133                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5134                 sysctl -w vm.dirty_writeback_centisecs=0
5135                 sysctl -w vm.dirty_writeback_centisecs=0
5136                 # save and increase /proc/sys/vm/dirty_ratio
5137                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5138                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5139                 # save and increase /proc/sys/vm/dirty_background_ratio
5140                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5141                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5142         else
5143                 # if file not here, we are a 2.4 kernel
5144                 kill -STOP `pidof kupdated`
5145         fi
5146 }
5147
5148 # ensure that all stripes have some grant before we test client-side cache
5149 setup_test42() {
5150         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5151                 dd if=/dev/zero of=$i bs=4k count=1
5152                 rm $i
5153         done
5154 }
5155
5156 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5157 # file truncation, and file removal.
5158 test_42a() {
5159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5160
5161         setup_test42
5162         cancel_lru_locks $OSC
5163         stop_writeback
5164         sync; sleep 1; sync # just to be safe
5165         BEFOREWRITES=`count_ost_writes`
5166         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5167         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5168         AFTERWRITES=`count_ost_writes`
5169         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5170                 error "$BEFOREWRITES < $AFTERWRITES"
5171         start_writeback
5172 }
5173 run_test 42a "ensure that we don't flush on close"
5174
5175 test_42b() {
5176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5177
5178         setup_test42
5179         cancel_lru_locks $OSC
5180         stop_writeback
5181         sync
5182         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5183         BEFOREWRITES=$(count_ost_writes)
5184         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5185         AFTERWRITES=$(count_ost_writes)
5186         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5187                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5188         fi
5189         BEFOREWRITES=$(count_ost_writes)
5190         sync || error "sync: $?"
5191         AFTERWRITES=$(count_ost_writes)
5192         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5193                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5194         fi
5195         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5196         start_writeback
5197         return 0
5198 }
5199 run_test 42b "test destroy of file with cached dirty data ======"
5200
5201 # if these tests just want to test the effect of truncation,
5202 # they have to be very careful.  consider:
5203 # - the first open gets a {0,EOF}PR lock
5204 # - the first write conflicts and gets a {0, count-1}PW
5205 # - the rest of the writes are under {count,EOF}PW
5206 # - the open for truncate tries to match a {0,EOF}PR
5207 #   for the filesize and cancels the PWs.
5208 # any number of fixes (don't get {0,EOF} on open, match
5209 # composite locks, do smarter file size management) fix
5210 # this, but for now we want these tests to verify that
5211 # the cancellation with truncate intent works, so we
5212 # start the file with a full-file pw lock to match against
5213 # until the truncate.
5214 trunc_test() {
5215         test=$1
5216         file=$DIR/$test
5217         offset=$2
5218         cancel_lru_locks $OSC
5219         stop_writeback
5220         # prime the file with 0,EOF PW to match
5221         touch $file
5222         $TRUNCATE $file 0
5223         sync; sync
5224         # now the real test..
5225         dd if=/dev/zero of=$file bs=1024 count=100
5226         BEFOREWRITES=`count_ost_writes`
5227         $TRUNCATE $file $offset
5228         cancel_lru_locks $OSC
5229         AFTERWRITES=`count_ost_writes`
5230         start_writeback
5231 }
5232
5233 test_42c() {
5234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5235
5236         trunc_test 42c 1024
5237         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5238                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5239         rm $file
5240 }
5241 run_test 42c "test partial truncate of file with cached dirty data"
5242
5243 test_42d() {
5244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5245
5246         trunc_test 42d 0
5247         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5248                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5249         rm $file
5250 }
5251 run_test 42d "test complete truncate of file with cached dirty data"
5252
5253 test_42e() { # bug22074
5254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5255
5256         local TDIR=$DIR/${tdir}e
5257         local pages=16 # hardcoded 16 pages, don't change it.
5258         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5259         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5260         local max_dirty_mb
5261         local warmup_files
5262
5263         test_mkdir $DIR/${tdir}e
5264         $LFS setstripe -c 1 $TDIR
5265         createmany -o $TDIR/f $files
5266
5267         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5268
5269         # we assume that with $OSTCOUNT files, at least one of them will
5270         # be allocated on OST0.
5271         warmup_files=$((OSTCOUNT * max_dirty_mb))
5272         createmany -o $TDIR/w $warmup_files
5273
5274         # write a large amount of data into one file and sync, to get good
5275         # avail_grant number from OST.
5276         for ((i=0; i<$warmup_files; i++)); do
5277                 idx=$($LFS getstripe -i $TDIR/w$i)
5278                 [ $idx -ne 0 ] && continue
5279                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5280                 break
5281         done
5282         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5283         sync
5284         $LCTL get_param $proc_osc0/cur_dirty_bytes
5285         $LCTL get_param $proc_osc0/cur_grant_bytes
5286
5287         # create as much dirty pages as we can while not to trigger the actual
5288         # RPCs directly. but depends on the env, VFS may trigger flush during this
5289         # period, hopefully we are good.
5290         for ((i=0; i<$warmup_files; i++)); do
5291                 idx=$($LFS getstripe -i $TDIR/w$i)
5292                 [ $idx -ne 0 ] && continue
5293                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5294         done
5295         $LCTL get_param $proc_osc0/cur_dirty_bytes
5296         $LCTL get_param $proc_osc0/cur_grant_bytes
5297
5298         # perform the real test
5299         $LCTL set_param $proc_osc0/rpc_stats 0
5300         for ((;i<$files; i++)); do
5301                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5302                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5303         done
5304         sync
5305         $LCTL get_param $proc_osc0/rpc_stats
5306
5307         local percent=0
5308         local have_ppr=false
5309         $LCTL get_param $proc_osc0/rpc_stats |
5310                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5311                         # skip lines until we are at the RPC histogram data
5312                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5313                         $have_ppr || continue
5314
5315                         # we only want the percent stat for < 16 pages
5316                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5317
5318                         percent=$((percent + WPCT))
5319                         if [[ $percent -gt 15 ]]; then
5320                                 error "less than 16-pages write RPCs" \
5321                                       "$percent% > 15%"
5322                                 break
5323                         fi
5324                 done
5325         rm -rf $TDIR
5326 }
5327 run_test 42e "verify sub-RPC writes are not done synchronously"
5328
5329 test_43A() { # was test_43
5330         test_mkdir $DIR/$tdir
5331         cp -p /bin/ls $DIR/$tdir/$tfile
5332         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5333         pid=$!
5334         # give multiop a chance to open
5335         sleep 1
5336
5337         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5338         kill -USR1 $pid
5339         # Wait for multiop to exit
5340         wait $pid
5341 }
5342 run_test 43A "execution of file opened for write should return -ETXTBSY"
5343
5344 test_43a() {
5345         test_mkdir $DIR/$tdir
5346         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5347         $DIR/$tdir/sleep 60 &
5348         SLEEP_PID=$!
5349         # Make sure exec of $tdir/sleep wins race with truncate
5350         sleep 1
5351         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5352         kill $SLEEP_PID
5353 }
5354 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5355
5356 test_43b() {
5357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5358
5359         test_mkdir $DIR/$tdir
5360         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5361         $DIR/$tdir/sleep 60 &
5362         SLEEP_PID=$!
5363         # Make sure exec of $tdir/sleep wins race with truncate
5364         sleep 1
5365         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5366         kill $SLEEP_PID
5367 }
5368 run_test 43b "truncate of file being executed should return -ETXTBSY"
5369
5370 test_43c() {
5371         local testdir="$DIR/$tdir"
5372         test_mkdir $testdir
5373         cp $SHELL $testdir/
5374         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5375                 ( cd $testdir && md5sum -c )
5376 }
5377 run_test 43c "md5sum of copy into lustre"
5378
5379 test_44A() { # was test_44
5380         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5381
5382         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5383         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5384 }
5385 run_test 44A "zero length read from a sparse stripe"
5386
5387 test_44a() {
5388         local nstripe=$($LFS getstripe -c -d $DIR)
5389         [ -z "$nstripe" ] && skip "can't get stripe info"
5390         [[ $nstripe -gt $OSTCOUNT ]] &&
5391                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5392
5393         local stride=$($LFS getstripe -S -d $DIR)
5394         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5395                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5396         fi
5397
5398         OFFSETS="0 $((stride/2)) $((stride-1))"
5399         for offset in $OFFSETS; do
5400                 for i in $(seq 0 $((nstripe-1))); do
5401                         local GLOBALOFFSETS=""
5402                         # size in Bytes
5403                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5404                         local myfn=$DIR/d44a-$size
5405                         echo "--------writing $myfn at $size"
5406                         ll_sparseness_write $myfn $size ||
5407                                 error "ll_sparseness_write"
5408                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5409                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5410                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5411
5412                         for j in $(seq 0 $((nstripe-1))); do
5413                                 # size in Bytes
5414                                 size=$((((j + $nstripe )*$stride + $offset)))
5415                                 ll_sparseness_write $myfn $size ||
5416                                         error "ll_sparseness_write"
5417                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5418                         done
5419                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5420                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5421                         rm -f $myfn
5422                 done
5423         done
5424 }
5425 run_test 44a "test sparse pwrite ==============================="
5426
5427 dirty_osc_total() {
5428         tot=0
5429         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5430                 tot=$(($tot + $d))
5431         done
5432         echo $tot
5433 }
5434 do_dirty_record() {
5435         before=`dirty_osc_total`
5436         echo executing "\"$*\""
5437         eval $*
5438         after=`dirty_osc_total`
5439         echo before $before, after $after
5440 }
5441 test_45() {
5442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5443
5444         f="$DIR/f45"
5445         # Obtain grants from OST if it supports it
5446         echo blah > ${f}_grant
5447         stop_writeback
5448         sync
5449         do_dirty_record "echo blah > $f"
5450         [[ $before -eq $after ]] && error "write wasn't cached"
5451         do_dirty_record "> $f"
5452         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5453         do_dirty_record "echo blah > $f"
5454         [[ $before -eq $after ]] && error "write wasn't cached"
5455         do_dirty_record "sync"
5456         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5457         do_dirty_record "echo blah > $f"
5458         [[ $before -eq $after ]] && error "write wasn't cached"
5459         do_dirty_record "cancel_lru_locks osc"
5460         [[ $before -gt $after ]] ||
5461                 error "lock cancellation didn't lower dirty count"
5462         start_writeback
5463 }
5464 run_test 45 "osc io page accounting ============================"
5465
5466 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5467 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5468 # objects offset and an assert hit when an rpc was built with 1023's mapped
5469 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5470 test_46() {
5471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5472
5473         f="$DIR/f46"
5474         stop_writeback
5475         sync
5476         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5477         sync
5478         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5479         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5480         sync
5481         start_writeback
5482 }
5483 run_test 46 "dirtying a previously written page ================"
5484
5485 # test_47 is removed "Device nodes check" is moved to test_28
5486
5487 test_48a() { # bug 2399
5488         [ "$mds1_FSTYPE" = "zfs" ] &&
5489         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5490                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5491
5492         test_mkdir $DIR/$tdir
5493         cd $DIR/$tdir
5494         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5495         test_mkdir $DIR/$tdir
5496         touch foo || error "'touch foo' failed after recreating cwd"
5497         test_mkdir bar
5498         touch .foo || error "'touch .foo' failed after recreating cwd"
5499         test_mkdir .bar
5500         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5501         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5502         cd . || error "'cd .' failed after recreating cwd"
5503         mkdir . && error "'mkdir .' worked after recreating cwd"
5504         rmdir . && error "'rmdir .' worked after recreating cwd"
5505         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5506         cd .. || error "'cd ..' failed after recreating cwd"
5507 }
5508 run_test 48a "Access renamed working dir (should return errors)="
5509
5510 test_48b() { # bug 2399
5511         rm -rf $DIR/$tdir
5512         test_mkdir $DIR/$tdir
5513         cd $DIR/$tdir
5514         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5515         touch foo && error "'touch foo' worked after removing cwd"
5516         mkdir foo && error "'mkdir foo' worked after removing cwd"
5517         touch .foo && error "'touch .foo' worked after removing cwd"
5518         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5519         ls . > /dev/null && error "'ls .' worked after removing cwd"
5520         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5521         mkdir . && error "'mkdir .' worked after removing cwd"
5522         rmdir . && error "'rmdir .' worked after removing cwd"
5523         ln -s . foo && error "'ln -s .' worked after removing cwd"
5524         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5525 }
5526 run_test 48b "Access removed working dir (should return errors)="
5527
5528 test_48c() { # bug 2350
5529         #lctl set_param debug=-1
5530         #set -vx
5531         rm -rf $DIR/$tdir
5532         test_mkdir -p $DIR/$tdir/dir
5533         cd $DIR/$tdir/dir
5534         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5535         $TRACE touch foo && error "touch foo worked after removing cwd"
5536         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5537         touch .foo && error "touch .foo worked after removing cwd"
5538         mkdir .foo && error "mkdir .foo worked after removing cwd"
5539         $TRACE ls . && error "'ls .' worked after removing cwd"
5540         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5541         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5542         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5543         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5544         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5545 }
5546 run_test 48c "Access removed working subdir (should return errors)"
5547
5548 test_48d() { # bug 2350
5549         #lctl set_param debug=-1
5550         #set -vx
5551         rm -rf $DIR/$tdir
5552         test_mkdir -p $DIR/$tdir/dir
5553         cd $DIR/$tdir/dir
5554         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5555         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5556         $TRACE touch foo && error "'touch foo' worked after removing parent"
5557         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5558         touch .foo && error "'touch .foo' worked after removing parent"
5559         mkdir .foo && error "mkdir .foo worked after removing parent"
5560         $TRACE ls . && error "'ls .' worked after removing parent"
5561         $TRACE ls .. && error "'ls ..' worked after removing parent"
5562         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5563         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5564         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5565         true
5566 }
5567 run_test 48d "Access removed parent subdir (should return errors)"
5568
5569 test_48e() { # bug 4134
5570         #lctl set_param debug=-1
5571         #set -vx
5572         rm -rf $DIR/$tdir
5573         test_mkdir -p $DIR/$tdir/dir
5574         cd $DIR/$tdir/dir
5575         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5576         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5577         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5578         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5579         # On a buggy kernel addition of "touch foo" after cd .. will
5580         # produce kernel oops in lookup_hash_it
5581         touch ../foo && error "'cd ..' worked after recreate parent"
5582         cd $DIR
5583         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5584 }
5585 run_test 48e "Access to recreated parent subdir (should return errors)"
5586
5587 test_48f() {
5588         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5589                 skip "need MDS >= 2.13.55"
5590         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5591         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5592                 skip "needs different host for mdt1 mdt2"
5593         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5594
5595         $LFS mkdir -i0 $DIR/$tdir
5596         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5597
5598         for d in sub1 sub2 sub3; do
5599                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5600                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5601                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5602         done
5603
5604         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5605 }
5606 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5607
5608 test_49() { # LU-1030
5609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5610         remote_ost_nodsh && skip "remote OST with nodsh"
5611
5612         # get ost1 size - $FSNAME-OST0000
5613         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5614                 awk '{ print $4 }')
5615         # write 800M at maximum
5616         [[ $ost1_size -lt 2 ]] && ost1_size=2
5617         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5618
5619         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5620         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5621         local dd_pid=$!
5622
5623         # change max_pages_per_rpc while writing the file
5624         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5625         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5626         # loop until dd process exits
5627         while ps ax -opid | grep -wq $dd_pid; do
5628                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5629                 sleep $((RANDOM % 5 + 1))
5630         done
5631         # restore original max_pages_per_rpc
5632         $LCTL set_param $osc1_mppc=$orig_mppc
5633         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5634 }
5635 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5636
5637 test_50() {
5638         # bug 1485
5639         test_mkdir $DIR/$tdir
5640         cd $DIR/$tdir
5641         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5642 }
5643 run_test 50 "special situations: /proc symlinks  ==============="
5644
5645 test_51a() {    # was test_51
5646         # bug 1516 - create an empty entry right after ".." then split dir
5647         test_mkdir -c1 $DIR/$tdir
5648         touch $DIR/$tdir/foo
5649         $MCREATE $DIR/$tdir/bar
5650         rm $DIR/$tdir/foo
5651         createmany -m $DIR/$tdir/longfile 201
5652         FNUM=202
5653         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5654                 $MCREATE $DIR/$tdir/longfile$FNUM
5655                 FNUM=$(($FNUM + 1))
5656                 echo -n "+"
5657         done
5658         echo
5659         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5660 }
5661 run_test 51a "special situations: split htree with empty entry =="
5662
5663 cleanup_print_lfs_df () {
5664         trap 0
5665         $LFS df
5666         $LFS df -i
5667 }
5668
5669 test_51b() {
5670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5671
5672         local dir=$DIR/$tdir
5673         local nrdirs=$((65536 + 100))
5674
5675         # cleanup the directory
5676         rm -fr $dir
5677
5678         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5679
5680         $LFS df
5681         $LFS df -i
5682         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5683         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5684         [[ $numfree -lt $nrdirs ]] &&
5685                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5686
5687         # need to check free space for the directories as well
5688         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5689         numfree=$(( blkfree / $(fs_inode_ksize) ))
5690         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5691
5692         trap cleanup_print_lfs_df EXIT
5693
5694         # create files
5695         createmany -d $dir/d $nrdirs || {
5696                 unlinkmany $dir/d $nrdirs
5697                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5698         }
5699
5700         # really created :
5701         nrdirs=$(ls -U $dir | wc -l)
5702
5703         # unlink all but 100 subdirectories, then check it still works
5704         local left=100
5705         local delete=$((nrdirs - left))
5706
5707         $LFS df
5708         $LFS df -i
5709
5710         # for ldiskfs the nlink count should be 1, but this is OSD specific
5711         # and so this is listed for informational purposes only
5712         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5713         unlinkmany -d $dir/d $delete ||
5714                 error "unlink of first $delete subdirs failed"
5715
5716         echo "nlink between: $(stat -c %h $dir)"
5717         local found=$(ls -U $dir | wc -l)
5718         [ $found -ne $left ] &&
5719                 error "can't find subdirs: found only $found, expected $left"
5720
5721         unlinkmany -d $dir/d $delete $left ||
5722                 error "unlink of second $left subdirs failed"
5723         # regardless of whether the backing filesystem tracks nlink accurately
5724         # or not, the nlink count shouldn't be more than "." and ".." here
5725         local after=$(stat -c %h $dir)
5726         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5727                 echo "nlink after: $after"
5728
5729         cleanup_print_lfs_df
5730 }
5731 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5732
5733 test_51d() {
5734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5735         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5736         local qos_old
5737
5738         test_mkdir $DIR/$tdir
5739         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5740
5741         qos_old=$(do_facet mds1 \
5742                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5743         do_nodes $(comma_list $(mdts_nodes)) \
5744                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5745         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5746                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5747
5748         createmany -o $DIR/$tdir/t- 1000
5749         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5750         for ((n = 0; n < $OSTCOUNT; n++)); do
5751                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5752                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5753                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5754                             '($1 == '$n') { objs += 1 } \
5755                             END { printf("%0.0f", objs) }')
5756                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5757         done
5758         unlinkmany $DIR/$tdir/t- 1000
5759
5760         nlast=0
5761         for ((n = 0; n < $OSTCOUNT; n++)); do
5762                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5763                         { $LFS df && $LFS df -i &&
5764                         error "OST $n has fewer objects vs. OST $nlast" \
5765                               " (${objs[$n]} < ${objs[$nlast]}"; }
5766                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5767                         { $LFS df && $LFS df -i &&
5768                         error "OST $n has fewer objects vs. OST $nlast" \
5769                               " (${objs[$n]} < ${objs[$nlast]}"; }
5770
5771                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5772                         { $LFS df && $LFS df -i &&
5773                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5774                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5775                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5776                         { $LFS df && $LFS df -i &&
5777                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5778                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5779                 nlast=$n
5780         done
5781 }
5782 run_test 51d "check object distribution"
5783
5784 test_51e() {
5785         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5786                 skip_env "ldiskfs only test"
5787         fi
5788
5789         test_mkdir -c1 $DIR/$tdir
5790         test_mkdir -c1 $DIR/$tdir/d0
5791
5792         touch $DIR/$tdir/d0/foo
5793         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5794                 error "file exceed 65000 nlink limit!"
5795         unlinkmany $DIR/$tdir/d0/f- 65001
5796         return 0
5797 }
5798 run_test 51e "check file nlink limit"
5799
5800 test_51f() {
5801         test_mkdir $DIR/$tdir
5802
5803         local max=100000
5804         local ulimit_old=$(ulimit -n)
5805         local spare=20 # number of spare fd's for scripts/libraries, etc.
5806         local mdt=$($LFS getstripe -m $DIR/$tdir)
5807         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5808
5809         echo "MDT$mdt numfree=$numfree, max=$max"
5810         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5811         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5812                 while ! ulimit -n $((numfree + spare)); do
5813                         numfree=$((numfree * 3 / 4))
5814                 done
5815                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5816         else
5817                 echo "left ulimit at $ulimit_old"
5818         fi
5819
5820         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5821                 unlinkmany $DIR/$tdir/f $numfree
5822                 error "create+open $numfree files in $DIR/$tdir failed"
5823         }
5824         ulimit -n $ulimit_old
5825
5826         # if createmany exits at 120s there will be fewer than $numfree files
5827         unlinkmany $DIR/$tdir/f $numfree || true
5828 }
5829 run_test 51f "check many open files limit"
5830
5831 test_52a() {
5832         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5833         test_mkdir $DIR/$tdir
5834         touch $DIR/$tdir/foo
5835         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5836         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5837         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5838         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5839         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5840                                         error "link worked"
5841         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5842         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5843         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5844                                                      error "lsattr"
5845         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5846         cp -r $DIR/$tdir $TMP/
5847         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5848 }
5849 run_test 52a "append-only flag test (should return errors)"
5850
5851 test_52b() {
5852         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5853         test_mkdir $DIR/$tdir
5854         touch $DIR/$tdir/foo
5855         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5856         cat test > $DIR/$tdir/foo && error "cat test worked"
5857         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5858         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5859         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5860                                         error "link worked"
5861         echo foo >> $DIR/$tdir/foo && error "echo worked"
5862         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5863         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5864         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5865         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5866                                                         error "lsattr"
5867         chattr -i $DIR/$tdir/foo || error "chattr failed"
5868
5869         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5870 }
5871 run_test 52b "immutable flag test (should return errors) ======="
5872
5873 test_53() {
5874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5875         remote_mds_nodsh && skip "remote MDS with nodsh"
5876         remote_ost_nodsh && skip "remote OST with nodsh"
5877
5878         local param
5879         local param_seq
5880         local ostname
5881         local mds_last
5882         local mds_last_seq
5883         local ost_last
5884         local ost_last_seq
5885         local ost_last_id
5886         local ostnum
5887         local node
5888         local found=false
5889         local support_last_seq=true
5890
5891         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5892                 support_last_seq=false
5893
5894         # only test MDT0000
5895         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5896         local value
5897         for value in $(do_facet $SINGLEMDS \
5898                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5899                 param=$(echo ${value[0]} | cut -d "=" -f1)
5900                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5901
5902                 if $support_last_seq; then
5903                         param_seq=$(echo $param |
5904                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5905                         mds_last_seq=$(do_facet $SINGLEMDS \
5906                                        $LCTL get_param -n $param_seq)
5907                 fi
5908                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5909
5910                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5911                 node=$(facet_active_host ost$((ostnum+1)))
5912                 param="obdfilter.$ostname.last_id"
5913                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5914                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5915                         ost_last_id=$ost_last
5916
5917                         if $support_last_seq; then
5918                                 ost_last_id=$(echo $ost_last |
5919                                               awk -F':' '{print $2}' |
5920                                               sed -e "s/^0x//g")
5921                                 ost_last_seq=$(echo $ost_last |
5922                                                awk -F':' '{print $1}')
5923                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5924                         fi
5925
5926                         if [[ $ost_last_id != $mds_last ]]; then
5927                                 error "$ost_last_id != $mds_last"
5928                         else
5929                                 found=true
5930                                 break
5931                         fi
5932                 done
5933         done
5934         $found || error "can not match last_seq/last_id for $mdtosc"
5935         return 0
5936 }
5937 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5938
5939 test_54a() {
5940         perl -MSocket -e ';' || skip "no Socket perl module installed"
5941
5942         $SOCKETSERVER $DIR/socket ||
5943                 error "$SOCKETSERVER $DIR/socket failed: $?"
5944         $SOCKETCLIENT $DIR/socket ||
5945                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5946         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5947 }
5948 run_test 54a "unix domain socket test =========================="
5949
5950 test_54b() {
5951         f="$DIR/f54b"
5952         mknod $f c 1 3
5953         chmod 0666 $f
5954         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5955 }
5956 run_test 54b "char device works in lustre ======================"
5957
5958 find_loop_dev() {
5959         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5960         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5961         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5962
5963         for i in $(seq 3 7); do
5964                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5965                 LOOPDEV=$LOOPBASE$i
5966                 LOOPNUM=$i
5967                 break
5968         done
5969 }
5970
5971 cleanup_54c() {
5972         local rc=0
5973         loopdev="$DIR/loop54c"
5974
5975         trap 0
5976         $UMOUNT $DIR/$tdir || rc=$?
5977         losetup -d $loopdev || true
5978         losetup -d $LOOPDEV || true
5979         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5980         return $rc
5981 }
5982
5983 test_54c() {
5984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5985
5986         loopdev="$DIR/loop54c"
5987
5988         find_loop_dev
5989         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5990         trap cleanup_54c EXIT
5991         mknod $loopdev b 7 $LOOPNUM
5992         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5993         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5994         losetup $loopdev $DIR/$tfile ||
5995                 error "can't set up $loopdev for $DIR/$tfile"
5996         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5997         test_mkdir $DIR/$tdir
5998         mount -t ext2 $loopdev $DIR/$tdir ||
5999                 error "error mounting $loopdev on $DIR/$tdir"
6000         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6001                 error "dd write"
6002         df $DIR/$tdir
6003         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6004                 error "dd read"
6005         cleanup_54c
6006 }
6007 run_test 54c "block device works in lustre ====================="
6008
6009 test_54d() {
6010         f="$DIR/f54d"
6011         string="aaaaaa"
6012         mknod $f p
6013         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
6014 }
6015 run_test 54d "fifo device works in lustre ======================"
6016
6017 test_54e() {
6018         f="$DIR/f54e"
6019         string="aaaaaa"
6020         cp -aL /dev/console $f
6021         echo $string > $f || error "echo $string to $f failed"
6022 }
6023 run_test 54e "console/tty device works in lustre ======================"
6024
6025 test_56a() {
6026         local numfiles=3
6027         local numdirs=2
6028         local dir=$DIR/$tdir
6029
6030         rm -rf $dir
6031         test_mkdir -p $dir/dir
6032         for i in $(seq $numfiles); do
6033                 touch $dir/file$i
6034                 touch $dir/dir/file$i
6035         done
6036
6037         local numcomp=$($LFS getstripe --component-count $dir)
6038
6039         [[ $numcomp == 0 ]] && numcomp=1
6040
6041         # test lfs getstripe with --recursive
6042         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6043
6044         [[ $filenum -eq $((numfiles * 2)) ]] ||
6045                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6046         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6047         [[ $filenum -eq $numfiles ]] ||
6048                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6049         echo "$LFS getstripe showed obdidx or l_ost_idx"
6050
6051         # test lfs getstripe with file instead of dir
6052         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6053         [[ $filenum -eq 1 ]] ||
6054                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6055         echo "$LFS getstripe file1 passed"
6056
6057         #test lfs getstripe with --verbose
6058         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6059         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6060                 error "$LFS getstripe --verbose $dir: "\
6061                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6062         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6063                 error "$LFS getstripe $dir: showed lmm_magic"
6064
6065         #test lfs getstripe with -v prints lmm_fid
6066         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6067         local countfids=$((numdirs + numfiles * numcomp))
6068         [[ $filenum -eq $countfids ]] ||
6069                 error "$LFS getstripe -v $dir: "\
6070                       "got $filenum want $countfids lmm_fid"
6071         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6072                 error "$LFS getstripe $dir: showed lmm_fid by default"
6073         echo "$LFS getstripe --verbose passed"
6074
6075         #check for FID information
6076         local fid1=$($LFS getstripe --fid $dir/file1)
6077         local fid2=$($LFS getstripe --verbose $dir/file1 |
6078                      awk '/lmm_fid: / { print $2; exit; }')
6079         local fid3=$($LFS path2fid $dir/file1)
6080
6081         [ "$fid1" != "$fid2" ] &&
6082                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6083         [ "$fid1" != "$fid3" ] &&
6084                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6085         echo "$LFS getstripe --fid passed"
6086
6087         #test lfs getstripe with --obd
6088         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6089                 error "$LFS getstripe --obd wrong_uuid: should return error"
6090
6091         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6092
6093         local ostidx=1
6094         local obduuid=$(ostuuid_from_index $ostidx)
6095         local found=$($LFS getstripe -r --obd $obduuid $dir |
6096                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6097
6098         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6099         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6100                 ((filenum--))
6101         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6102                 ((filenum--))
6103
6104         [[ $found -eq $filenum ]] ||
6105                 error "$LFS getstripe --obd: found $found expect $filenum"
6106         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6107                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6108                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6109                 error "$LFS getstripe --obd: should not show file on other obd"
6110         echo "$LFS getstripe --obd passed"
6111 }
6112 run_test 56a "check $LFS getstripe"
6113
6114 test_56b() {
6115         local dir=$DIR/$tdir
6116         local numdirs=3
6117
6118         test_mkdir $dir
6119         for i in $(seq $numdirs); do
6120                 test_mkdir $dir/dir$i
6121         done
6122
6123         # test lfs getdirstripe default mode is non-recursion, which is
6124         # different from lfs getstripe
6125         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6126
6127         [[ $dircnt -eq 1 ]] ||
6128                 error "$LFS getdirstripe: found $dircnt, not 1"
6129         dircnt=$($LFS getdirstripe --recursive $dir |
6130                 grep -c lmv_stripe_count)
6131         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6132                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6133 }
6134 run_test 56b "check $LFS getdirstripe"
6135
6136 test_56c() {
6137         remote_ost_nodsh && skip "remote OST with nodsh"
6138
6139         local ost_idx=0
6140         local ost_name=$(ostname_from_index $ost_idx)
6141         local old_status=$(ost_dev_status $ost_idx)
6142         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6143
6144         [[ -z "$old_status" ]] ||
6145                 skip_env "OST $ost_name is in $old_status status"
6146
6147         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6148         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6149                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6150         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6151                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6152                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6153         fi
6154
6155         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6156                 error "$LFS df -v showing inactive devices"
6157         sleep_maxage
6158
6159         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6160
6161         [[ "$new_status" =~ "D" ]] ||
6162                 error "$ost_name status is '$new_status', missing 'D'"
6163         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6164                 [[ "$new_status" =~ "N" ]] ||
6165                         error "$ost_name status is '$new_status', missing 'N'"
6166         fi
6167         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6168                 [[ "$new_status" =~ "f" ]] ||
6169                         error "$ost_name status is '$new_status', missing 'f'"
6170         fi
6171
6172         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6173         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6174                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6175         [[ -z "$p" ]] && restore_lustre_params < $p || true
6176         sleep_maxage
6177
6178         new_status=$(ost_dev_status $ost_idx)
6179         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6180                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6181         # can't check 'f' as devices may actually be on flash
6182 }
6183 run_test 56c "check 'lfs df' showing device status"
6184
6185 test_56d() {
6186         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6187         local osts=$($LFS df -v $MOUNT | grep -c OST)
6188
6189         $LFS df $MOUNT
6190
6191         (( mdts == MDSCOUNT )) ||
6192                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6193         (( osts == OSTCOUNT )) ||
6194                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6195 }
6196 run_test 56d "'lfs df -v' prints only configured devices"
6197
6198 test_56e() {
6199         err_enoent=2 # No such file or directory
6200         err_eopnotsupp=95 # Operation not supported
6201
6202         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6203         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6204
6205         # Check for handling of path not exists
6206         output=$($LFS df $enoent_mnt 2>&1)
6207         ret=$?
6208
6209         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6210         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6211                 error "expect failure $err_enoent, not $ret"
6212
6213         # Check for handling of non-Lustre FS
6214         output=$($LFS df $notsup_mnt)
6215         ret=$?
6216
6217         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6218         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6219                 error "expect success $err_eopnotsupp, not $ret"
6220
6221         # Check for multiple LustreFS argument
6222         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6223         ret=$?
6224
6225         [[ $output -eq 3 && $ret -eq 0 ]] ||
6226                 error "expect success 3, not $output, rc = $ret"
6227
6228         # Check for correct non-Lustre FS handling among multiple
6229         # LustreFS argument
6230         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6231                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6232         ret=$?
6233
6234         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6235                 error "expect success 2, not $output, rc = $ret"
6236 }
6237 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6238
6239 NUMFILES=3
6240 NUMDIRS=3
6241 setup_56() {
6242         local local_tdir="$1"
6243         local local_numfiles="$2"
6244         local local_numdirs="$3"
6245         local dir_params="$4"
6246         local dir_stripe_params="$5"
6247
6248         if [ ! -d "$local_tdir" ] ; then
6249                 test_mkdir -p $dir_stripe_params $local_tdir
6250                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6251                 for i in $(seq $local_numfiles) ; do
6252                         touch $local_tdir/file$i
6253                 done
6254                 for i in $(seq $local_numdirs) ; do
6255                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6256                         for j in $(seq $local_numfiles) ; do
6257                                 touch $local_tdir/dir$i/file$j
6258                         done
6259                 done
6260         fi
6261 }
6262
6263 setup_56_special() {
6264         local local_tdir=$1
6265         local local_numfiles=$2
6266         local local_numdirs=$3
6267
6268         setup_56 $local_tdir $local_numfiles $local_numdirs
6269
6270         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6271                 for i in $(seq $local_numfiles) ; do
6272                         mknod $local_tdir/loop${i}b b 7 $i
6273                         mknod $local_tdir/null${i}c c 1 3
6274                         ln -s $local_tdir/file1 $local_tdir/link${i}
6275                 done
6276                 for i in $(seq $local_numdirs) ; do
6277                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6278                         mknod $local_tdir/dir$i/null${i}c c 1 3
6279                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6280                 done
6281         fi
6282 }
6283
6284 test_56g() {
6285         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6286         local expected=$(($NUMDIRS + 2))
6287
6288         setup_56 $dir $NUMFILES $NUMDIRS
6289
6290         # test lfs find with -name
6291         for i in $(seq $NUMFILES) ; do
6292                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6293
6294                 [ $nums -eq $expected ] ||
6295                         error "lfs find -name '*$i' $dir wrong: "\
6296                               "found $nums, expected $expected"
6297         done
6298 }
6299 run_test 56g "check lfs find -name"
6300
6301 test_56h() {
6302         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6303         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6304
6305         setup_56 $dir $NUMFILES $NUMDIRS
6306
6307         # test lfs find with ! -name
6308         for i in $(seq $NUMFILES) ; do
6309                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6310
6311                 [ $nums -eq $expected ] ||
6312                         error "lfs find ! -name '*$i' $dir wrong: "\
6313                               "found $nums, expected $expected"
6314         done
6315 }
6316 run_test 56h "check lfs find ! -name"
6317
6318 test_56i() {
6319         local dir=$DIR/$tdir
6320
6321         test_mkdir $dir
6322
6323         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6324         local out=$($cmd)
6325
6326         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6327 }
6328 run_test 56i "check 'lfs find -ost UUID' skips directories"
6329
6330 test_56j() {
6331         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6332
6333         setup_56_special $dir $NUMFILES $NUMDIRS
6334
6335         local expected=$((NUMDIRS + 1))
6336         local cmd="$LFS find -type d $dir"
6337         local nums=$($cmd | wc -l)
6338
6339         [ $nums -eq $expected ] ||
6340                 error "'$cmd' wrong: found $nums, expected $expected"
6341 }
6342 run_test 56j "check lfs find -type d"
6343
6344 test_56k() {
6345         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6346
6347         setup_56_special $dir $NUMFILES $NUMDIRS
6348
6349         local expected=$(((NUMDIRS + 1) * NUMFILES))
6350         local cmd="$LFS find -type f $dir"
6351         local nums=$($cmd | wc -l)
6352
6353         [ $nums -eq $expected ] ||
6354                 error "'$cmd' wrong: found $nums, expected $expected"
6355 }
6356 run_test 56k "check lfs find -type f"
6357
6358 test_56l() {
6359         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6360
6361         setup_56_special $dir $NUMFILES $NUMDIRS
6362
6363         local expected=$((NUMDIRS + NUMFILES))
6364         local cmd="$LFS find -type b $dir"
6365         local nums=$($cmd | wc -l)
6366
6367         [ $nums -eq $expected ] ||
6368                 error "'$cmd' wrong: found $nums, expected $expected"
6369 }
6370 run_test 56l "check lfs find -type b"
6371
6372 test_56m() {
6373         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6374
6375         setup_56_special $dir $NUMFILES $NUMDIRS
6376
6377         local expected=$((NUMDIRS + NUMFILES))
6378         local cmd="$LFS find -type c $dir"
6379         local nums=$($cmd | wc -l)
6380         [ $nums -eq $expected ] ||
6381                 error "'$cmd' wrong: found $nums, expected $expected"
6382 }
6383 run_test 56m "check lfs find -type c"
6384
6385 test_56n() {
6386         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6387         setup_56_special $dir $NUMFILES $NUMDIRS
6388
6389         local expected=$((NUMDIRS + NUMFILES))
6390         local cmd="$LFS find -type l $dir"
6391         local nums=$($cmd | wc -l)
6392
6393         [ $nums -eq $expected ] ||
6394                 error "'$cmd' wrong: found $nums, expected $expected"
6395 }
6396 run_test 56n "check lfs find -type l"
6397
6398 test_56o() {
6399         local dir=$DIR/$tdir
6400
6401         setup_56 $dir $NUMFILES $NUMDIRS
6402         utime $dir/file1 > /dev/null || error "utime (1)"
6403         utime $dir/file2 > /dev/null || error "utime (2)"
6404         utime $dir/dir1 > /dev/null || error "utime (3)"
6405         utime $dir/dir2 > /dev/null || error "utime (4)"
6406         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6407         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6408
6409         local expected=4
6410         local nums=$($LFS find -mtime +0 $dir | wc -l)
6411
6412         [ $nums -eq $expected ] ||
6413                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6414
6415         expected=12
6416         cmd="$LFS find -mtime 0 $dir"
6417         nums=$($cmd | wc -l)
6418         [ $nums -eq $expected ] ||
6419                 error "'$cmd' wrong: found $nums, expected $expected"
6420 }
6421 run_test 56o "check lfs find -mtime for old files"
6422
6423 test_56ob() {
6424         local dir=$DIR/$tdir
6425         local expected=1
6426         local count=0
6427
6428         # just to make sure there is something that won't be found
6429         test_mkdir $dir
6430         touch $dir/$tfile.now
6431
6432         for age in year week day hour min; do
6433                 count=$((count + 1))
6434
6435                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6436                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6437                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6438
6439                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6440                 local nums=$($cmd | wc -l)
6441                 [ $nums -eq $expected ] ||
6442                         error "'$cmd' wrong: found $nums, expected $expected"
6443
6444                 cmd="$LFS find $dir -atime $count${age:0:1}"
6445                 nums=$($cmd | wc -l)
6446                 [ $nums -eq $expected ] ||
6447                         error "'$cmd' wrong: found $nums, expected $expected"
6448         done
6449
6450         sleep 2
6451         cmd="$LFS find $dir -ctime +1s -type f"
6452         nums=$($cmd | wc -l)
6453         (( $nums == $count * 2 + 1)) ||
6454                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6455 }
6456 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6457
6458 test_newerXY_base() {
6459         local x=$1
6460         local y=$2
6461         local dir=$DIR/$tdir
6462         local ref
6463         local negref
6464
6465         if [ $y == "t" ]; then
6466                 if [ $x == "b" ]; then
6467                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6468                 else
6469                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6470                 fi
6471         else
6472                 ref=$DIR/$tfile.newer.$x$y
6473                 touch $ref || error "touch $ref failed"
6474         fi
6475
6476         echo "before = $ref"
6477         sleep 2
6478         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6479         sleep 2
6480         if [ $y == "t" ]; then
6481                 if [ $x == "b" ]; then
6482                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6483                 else
6484                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6485                 fi
6486         else
6487                 negref=$DIR/$tfile.negnewer.$x$y
6488                 touch $negref || error "touch $negref failed"
6489         fi
6490
6491         echo "after = $negref"
6492         local cmd="$LFS find $dir -newer$x$y $ref"
6493         local nums=$(eval $cmd | wc -l)
6494         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6495
6496         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6497                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6498
6499         cmd="$LFS find $dir ! -newer$x$y $negref"
6500         nums=$(eval $cmd | wc -l)
6501         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6502                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6503
6504         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6505         nums=$(eval $cmd | wc -l)
6506         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6507                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6508
6509         rm -rf $DIR/*
6510 }
6511
6512 test_56oc() {
6513         test_newerXY_base "a" "a"
6514         test_newerXY_base "a" "m"
6515         test_newerXY_base "a" "c"
6516         test_newerXY_base "m" "a"
6517         test_newerXY_base "m" "m"
6518         test_newerXY_base "m" "c"
6519         test_newerXY_base "c" "a"
6520         test_newerXY_base "c" "m"
6521         test_newerXY_base "c" "c"
6522
6523         [[ -n "$sles_version" ]] &&
6524                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6525
6526         test_newerXY_base "a" "t"
6527         test_newerXY_base "m" "t"
6528         test_newerXY_base "c" "t"
6529
6530         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6531            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6532                 ! btime_supported && echo "btime unsupported" && return 0
6533
6534         test_newerXY_base "b" "b"
6535         test_newerXY_base "b" "t"
6536 }
6537 run_test 56oc "check lfs find -newerXY work"
6538
6539 btime_supported() {
6540         local dir=$DIR/$tdir
6541         local rc
6542
6543         mkdir -p $dir
6544         touch $dir/$tfile
6545         $LFS find $dir -btime -1d -type f
6546         rc=$?
6547         rm -rf $dir
6548         return $rc
6549 }
6550
6551 test_56od() {
6552         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6553                 ! btime_supported && skip "btime unsupported on MDS"
6554
6555         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6556                 ! btime_supported && skip "btime unsupported on clients"
6557
6558         local dir=$DIR/$tdir
6559         local ref=$DIR/$tfile.ref
6560         local negref=$DIR/$tfile.negref
6561
6562         mkdir $dir || error "mkdir $dir failed"
6563         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6564         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6565         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6566         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6567         touch $ref || error "touch $ref failed"
6568         # sleep 3 seconds at least
6569         sleep 3
6570
6571         local before=$(do_facet mds1 date +%s)
6572         local skew=$(($(date +%s) - before + 1))
6573
6574         if (( skew < 0 && skew > -5 )); then
6575                 sleep $((0 - skew + 1))
6576                 skew=0
6577         fi
6578
6579         # Set the dir stripe params to limit files all on MDT0,
6580         # otherwise we need to calc the max clock skew between
6581         # the client and MDTs.
6582         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6583         sleep 2
6584         touch $negref || error "touch $negref failed"
6585
6586         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6587         local nums=$($cmd | wc -l)
6588         local expected=$(((NUMFILES + 1) * NUMDIRS))
6589
6590         [ $nums -eq $expected ] ||
6591                 error "'$cmd' wrong: found $nums, expected $expected"
6592
6593         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6594         nums=$($cmd | wc -l)
6595         expected=$((NUMFILES + 1))
6596         [ $nums -eq $expected ] ||
6597                 error "'$cmd' wrong: found $nums, expected $expected"
6598
6599         [ $skew -lt 0 ] && return
6600
6601         local after=$(do_facet mds1 date +%s)
6602         local age=$((after - before + 1 + skew))
6603
6604         cmd="$LFS find $dir -btime -${age}s -type f"
6605         nums=$($cmd | wc -l)
6606         expected=$(((NUMFILES + 1) * NUMDIRS))
6607
6608         echo "Clock skew between client and server: $skew, age:$age"
6609         [ $nums -eq $expected ] ||
6610                 error "'$cmd' wrong: found $nums, expected $expected"
6611
6612         expected=$(($NUMDIRS + 1))
6613         cmd="$LFS find $dir -btime -${age}s -type d"
6614         nums=$($cmd | wc -l)
6615         [ $nums -eq $expected ] ||
6616                 error "'$cmd' wrong: found $nums, expected $expected"
6617         rm -f $ref $negref || error "Failed to remove $ref $negref"
6618 }
6619 run_test 56od "check lfs find -btime with units"
6620
6621 test_56p() {
6622         [ $RUNAS_ID -eq $UID ] &&
6623                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6624
6625         local dir=$DIR/$tdir
6626
6627         setup_56 $dir $NUMFILES $NUMDIRS
6628         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6629
6630         local expected=$NUMFILES
6631         local cmd="$LFS find -uid $RUNAS_ID $dir"
6632         local nums=$($cmd | wc -l)
6633
6634         [ $nums -eq $expected ] ||
6635                 error "'$cmd' wrong: found $nums, expected $expected"
6636
6637         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6638         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6639         nums=$($cmd | wc -l)
6640         [ $nums -eq $expected ] ||
6641                 error "'$cmd' wrong: found $nums, expected $expected"
6642 }
6643 run_test 56p "check lfs find -uid and ! -uid"
6644
6645 test_56q() {
6646         [ $RUNAS_ID -eq $UID ] &&
6647                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6648
6649         local dir=$DIR/$tdir
6650
6651         setup_56 $dir $NUMFILES $NUMDIRS
6652         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6653
6654         local expected=$NUMFILES
6655         local cmd="$LFS find -gid $RUNAS_GID $dir"
6656         local nums=$($cmd | wc -l)
6657
6658         [ $nums -eq $expected ] ||
6659                 error "'$cmd' wrong: found $nums, expected $expected"
6660
6661         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6662         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6663         nums=$($cmd | wc -l)
6664         [ $nums -eq $expected ] ||
6665                 error "'$cmd' wrong: found $nums, expected $expected"
6666 }
6667 run_test 56q "check lfs find -gid and ! -gid"
6668
6669 test_56r() {
6670         local dir=$DIR/$tdir
6671
6672         setup_56 $dir $NUMFILES $NUMDIRS
6673
6674         local expected=12
6675         local cmd="$LFS find -size 0 -type f -lazy $dir"
6676         local nums=$($cmd | wc -l)
6677
6678         [ $nums -eq $expected ] ||
6679                 error "'$cmd' wrong: found $nums, expected $expected"
6680         cmd="$LFS find -size 0 -type f $dir"
6681         nums=$($cmd | wc -l)
6682         [ $nums -eq $expected ] ||
6683                 error "'$cmd' wrong: found $nums, expected $expected"
6684
6685         expected=0
6686         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6687         nums=$($cmd | wc -l)
6688         [ $nums -eq $expected ] ||
6689                 error "'$cmd' wrong: found $nums, expected $expected"
6690         cmd="$LFS find ! -size 0 -type f $dir"
6691         nums=$($cmd | wc -l)
6692         [ $nums -eq $expected ] ||
6693                 error "'$cmd' wrong: found $nums, expected $expected"
6694
6695         echo "test" > $dir/$tfile
6696         echo "test2" > $dir/$tfile.2 && sync
6697         expected=1
6698         cmd="$LFS find -size 5 -type f -lazy $dir"
6699         nums=$($cmd | wc -l)
6700         [ $nums -eq $expected ] ||
6701                 error "'$cmd' wrong: found $nums, expected $expected"
6702         cmd="$LFS find -size 5 -type f $dir"
6703         nums=$($cmd | wc -l)
6704         [ $nums -eq $expected ] ||
6705                 error "'$cmd' wrong: found $nums, expected $expected"
6706
6707         expected=1
6708         cmd="$LFS find -size +5 -type f -lazy $dir"
6709         nums=$($cmd | wc -l)
6710         [ $nums -eq $expected ] ||
6711                 error "'$cmd' wrong: found $nums, expected $expected"
6712         cmd="$LFS find -size +5 -type f $dir"
6713         nums=$($cmd | wc -l)
6714         [ $nums -eq $expected ] ||
6715                 error "'$cmd' wrong: found $nums, expected $expected"
6716
6717         expected=2
6718         cmd="$LFS find -size +0 -type f -lazy $dir"
6719         nums=$($cmd | wc -l)
6720         [ $nums -eq $expected ] ||
6721                 error "'$cmd' wrong: found $nums, expected $expected"
6722         cmd="$LFS find -size +0 -type f $dir"
6723         nums=$($cmd | wc -l)
6724         [ $nums -eq $expected ] ||
6725                 error "'$cmd' wrong: found $nums, expected $expected"
6726
6727         expected=2
6728         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6729         nums=$($cmd | wc -l)
6730         [ $nums -eq $expected ] ||
6731                 error "'$cmd' wrong: found $nums, expected $expected"
6732         cmd="$LFS find ! -size -5 -type f $dir"
6733         nums=$($cmd | wc -l)
6734         [ $nums -eq $expected ] ||
6735                 error "'$cmd' wrong: found $nums, expected $expected"
6736
6737         expected=12
6738         cmd="$LFS find -size -5 -type f -lazy $dir"
6739         nums=$($cmd | wc -l)
6740         [ $nums -eq $expected ] ||
6741                 error "'$cmd' wrong: found $nums, expected $expected"
6742         cmd="$LFS find -size -5 -type f $dir"
6743         nums=$($cmd | wc -l)
6744         [ $nums -eq $expected ] ||
6745                 error "'$cmd' wrong: found $nums, expected $expected"
6746 }
6747 run_test 56r "check lfs find -size works"
6748
6749 test_56ra_sub() {
6750         local expected=$1
6751         local glimpses=$2
6752         local cmd="$3"
6753
6754         cancel_lru_locks $OSC
6755
6756         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6757         local nums=$($cmd | wc -l)
6758
6759         [ $nums -eq $expected ] ||
6760                 error "'$cmd' wrong: found $nums, expected $expected"
6761
6762         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6763
6764         if (( rpcs_before + glimpses != rpcs_after )); then
6765                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6766                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6767
6768                 if [[ $glimpses == 0 ]]; then
6769                         error "'$cmd' should not send glimpse RPCs to OST"
6770                 else
6771                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6772                 fi
6773         fi
6774 }
6775
6776 test_56ra() {
6777         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6778                 skip "MDS < 2.12.58 doesn't return LSOM data"
6779         local dir=$DIR/$tdir
6780         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6781
6782         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6783
6784         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6785         $LCTL set_param -n llite.*.statahead_agl=0
6786         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6787
6788         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6789         # open and close all files to ensure LSOM is updated
6790         cancel_lru_locks $OSC
6791         find $dir -type f | xargs cat > /dev/null
6792
6793         #   expect_found  glimpse_rpcs  command_to_run
6794         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6795         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6796         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6797         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6798
6799         echo "test" > $dir/$tfile
6800         echo "test2" > $dir/$tfile.2 && sync
6801         cancel_lru_locks $OSC
6802         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6803
6804         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6805         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6806         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6807         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6808
6809         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6810         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6811         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6812         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6813         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6814         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6815 }
6816 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6817
6818 test_56rb() {
6819         local dir=$DIR/$tdir
6820         local tmp=$TMP/$tfile.log
6821         local mdt_idx;
6822
6823         test_mkdir -p $dir || error "failed to mkdir $dir"
6824         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6825                 error "failed to setstripe $dir/$tfile"
6826         mdt_idx=$($LFS getdirstripe -i $dir)
6827         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6828
6829         stack_trap "rm -f $tmp" EXIT
6830         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6831         ! grep -q obd_uuid $tmp ||
6832                 error "failed to find --size +100K --ost 0 $dir"
6833         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6834         ! grep -q obd_uuid $tmp ||
6835                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6836 }
6837 run_test 56rb "check lfs find --size --ost/--mdt works"
6838
6839 test_56rc() {
6840         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6841         local dir=$DIR/$tdir
6842         local found
6843
6844         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6845         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6846         (( $MDSCOUNT > 2 )) &&
6847                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6848         mkdir $dir/$tdir-{1..10}
6849         touch $dir/$tfile-{1..10}
6850
6851         found=$($LFS find $dir --mdt-count 2 | wc -l)
6852         expect=11
6853         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6854
6855         found=$($LFS find $dir -T +1 | wc -l)
6856         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6857         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6858
6859         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6860         expect=11
6861         (( $found == $expect )) || error "found $found all_char, expect $expect"
6862
6863         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6864         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6865         (( $found == $expect )) || error "found $found all_char, expect $expect"
6866 }
6867 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6868
6869 test_56s() { # LU-611 #LU-9369
6870         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6871
6872         local dir=$DIR/$tdir
6873         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6874
6875         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6876         for i in $(seq $NUMDIRS); do
6877                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6878         done
6879
6880         local expected=$NUMDIRS
6881         local cmd="$LFS find -c $OSTCOUNT $dir"
6882         local nums=$($cmd | wc -l)
6883
6884         [ $nums -eq $expected ] || {
6885                 $LFS getstripe -R $dir
6886                 error "'$cmd' wrong: found $nums, expected $expected"
6887         }
6888
6889         expected=$((NUMDIRS + onestripe))
6890         cmd="$LFS find -stripe-count +0 -type f $dir"
6891         nums=$($cmd | wc -l)
6892         [ $nums -eq $expected ] || {
6893                 $LFS getstripe -R $dir
6894                 error "'$cmd' wrong: found $nums, expected $expected"
6895         }
6896
6897         expected=$onestripe
6898         cmd="$LFS find -stripe-count 1 -type f $dir"
6899         nums=$($cmd | wc -l)
6900         [ $nums -eq $expected ] || {
6901                 $LFS getstripe -R $dir
6902                 error "'$cmd' wrong: found $nums, expected $expected"
6903         }
6904
6905         cmd="$LFS find -stripe-count -2 -type f $dir"
6906         nums=$($cmd | wc -l)
6907         [ $nums -eq $expected ] || {
6908                 $LFS getstripe -R $dir
6909                 error "'$cmd' wrong: found $nums, expected $expected"
6910         }
6911
6912         expected=0
6913         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6914         nums=$($cmd | wc -l)
6915         [ $nums -eq $expected ] || {
6916                 $LFS getstripe -R $dir
6917                 error "'$cmd' wrong: found $nums, expected $expected"
6918         }
6919 }
6920 run_test 56s "check lfs find -stripe-count works"
6921
6922 test_56t() { # LU-611 #LU-9369
6923         local dir=$DIR/$tdir
6924
6925         setup_56 $dir 0 $NUMDIRS
6926         for i in $(seq $NUMDIRS); do
6927                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6928         done
6929
6930         local expected=$NUMDIRS
6931         local cmd="$LFS find -S 8M $dir"
6932         local nums=$($cmd | wc -l)
6933
6934         [ $nums -eq $expected ] || {
6935                 $LFS getstripe -R $dir
6936                 error "'$cmd' wrong: found $nums, expected $expected"
6937         }
6938         rm -rf $dir
6939
6940         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6941
6942         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6943
6944         expected=$(((NUMDIRS + 1) * NUMFILES))
6945         cmd="$LFS find -stripe-size 512k -type f $dir"
6946         nums=$($cmd | wc -l)
6947         [ $nums -eq $expected ] ||
6948                 error "'$cmd' wrong: found $nums, expected $expected"
6949
6950         cmd="$LFS find -stripe-size +320k -type f $dir"
6951         nums=$($cmd | wc -l)
6952         [ $nums -eq $expected ] ||
6953                 error "'$cmd' wrong: found $nums, expected $expected"
6954
6955         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6956         cmd="$LFS find -stripe-size +200k -type f $dir"
6957         nums=$($cmd | wc -l)
6958         [ $nums -eq $expected ] ||
6959                 error "'$cmd' wrong: found $nums, expected $expected"
6960
6961         cmd="$LFS find -stripe-size -640k -type f $dir"
6962         nums=$($cmd | wc -l)
6963         [ $nums -eq $expected ] ||
6964                 error "'$cmd' wrong: found $nums, expected $expected"
6965
6966         expected=4
6967         cmd="$LFS find -stripe-size 256k -type f $dir"
6968         nums=$($cmd | wc -l)
6969         [ $nums -eq $expected ] ||
6970                 error "'$cmd' wrong: found $nums, expected $expected"
6971
6972         cmd="$LFS find -stripe-size -320k -type f $dir"
6973         nums=$($cmd | wc -l)
6974         [ $nums -eq $expected ] ||
6975                 error "'$cmd' wrong: found $nums, expected $expected"
6976
6977         expected=0
6978         cmd="$LFS find -stripe-size 1024k -type f $dir"
6979         nums=$($cmd | wc -l)
6980         [ $nums -eq $expected ] ||
6981                 error "'$cmd' wrong: found $nums, expected $expected"
6982 }
6983 run_test 56t "check lfs find -stripe-size works"
6984
6985 test_56u() { # LU-611
6986         local dir=$DIR/$tdir
6987
6988         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6989
6990         if [[ $OSTCOUNT -gt 1 ]]; then
6991                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6992                 onestripe=4
6993         else
6994                 onestripe=0
6995         fi
6996
6997         local expected=$(((NUMDIRS + 1) * NUMFILES))
6998         local cmd="$LFS find -stripe-index 0 -type f $dir"
6999         local nums=$($cmd | wc -l)
7000
7001         [ $nums -eq $expected ] ||
7002                 error "'$cmd' wrong: found $nums, expected $expected"
7003
7004         expected=$onestripe
7005         cmd="$LFS find -stripe-index 1 -type f $dir"
7006         nums=$($cmd | wc -l)
7007         [ $nums -eq $expected ] ||
7008                 error "'$cmd' wrong: found $nums, expected $expected"
7009
7010         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7011         nums=$($cmd | wc -l)
7012         [ $nums -eq $expected ] ||
7013                 error "'$cmd' wrong: found $nums, expected $expected"
7014
7015         expected=0
7016         # This should produce an error and not return any files
7017         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7018         nums=$($cmd 2>/dev/null | wc -l)
7019         [ $nums -eq $expected ] ||
7020                 error "'$cmd' wrong: found $nums, expected $expected"
7021
7022         if [[ $OSTCOUNT -gt 1 ]]; then
7023                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7024                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7025                 nums=$($cmd | wc -l)
7026                 [ $nums -eq $expected ] ||
7027                         error "'$cmd' wrong: found $nums, expected $expected"
7028         fi
7029 }
7030 run_test 56u "check lfs find -stripe-index works"
7031
7032 test_56v() {
7033         local mdt_idx=0
7034         local dir=$DIR/$tdir
7035
7036         setup_56 $dir $NUMFILES $NUMDIRS
7037
7038         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7039         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7040
7041         for file in $($LFS find -m $UUID $dir); do
7042                 file_midx=$($LFS getstripe -m $file)
7043                 [ $file_midx -eq $mdt_idx ] ||
7044                         error "lfs find -m $UUID != getstripe -m $file_midx"
7045         done
7046 }
7047 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7048
7049 test_56w() {
7050         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7052
7053         local dir=$DIR/$tdir
7054
7055         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7056
7057         local stripe_size=$($LFS getstripe -S -d $dir) ||
7058                 error "$LFS getstripe -S -d $dir failed"
7059         stripe_size=${stripe_size%% *}
7060
7061         local file_size=$((stripe_size * OSTCOUNT))
7062         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7063         local required_space=$((file_num * file_size))
7064         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7065                            head -n1)
7066         [[ $free_space -le $((required_space / 1024)) ]] &&
7067                 skip_env "need $required_space, have $free_space kbytes"
7068
7069         local dd_bs=65536
7070         local dd_count=$((file_size / dd_bs))
7071
7072         # write data into the files
7073         local i
7074         local j
7075         local file
7076
7077         for i in $(seq $NUMFILES); do
7078                 file=$dir/file$i
7079                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7080                         error "write data into $file failed"
7081         done
7082         for i in $(seq $NUMDIRS); do
7083                 for j in $(seq $NUMFILES); do
7084                         file=$dir/dir$i/file$j
7085                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7086                                 error "write data into $file failed"
7087                 done
7088         done
7089
7090         # $LFS_MIGRATE will fail if hard link migration is unsupported
7091         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7092                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7093                         error "creating links to $dir/dir1/file1 failed"
7094         fi
7095
7096         local expected=-1
7097
7098         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7099
7100         # lfs_migrate file
7101         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7102
7103         echo "$cmd"
7104         eval $cmd || error "$cmd failed"
7105
7106         check_stripe_count $dir/file1 $expected
7107
7108         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7109         then
7110                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7111                 # OST 1 if it is on OST 0. This file is small enough to
7112                 # be on only one stripe.
7113                 file=$dir/migr_1_ost
7114                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7115                         error "write data into $file failed"
7116                 local obdidx=$($LFS getstripe -i $file)
7117                 local oldmd5=$(md5sum $file)
7118                 local newobdidx=0
7119
7120                 [[ $obdidx -eq 0 ]] && newobdidx=1
7121                 cmd="$LFS migrate -i $newobdidx $file"
7122                 echo $cmd
7123                 eval $cmd || error "$cmd failed"
7124
7125                 local realobdix=$($LFS getstripe -i $file)
7126                 local newmd5=$(md5sum $file)
7127
7128                 [[ $newobdidx -ne $realobdix ]] &&
7129                         error "new OST is different (was=$obdidx, "\
7130                               "wanted=$newobdidx, got=$realobdix)"
7131                 [[ "$oldmd5" != "$newmd5" ]] &&
7132                         error "md5sum differ: $oldmd5, $newmd5"
7133         fi
7134
7135         # lfs_migrate dir
7136         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7137         echo "$cmd"
7138         eval $cmd || error "$cmd failed"
7139
7140         for j in $(seq $NUMFILES); do
7141                 check_stripe_count $dir/dir1/file$j $expected
7142         done
7143
7144         # lfs_migrate works with lfs find
7145         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7146              $LFS_MIGRATE -y -c $expected"
7147         echo "$cmd"
7148         eval $cmd || error "$cmd failed"
7149
7150         for i in $(seq 2 $NUMFILES); do
7151                 check_stripe_count $dir/file$i $expected
7152         done
7153         for i in $(seq 2 $NUMDIRS); do
7154                 for j in $(seq $NUMFILES); do
7155                 check_stripe_count $dir/dir$i/file$j $expected
7156                 done
7157         done
7158 }
7159 run_test 56w "check lfs_migrate -c stripe_count works"
7160
7161 test_56wb() {
7162         local file1=$DIR/$tdir/file1
7163         local create_pool=false
7164         local initial_pool=$($LFS getstripe -p $DIR)
7165         local pool_list=()
7166         local pool=""
7167
7168         echo -n "Creating test dir..."
7169         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7170         echo "done."
7171
7172         echo -n "Creating test file..."
7173         touch $file1 || error "cannot create file"
7174         echo "done."
7175
7176         echo -n "Detecting existing pools..."
7177         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7178
7179         if [ ${#pool_list[@]} -gt 0 ]; then
7180                 echo "${pool_list[@]}"
7181                 for thispool in "${pool_list[@]}"; do
7182                         if [[ -z "$initial_pool" ||
7183                               "$initial_pool" != "$thispool" ]]; then
7184                                 pool="$thispool"
7185                                 echo "Using existing pool '$pool'"
7186                                 break
7187                         fi
7188                 done
7189         else
7190                 echo "none detected."
7191         fi
7192         if [ -z "$pool" ]; then
7193                 pool=${POOL:-testpool}
7194                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7195                 echo -n "Creating pool '$pool'..."
7196                 create_pool=true
7197                 pool_add $pool &> /dev/null ||
7198                         error "pool_add failed"
7199                 echo "done."
7200
7201                 echo -n "Adding target to pool..."
7202                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7203                         error "pool_add_targets failed"
7204                 echo "done."
7205         fi
7206
7207         echo -n "Setting pool using -p option..."
7208         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7209                 error "migrate failed rc = $?"
7210         echo "done."
7211
7212         echo -n "Verifying test file is in pool after migrating..."
7213         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7214                 error "file was not migrated to pool $pool"
7215         echo "done."
7216
7217         echo -n "Removing test file from pool '$pool'..."
7218         # "lfs migrate $file" won't remove the file from the pool
7219         # until some striping information is changed.
7220         $LFS migrate -c 1 $file1 &> /dev/null ||
7221                 error "cannot remove from pool"
7222         [ "$($LFS getstripe -p $file1)" ] &&
7223                 error "pool still set"
7224         echo "done."
7225
7226         echo -n "Setting pool using --pool option..."
7227         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7228                 error "migrate failed rc = $?"
7229         echo "done."
7230
7231         # Clean up
7232         rm -f $file1
7233         if $create_pool; then
7234                 destroy_test_pools 2> /dev/null ||
7235                         error "destroy test pools failed"
7236         fi
7237 }
7238 run_test 56wb "check lfs_migrate pool support"
7239
7240 test_56wc() {
7241         local file1="$DIR/$tdir/file1"
7242         local parent_ssize
7243         local parent_scount
7244         local cur_ssize
7245         local cur_scount
7246         local orig_ssize
7247
7248         echo -n "Creating test dir..."
7249         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7250         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7251                 error "cannot set stripe by '-S 1M -c 1'"
7252         echo "done"
7253
7254         echo -n "Setting initial stripe for test file..."
7255         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7256                 error "cannot set stripe"
7257         cur_ssize=$($LFS getstripe -S "$file1")
7258         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7259         echo "done."
7260
7261         # File currently set to -S 512K -c 1
7262
7263         # Ensure -c and -S options are rejected when -R is set
7264         echo -n "Verifying incompatible options are detected..."
7265         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7266                 error "incompatible -c and -R options not detected"
7267         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7268                 error "incompatible -S and -R options not detected"
7269         echo "done."
7270
7271         # Ensure unrecognized options are passed through to 'lfs migrate'
7272         echo -n "Verifying -S option is passed through to lfs migrate..."
7273         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7274                 error "migration failed"
7275         cur_ssize=$($LFS getstripe -S "$file1")
7276         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7277         echo "done."
7278
7279         # File currently set to -S 1M -c 1
7280
7281         # Ensure long options are supported
7282         echo -n "Verifying long options supported..."
7283         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7284                 error "long option without argument not supported"
7285         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7286                 error "long option with argument not supported"
7287         cur_ssize=$($LFS getstripe -S "$file1")
7288         [ $cur_ssize -eq 524288 ] ||
7289                 error "migrate --stripe-size $cur_ssize != 524288"
7290         echo "done."
7291
7292         # File currently set to -S 512K -c 1
7293
7294         if [ "$OSTCOUNT" -gt 1 ]; then
7295                 echo -n "Verifying explicit stripe count can be set..."
7296                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7297                         error "migrate failed"
7298                 cur_scount=$($LFS getstripe -c "$file1")
7299                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7300                 echo "done."
7301         fi
7302
7303         # File currently set to -S 512K -c 1 or -S 512K -c 2
7304
7305         # Ensure parent striping is used if -R is set, and no stripe
7306         # count or size is specified
7307         echo -n "Setting stripe for parent directory..."
7308         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7309                 error "cannot set stripe '-S 2M -c 1'"
7310         echo "done."
7311
7312         echo -n "Verifying restripe option uses parent stripe settings..."
7313         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7314         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7315         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7316                 error "migrate failed"
7317         cur_ssize=$($LFS getstripe -S "$file1")
7318         [ $cur_ssize -eq $parent_ssize ] ||
7319                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7320         cur_scount=$($LFS getstripe -c "$file1")
7321         [ $cur_scount -eq $parent_scount ] ||
7322                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7323         echo "done."
7324
7325         # File currently set to -S 1M -c 1
7326
7327         # Ensure striping is preserved if -R is not set, and no stripe
7328         # count or size is specified
7329         echo -n "Verifying striping size preserved when not specified..."
7330         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7331         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7332                 error "cannot set stripe on parent directory"
7333         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7334                 error "migrate failed"
7335         cur_ssize=$($LFS getstripe -S "$file1")
7336         [ $cur_ssize -eq $orig_ssize ] ||
7337                 error "migrate by default $cur_ssize != $orig_ssize"
7338         echo "done."
7339
7340         # Ensure file name properly detected when final option has no argument
7341         echo -n "Verifying file name properly detected..."
7342         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7343                 error "file name interpreted as option argument"
7344         echo "done."
7345
7346         # Clean up
7347         rm -f "$file1"
7348 }
7349 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7350
7351 test_56wd() {
7352         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7353
7354         local file1=$DIR/$tdir/file1
7355
7356         echo -n "Creating test dir..."
7357         test_mkdir $DIR/$tdir || error "cannot create dir"
7358         echo "done."
7359
7360         echo -n "Creating test file..."
7361         touch $file1
7362         echo "done."
7363
7364         # Ensure 'lfs migrate' will fail by using a non-existent option,
7365         # and make sure rsync is not called to recover
7366         echo -n "Make sure --no-rsync option works..."
7367         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7368                 grep -q 'refusing to fall back to rsync' ||
7369                 error "rsync was called with --no-rsync set"
7370         echo "done."
7371
7372         # Ensure rsync is called without trying 'lfs migrate' first
7373         echo -n "Make sure --rsync option works..."
7374         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7375                 grep -q 'falling back to rsync' &&
7376                 error "lfs migrate was called with --rsync set"
7377         echo "done."
7378
7379         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7380         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7381                 grep -q 'at the same time' ||
7382                 error "--rsync and --no-rsync accepted concurrently"
7383         echo "done."
7384
7385         # Clean up
7386         rm -f $file1
7387 }
7388 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7389
7390 test_56we() {
7391         local td=$DIR/$tdir
7392         local tf=$td/$tfile
7393
7394         test_mkdir $td || error "cannot create $td"
7395         touch $tf || error "cannot touch $tf"
7396
7397         echo -n "Make sure --non-direct|-D works..."
7398         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7399                 grep -q "lfs migrate --non-direct" ||
7400                 error "--non-direct option cannot work correctly"
7401         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7402                 grep -q "lfs migrate -D" ||
7403                 error "-D option cannot work correctly"
7404         echo "done."
7405 }
7406 run_test 56we "check lfs_migrate --non-direct|-D support"
7407
7408 test_56x() {
7409         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7410         check_swap_layouts_support
7411
7412         local dir=$DIR/$tdir
7413         local ref1=/etc/passwd
7414         local file1=$dir/file1
7415
7416         test_mkdir $dir || error "creating dir $dir"
7417         $LFS setstripe -c 2 $file1
7418         cp $ref1 $file1
7419         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7420         stripe=$($LFS getstripe -c $file1)
7421         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7422         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7423
7424         # clean up
7425         rm -f $file1
7426 }
7427 run_test 56x "lfs migration support"
7428
7429 test_56xa() {
7430         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7431         check_swap_layouts_support
7432
7433         local dir=$DIR/$tdir/$testnum
7434
7435         test_mkdir -p $dir
7436
7437         local ref1=/etc/passwd
7438         local file1=$dir/file1
7439
7440         $LFS setstripe -c 2 $file1
7441         cp $ref1 $file1
7442         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7443
7444         local stripe=$($LFS getstripe -c $file1)
7445
7446         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7447         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7448
7449         # clean up
7450         rm -f $file1
7451 }
7452 run_test 56xa "lfs migration --block support"
7453
7454 check_migrate_links() {
7455         local dir="$1"
7456         local file1="$dir/file1"
7457         local begin="$2"
7458         local count="$3"
7459         local runas="$4"
7460         local total_count=$(($begin + $count - 1))
7461         local symlink_count=10
7462         local uniq_count=10
7463
7464         if [ ! -f "$file1" ]; then
7465                 echo -n "creating initial file..."
7466                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7467                         error "cannot setstripe initial file"
7468                 echo "done"
7469
7470                 echo -n "creating symlinks..."
7471                 for s in $(seq 1 $symlink_count); do
7472                         ln -s "$file1" "$dir/slink$s" ||
7473                                 error "cannot create symlinks"
7474                 done
7475                 echo "done"
7476
7477                 echo -n "creating nonlinked files..."
7478                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7479                         error "cannot create nonlinked files"
7480                 echo "done"
7481         fi
7482
7483         # create hard links
7484         if [ ! -f "$dir/file$total_count" ]; then
7485                 echo -n "creating hard links $begin:$total_count..."
7486                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7487                         /dev/null || error "cannot create hard links"
7488                 echo "done"
7489         fi
7490
7491         echo -n "checking number of hard links listed in xattrs..."
7492         local fid=$($LFS getstripe -F "$file1")
7493         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7494
7495         echo "${#paths[*]}"
7496         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7497                         skip "hard link list has unexpected size, skipping test"
7498         fi
7499         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7500                         error "link names should exceed xattrs size"
7501         fi
7502
7503         echo -n "migrating files..."
7504         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7505         local rc=$?
7506         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7507         echo "done"
7508
7509         # make sure all links have been properly migrated
7510         echo -n "verifying files..."
7511         fid=$($LFS getstripe -F "$file1") ||
7512                 error "cannot get fid for file $file1"
7513         for i in $(seq 2 $total_count); do
7514                 local fid2=$($LFS getstripe -F $dir/file$i)
7515
7516                 [ "$fid2" == "$fid" ] ||
7517                         error "migrated hard link has mismatched FID"
7518         done
7519
7520         # make sure hard links were properly detected, and migration was
7521         # performed only once for the entire link set; nonlinked files should
7522         # also be migrated
7523         local actual=$(grep -c 'done' <<< "$migrate_out")
7524         local expected=$(($uniq_count + 1))
7525
7526         [ "$actual" -eq  "$expected" ] ||
7527                 error "hard links individually migrated ($actual != $expected)"
7528
7529         # make sure the correct number of hard links are present
7530         local hardlinks=$(stat -c '%h' "$file1")
7531
7532         [ $hardlinks -eq $total_count ] ||
7533                 error "num hard links $hardlinks != $total_count"
7534         echo "done"
7535
7536         return 0
7537 }
7538
7539 test_56xb() {
7540         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7541                 skip "Need MDS version at least 2.10.55"
7542
7543         local dir="$DIR/$tdir"
7544
7545         test_mkdir "$dir" || error "cannot create dir $dir"
7546
7547         echo "testing lfs migrate mode when all links fit within xattrs"
7548         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7549
7550         echo "testing rsync mode when all links fit within xattrs"
7551         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7552
7553         echo "testing lfs migrate mode when all links do not fit within xattrs"
7554         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7555
7556         echo "testing rsync mode when all links do not fit within xattrs"
7557         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7558
7559         chown -R $RUNAS_ID $dir
7560         echo "testing non-root lfs migrate mode when not all links are in xattr"
7561         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7562
7563         # clean up
7564         rm -rf $dir
7565 }
7566 run_test 56xb "lfs migration hard link support"
7567
7568 test_56xc() {
7569         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7570
7571         local dir="$DIR/$tdir"
7572
7573         test_mkdir "$dir" || error "cannot create dir $dir"
7574
7575         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7576         echo -n "Setting initial stripe for 20MB test file..."
7577         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7578                 error "cannot setstripe 20MB file"
7579         echo "done"
7580         echo -n "Sizing 20MB test file..."
7581         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7582         echo "done"
7583         echo -n "Verifying small file autostripe count is 1..."
7584         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7585                 error "cannot migrate 20MB file"
7586         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7587                 error "cannot get stripe for $dir/20mb"
7588         [ $stripe_count -eq 1 ] ||
7589                 error "unexpected stripe count $stripe_count for 20MB file"
7590         rm -f "$dir/20mb"
7591         echo "done"
7592
7593         # Test 2: File is small enough to fit within the available space on
7594         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7595         # have at least an additional 1KB for each desired stripe for test 3
7596         echo -n "Setting stripe for 1GB test file..."
7597         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7598         echo "done"
7599         echo -n "Sizing 1GB test file..."
7600         # File size is 1GB + 3KB
7601         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7602         echo "done"
7603
7604         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7605         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7606         if (( avail > 524288 * OSTCOUNT )); then
7607                 echo -n "Migrating 1GB file..."
7608                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7609                         error "cannot migrate 1GB file"
7610                 echo "done"
7611                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7612                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7613                         error "cannot getstripe for 1GB file"
7614                 [ $stripe_count -eq 2 ] ||
7615                         error "unexpected stripe count $stripe_count != 2"
7616                 echo "done"
7617         fi
7618
7619         # Test 3: File is too large to fit within the available space on
7620         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7621         if [ $OSTCOUNT -ge 3 ]; then
7622                 # The required available space is calculated as
7623                 # file size (1GB + 3KB) / OST count (3).
7624                 local kb_per_ost=349526
7625
7626                 echo -n "Migrating 1GB file with limit..."
7627                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7628                         error "cannot migrate 1GB file with limit"
7629                 echo "done"
7630
7631                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7632                 echo -n "Verifying 1GB autostripe count with limited space..."
7633                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7634                         error "unexpected stripe count $stripe_count (min 3)"
7635                 echo "done"
7636         fi
7637
7638         # clean up
7639         rm -rf $dir
7640 }
7641 run_test 56xc "lfs migration autostripe"
7642
7643 test_56xd() {
7644         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7645
7646         local dir=$DIR/$tdir
7647         local f_mgrt=$dir/$tfile.mgrt
7648         local f_yaml=$dir/$tfile.yaml
7649         local f_copy=$dir/$tfile.copy
7650         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7651         local layout_copy="-c 2 -S 2M -i 1"
7652         local yamlfile=$dir/yamlfile
7653         local layout_before;
7654         local layout_after;
7655
7656         test_mkdir "$dir" || error "cannot create dir $dir"
7657         $LFS setstripe $layout_yaml $f_yaml ||
7658                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7659         $LFS getstripe --yaml $f_yaml > $yamlfile
7660         $LFS setstripe $layout_copy $f_copy ||
7661                 error "cannot setstripe $f_copy with layout $layout_copy"
7662         touch $f_mgrt
7663         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7664
7665         # 1. test option --yaml
7666         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7667                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7668         layout_before=$(get_layout_param $f_yaml)
7669         layout_after=$(get_layout_param $f_mgrt)
7670         [ "$layout_after" == "$layout_before" ] ||
7671                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7672
7673         # 2. test option --copy
7674         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7675                 error "cannot migrate $f_mgrt with --copy $f_copy"
7676         layout_before=$(get_layout_param $f_copy)
7677         layout_after=$(get_layout_param $f_mgrt)
7678         [ "$layout_after" == "$layout_before" ] ||
7679                 error "lfs_migrate --copy: $layout_after != $layout_before"
7680 }
7681 run_test 56xd "check lfs_migrate --yaml and --copy support"
7682
7683 test_56xe() {
7684         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7685
7686         local dir=$DIR/$tdir
7687         local f_comp=$dir/$tfile
7688         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7689         local layout_before=""
7690         local layout_after=""
7691
7692         test_mkdir "$dir" || error "cannot create dir $dir"
7693         $LFS setstripe $layout $f_comp ||
7694                 error "cannot setstripe $f_comp with layout $layout"
7695         layout_before=$(get_layout_param $f_comp)
7696         dd if=/dev/zero of=$f_comp bs=1M count=4
7697
7698         # 1. migrate a comp layout file by lfs_migrate
7699         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7700         layout_after=$(get_layout_param $f_comp)
7701         [ "$layout_before" == "$layout_after" ] ||
7702                 error "lfs_migrate: $layout_before != $layout_after"
7703
7704         # 2. migrate a comp layout file by lfs migrate
7705         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7706         layout_after=$(get_layout_param $f_comp)
7707         [ "$layout_before" == "$layout_after" ] ||
7708                 error "lfs migrate: $layout_before != $layout_after"
7709 }
7710 run_test 56xe "migrate a composite layout file"
7711
7712 test_56xf() {
7713         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7714
7715         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7716                 skip "Need server version at least 2.13.53"
7717
7718         local dir=$DIR/$tdir
7719         local f_comp=$dir/$tfile
7720         local layout="-E 1M -c1 -E -1 -c2"
7721         local fid_before=""
7722         local fid_after=""
7723
7724         test_mkdir "$dir" || error "cannot create dir $dir"
7725         $LFS setstripe $layout $f_comp ||
7726                 error "cannot setstripe $f_comp with layout $layout"
7727         fid_before=$($LFS getstripe --fid $f_comp)
7728         dd if=/dev/zero of=$f_comp bs=1M count=4
7729
7730         # 1. migrate a comp layout file to a comp layout
7731         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7732         fid_after=$($LFS getstripe --fid $f_comp)
7733         [ "$fid_before" == "$fid_after" ] ||
7734                 error "comp-to-comp migrate: $fid_before != $fid_after"
7735
7736         # 2. migrate a comp layout file to a plain layout
7737         $LFS migrate -c2 $f_comp ||
7738                 error "cannot migrate $f_comp by lfs migrate"
7739         fid_after=$($LFS getstripe --fid $f_comp)
7740         [ "$fid_before" == "$fid_after" ] ||
7741                 error "comp-to-plain migrate: $fid_before != $fid_after"
7742
7743         # 3. migrate a plain layout file to a comp layout
7744         $LFS migrate $layout $f_comp ||
7745                 error "cannot migrate $f_comp by lfs migrate"
7746         fid_after=$($LFS getstripe --fid $f_comp)
7747         [ "$fid_before" == "$fid_after" ] ||
7748                 error "plain-to-comp migrate: $fid_before != $fid_after"
7749 }
7750 run_test 56xf "FID is not lost during migration of a composite layout file"
7751
7752 check_file_ost_range() {
7753         local file="$1"
7754         shift
7755         local range="$*"
7756         local -a file_range
7757         local idx
7758
7759         file_range=($($LFS getstripe -y "$file" |
7760                 awk '/l_ost_idx:/ { print $NF }'))
7761
7762         if [[ "${#file_range[@]}" = 0 ]]; then
7763                 echo "No osts found for $file"
7764                 return 1
7765         fi
7766
7767         for idx in "${file_range[@]}"; do
7768                 [[ " $range " =~ " $idx " ]] ||
7769                         return 1
7770         done
7771
7772         return 0
7773 }
7774
7775 sub_test_56xg() {
7776         local stripe_opt="$1"
7777         local pool="$2"
7778         shift 2
7779         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7780
7781         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7782                 error "Fail to migrate $tfile on $pool"
7783         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7784                 error "$tfile is not in pool $pool"
7785         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7786                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7787 }
7788
7789 test_56xg() {
7790         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7791         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7792         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7793                 skip "Need MDS version newer than 2.14.52"
7794
7795         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7796         local -a pool_ranges=("0 0" "1 1" "0 1")
7797
7798         # init pools
7799         for i in "${!pool_names[@]}"; do
7800                 pool_add ${pool_names[$i]} ||
7801                         error "pool_add failed (pool: ${pool_names[$i]})"
7802                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7803                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7804         done
7805
7806         # init the file to migrate
7807         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7808                 error "Unable to create $tfile on OST1"
7809         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7810                 error "Unable to write on $tfile"
7811
7812         echo "1. migrate $tfile on pool ${pool_names[0]}"
7813         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7814
7815         echo "2. migrate $tfile on pool ${pool_names[2]}"
7816         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7817
7818         echo "3. migrate $tfile on pool ${pool_names[1]}"
7819         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7820
7821         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7822         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7823         echo
7824
7825         # Clean pools
7826         destroy_test_pools ||
7827                 error "pool_destroy failed"
7828 }
7829 run_test 56xg "lfs migrate pool support"
7830
7831 test_56y() {
7832         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7833                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7834
7835         local res=""
7836         local dir=$DIR/$tdir
7837         local f1=$dir/file1
7838         local f2=$dir/file2
7839
7840         test_mkdir -p $dir || error "creating dir $dir"
7841         touch $f1 || error "creating std file $f1"
7842         $MULTIOP $f2 H2c || error "creating released file $f2"
7843
7844         # a directory can be raid0, so ask only for files
7845         res=$($LFS find $dir -L raid0 -type f | wc -l)
7846         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7847
7848         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7849         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7850
7851         # only files can be released, so no need to force file search
7852         res=$($LFS find $dir -L released)
7853         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7854
7855         res=$($LFS find $dir -type f \! -L released)
7856         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7857 }
7858 run_test 56y "lfs find -L raid0|released"
7859
7860 test_56z() { # LU-4824
7861         # This checks to make sure 'lfs find' continues after errors
7862         # There are two classes of errors that should be caught:
7863         # - If multiple paths are provided, all should be searched even if one
7864         #   errors out
7865         # - If errors are encountered during the search, it should not terminate
7866         #   early
7867         local dir=$DIR/$tdir
7868         local i
7869
7870         test_mkdir $dir
7871         for i in d{0..9}; do
7872                 test_mkdir $dir/$i
7873                 touch $dir/$i/$tfile
7874         done
7875         $LFS find $DIR/non_existent_dir $dir &&
7876                 error "$LFS find did not return an error"
7877         # Make a directory unsearchable. This should NOT be the last entry in
7878         # directory order.  Arbitrarily pick the 6th entry
7879         chmod 700 $($LFS find $dir -type d | sed '6!d')
7880
7881         $RUNAS $LFS find $DIR/non_existent $dir
7882         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7883
7884         # The user should be able to see 10 directories and 9 files
7885         (( count == 19 )) ||
7886                 error "$LFS find found $count != 19 entries after error"
7887 }
7888 run_test 56z "lfs find should continue after an error"
7889
7890 test_56aa() { # LU-5937
7891         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7892
7893         local dir=$DIR/$tdir
7894
7895         mkdir $dir
7896         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7897
7898         createmany -o $dir/striped_dir/${tfile}- 1024
7899         local dirs=$($LFS find --size +8k $dir/)
7900
7901         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7902 }
7903 run_test 56aa "lfs find --size under striped dir"
7904
7905 test_56ab() { # LU-10705
7906         test_mkdir $DIR/$tdir
7907         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7908         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7909         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7910         # Flush writes to ensure valid blocks.  Need to be more thorough for
7911         # ZFS, since blocks are not allocated/returned to client immediately.
7912         sync_all_data
7913         wait_zfs_commit ost1 2
7914         cancel_lru_locks osc
7915         ls -ls $DIR/$tdir
7916
7917         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7918
7919         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7920
7921         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7922         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7923
7924         rm -f $DIR/$tdir/$tfile.[123]
7925 }
7926 run_test 56ab "lfs find --blocks"
7927
7928 # LU-11188
7929 test_56aca() {
7930         local dir="$DIR/$tdir"
7931         local perms=(001 002 003 004 005 006 007
7932                      010 020 030 040 050 060 070
7933                      100 200 300 400 500 600 700
7934                      111 222 333 444 555 666 777)
7935         local perm_minus=(8 8 4 8 4 4 2
7936                           8 8 4 8 4 4 2
7937                           8 8 4 8 4 4 2
7938                           4 4 2 4 2 2 1)
7939         local perm_slash=(8  8 12  8 12 12 14
7940                           8  8 12  8 12 12 14
7941                           8  8 12  8 12 12 14
7942                          16 16 24 16 24 24 28)
7943
7944         test_mkdir "$dir"
7945         for perm in ${perms[*]}; do
7946                 touch "$dir/$tfile.$perm"
7947                 chmod $perm "$dir/$tfile.$perm"
7948         done
7949
7950         for ((i = 0; i < ${#perms[*]}; i++)); do
7951                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7952                 (( $num == 1 )) ||
7953                         error "lfs find -perm ${perms[i]}:"\
7954                               "$num != 1"
7955
7956                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7957                 (( $num == ${perm_minus[i]} )) ||
7958                         error "lfs find -perm -${perms[i]}:"\
7959                               "$num != ${perm_minus[i]}"
7960
7961                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7962                 (( $num == ${perm_slash[i]} )) ||
7963                         error "lfs find -perm /${perms[i]}:"\
7964                               "$num != ${perm_slash[i]}"
7965         done
7966 }
7967 run_test 56aca "check lfs find -perm with octal representation"
7968
7969 test_56acb() {
7970         local dir=$DIR/$tdir
7971         # p is the permission of write and execute for user, group and other
7972         # without the umask. It is used to test +wx.
7973         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7974         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7975         local symbolic=(+t  a+t u+t g+t o+t
7976                         g+s u+s o+s +s o+sr
7977                         o=r,ug+o,u+w
7978                         u+ g+ o+ a+ ugo+
7979                         u- g- o- a- ugo-
7980                         u= g= o= a= ugo=
7981                         o=r,ug+o,u+w u=r,a+u,u+w
7982                         g=r,ugo=g,u+w u+x,+X +X
7983                         u+x,u+X u+X u+x,g+X o+r,+X
7984                         u+x,go+X +wx +rwx)
7985
7986         test_mkdir $dir
7987         for perm in ${perms[*]}; do
7988                 touch "$dir/$tfile.$perm"
7989                 chmod $perm "$dir/$tfile.$perm"
7990         done
7991
7992         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7993                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7994
7995                 (( $num == 1 )) ||
7996                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7997         done
7998 }
7999 run_test 56acb "check lfs find -perm with symbolic representation"
8000
8001 test_56acc() {
8002         local dir=$DIR/$tdir
8003         local tests="17777 787 789 abcd
8004                 ug=uu ug=a ug=gu uo=ou urw
8005                 u+xg+x a=r,u+x,"
8006
8007         test_mkdir $dir
8008         for err in $tests; do
8009                 if $LFS find $dir -perm $err 2>/dev/null; then
8010                         error "lfs find -perm $err: parsing should have failed"
8011                 fi
8012         done
8013 }
8014 run_test 56acc "check parsing error for lfs find -perm"
8015
8016 test_56ba() {
8017         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8018                 skip "Need MDS version at least 2.10.50"
8019
8020         # Create composite files with one component
8021         local dir=$DIR/$tdir
8022
8023         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8024         # Create composite files with three components
8025         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8026         # Create non-composite files
8027         createmany -o $dir/${tfile}- 10
8028
8029         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8030
8031         [[ $nfiles == 10 ]] ||
8032                 error "lfs find -E 1M found $nfiles != 10 files"
8033
8034         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8035         [[ $nfiles == 25 ]] ||
8036                 error "lfs find ! -E 1M found $nfiles != 25 files"
8037
8038         # All files have a component that starts at 0
8039         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8040         [[ $nfiles == 35 ]] ||
8041                 error "lfs find --component-start 0 - $nfiles != 35 files"
8042
8043         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8044         [[ $nfiles == 15 ]] ||
8045                 error "lfs find --component-start 2M - $nfiles != 15 files"
8046
8047         # All files created here have a componenet that does not starts at 2M
8048         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8049         [[ $nfiles == 35 ]] ||
8050                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8051
8052         # Find files with a specified number of components
8053         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8054         [[ $nfiles == 15 ]] ||
8055                 error "lfs find --component-count 3 - $nfiles != 15 files"
8056
8057         # Remember non-composite files have a component count of zero
8058         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8059         [[ $nfiles == 10 ]] ||
8060                 error "lfs find --component-count 0 - $nfiles != 10 files"
8061
8062         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8063         [[ $nfiles == 20 ]] ||
8064                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8065
8066         # All files have a flag called "init"
8067         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8068         [[ $nfiles == 35 ]] ||
8069                 error "lfs find --component-flags init - $nfiles != 35 files"
8070
8071         # Multi-component files will have a component not initialized
8072         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8073         [[ $nfiles == 15 ]] ||
8074                 error "lfs find !--component-flags init - $nfiles != 15 files"
8075
8076         rm -rf $dir
8077
8078 }
8079 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8080
8081 test_56ca() {
8082         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8083                 skip "Need MDS version at least 2.10.57"
8084
8085         local td=$DIR/$tdir
8086         local tf=$td/$tfile
8087         local dir
8088         local nfiles
8089         local cmd
8090         local i
8091         local j
8092
8093         # create mirrored directories and mirrored files
8094         mkdir $td || error "mkdir $td failed"
8095         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8096         createmany -o $tf- 10 || error "create $tf- failed"
8097
8098         for i in $(seq 2); do
8099                 dir=$td/dir$i
8100                 mkdir $dir || error "mkdir $dir failed"
8101                 $LFS mirror create -N$((3 + i)) $dir ||
8102                         error "create mirrored dir $dir failed"
8103                 createmany -o $dir/$tfile- 10 ||
8104                         error "create $dir/$tfile- failed"
8105         done
8106
8107         # change the states of some mirrored files
8108         echo foo > $tf-6
8109         for i in $(seq 2); do
8110                 dir=$td/dir$i
8111                 for j in $(seq 4 9); do
8112                         echo foo > $dir/$tfile-$j
8113                 done
8114         done
8115
8116         # find mirrored files with specific mirror count
8117         cmd="$LFS find --mirror-count 3 --type f $td"
8118         nfiles=$($cmd | wc -l)
8119         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8120
8121         cmd="$LFS find ! --mirror-count 3 --type f $td"
8122         nfiles=$($cmd | wc -l)
8123         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8124
8125         cmd="$LFS find --mirror-count +2 --type f $td"
8126         nfiles=$($cmd | wc -l)
8127         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8128
8129         cmd="$LFS find --mirror-count -6 --type f $td"
8130         nfiles=$($cmd | wc -l)
8131         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8132
8133         # find mirrored files with specific file state
8134         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8135         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8136
8137         cmd="$LFS find --mirror-state=ro --type f $td"
8138         nfiles=$($cmd | wc -l)
8139         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8140
8141         cmd="$LFS find ! --mirror-state=ro --type f $td"
8142         nfiles=$($cmd | wc -l)
8143         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8144
8145         cmd="$LFS find --mirror-state=wp --type f $td"
8146         nfiles=$($cmd | wc -l)
8147         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8148
8149         cmd="$LFS find ! --mirror-state=sp --type f $td"
8150         nfiles=$($cmd | wc -l)
8151         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8152 }
8153 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8154
8155 test_56da() { # LU-14179
8156         local path=$DIR/$tdir
8157
8158         test_mkdir $path
8159         cd $path
8160
8161         local longdir=$(str_repeat 'a' 255)
8162
8163         for i in {1..15}; do
8164                 path=$path/$longdir
8165                 test_mkdir $longdir
8166                 cd $longdir
8167         done
8168
8169         local len=${#path}
8170         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8171
8172         test_mkdir $lastdir
8173         cd $lastdir
8174         # PATH_MAX-1
8175         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8176
8177         # NAME_MAX
8178         touch $(str_repeat 'f' 255)
8179
8180         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8181                 error "lfs find reported an error"
8182
8183         rm -rf $DIR/$tdir
8184 }
8185 run_test 56da "test lfs find with long paths"
8186
8187 test_56ea() { #LU-10378
8188         local path=$DIR/$tdir
8189         local pool=$TESTNAME
8190
8191         # Create ost pool
8192         pool_add $pool || error "pool_add $pool failed"
8193         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8194                 error "adding targets to $pool failed"
8195
8196         # Set default pool on directory before creating file
8197         mkdir $path || error "mkdir $path failed"
8198         $LFS setstripe -p $pool $path ||
8199                 error "set OST pool on $pool failed"
8200         touch $path/$tfile || error "touch $path/$tfile failed"
8201
8202         # Compare basic file attributes from -printf and stat
8203         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8204         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8205
8206         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8207                 error "Attrs from lfs find and stat don't match"
8208
8209         # Compare Lustre attributes from lfs find and lfs getstripe
8210         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8211         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8212         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8213         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8214         local fpool=$($LFS getstripe --pool $path/$tfile)
8215         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8216
8217         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8218                 error "Attrs from lfs find and lfs getstripe don't match"
8219
8220         # Verify behavior for unknown escape/format sequences
8221         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8222
8223         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8224                 error "Escape/format codes don't match"
8225 }
8226 run_test 56ea "test lfs find -printf option"
8227
8228 test_57a() {
8229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8230         # note test will not do anything if MDS is not local
8231         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8232                 skip_env "ldiskfs only test"
8233         fi
8234         remote_mds_nodsh && skip "remote MDS with nodsh"
8235
8236         local MNTDEV="osd*.*MDT*.mntdev"
8237         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8238         [ -z "$DEV" ] && error "can't access $MNTDEV"
8239         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8240                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8241                         error "can't access $DEV"
8242                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8243                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8244                 rm $TMP/t57a.dump
8245         done
8246 }
8247 run_test 57a "verify MDS filesystem created with large inodes =="
8248
8249 test_57b() {
8250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8251         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8252                 skip_env "ldiskfs only test"
8253         fi
8254         remote_mds_nodsh && skip "remote MDS with nodsh"
8255
8256         local dir=$DIR/$tdir
8257         local filecount=100
8258         local file1=$dir/f1
8259         local fileN=$dir/f$filecount
8260
8261         rm -rf $dir || error "removing $dir"
8262         test_mkdir -c1 $dir
8263         local mdtidx=$($LFS getstripe -m $dir)
8264         local mdtname=MDT$(printf %04x $mdtidx)
8265         local facet=mds$((mdtidx + 1))
8266
8267         echo "mcreating $filecount files"
8268         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8269
8270         # verify that files do not have EAs yet
8271         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8272                 error "$file1 has an EA"
8273         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8274                 error "$fileN has an EA"
8275
8276         sync
8277         sleep 1
8278         df $dir  #make sure we get new statfs data
8279         local mdsfree=$(do_facet $facet \
8280                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8281         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8282         local file
8283
8284         echo "opening files to create objects/EAs"
8285         for file in $(seq -f $dir/f%g 1 $filecount); do
8286                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8287                         error "opening $file"
8288         done
8289
8290         # verify that files have EAs now
8291         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8292         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8293
8294         sleep 1  #make sure we get new statfs data
8295         df $dir
8296         local mdsfree2=$(do_facet $facet \
8297                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8298         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8299
8300         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8301                 if [ "$mdsfree" != "$mdsfree2" ]; then
8302                         error "MDC before $mdcfree != after $mdcfree2"
8303                 else
8304                         echo "MDC before $mdcfree != after $mdcfree2"
8305                         echo "unable to confirm if MDS has large inodes"
8306                 fi
8307         fi
8308         rm -rf $dir
8309 }
8310 run_test 57b "default LOV EAs are stored inside large inodes ==="
8311
8312 test_58() {
8313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8314         [ -z "$(which wiretest 2>/dev/null)" ] &&
8315                         skip_env "could not find wiretest"
8316
8317         wiretest
8318 }
8319 run_test 58 "verify cross-platform wire constants =============="
8320
8321 test_59() {
8322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8323
8324         echo "touch 130 files"
8325         createmany -o $DIR/f59- 130
8326         echo "rm 130 files"
8327         unlinkmany $DIR/f59- 130
8328         sync
8329         # wait for commitment of removal
8330         wait_delete_completed
8331 }
8332 run_test 59 "verify cancellation of llog records async ========="
8333
8334 TEST60_HEAD="test_60 run $RANDOM"
8335 test_60a() {
8336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8337         remote_mgs_nodsh && skip "remote MGS with nodsh"
8338         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8339                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8340                         skip_env "missing subtest run-llog.sh"
8341
8342         log "$TEST60_HEAD - from kernel mode"
8343         do_facet mgs "$LCTL dk > /dev/null"
8344         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8345         do_facet mgs $LCTL dk > $TMP/$tfile
8346
8347         # LU-6388: test llog_reader
8348         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8349         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8350         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8351                         skip_env "missing llog_reader"
8352         local fstype=$(facet_fstype mgs)
8353         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8354                 skip_env "Only for ldiskfs or zfs type mgs"
8355
8356         local mntpt=$(facet_mntpt mgs)
8357         local mgsdev=$(mgsdevname 1)
8358         local fid_list
8359         local fid
8360         local rec_list
8361         local rec
8362         local rec_type
8363         local obj_file
8364         local path
8365         local seq
8366         local oid
8367         local pass=true
8368
8369         #get fid and record list
8370         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8371                 tail -n 4))
8372         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8373                 tail -n 4))
8374         #remount mgs as ldiskfs or zfs type
8375         stop mgs || error "stop mgs failed"
8376         mount_fstype mgs || error "remount mgs failed"
8377         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8378                 fid=${fid_list[i]}
8379                 rec=${rec_list[i]}
8380                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8381                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8382                 oid=$((16#$oid))
8383
8384                 case $fstype in
8385                         ldiskfs )
8386                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8387                         zfs )
8388                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8389                 esac
8390                 echo "obj_file is $obj_file"
8391                 do_facet mgs $llog_reader $obj_file
8392
8393                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8394                         awk '{ print $3 }' | sed -e "s/^type=//g")
8395                 if [ $rec_type != $rec ]; then
8396                         echo "FAILED test_60a wrong record type $rec_type," \
8397                               "should be $rec"
8398                         pass=false
8399                         break
8400                 fi
8401
8402                 #check obj path if record type is LLOG_LOGID_MAGIC
8403                 if [ "$rec" == "1064553b" ]; then
8404                         path=$(do_facet mgs $llog_reader $obj_file |
8405                                 grep "path=" | awk '{ print $NF }' |
8406                                 sed -e "s/^path=//g")
8407                         if [ $obj_file != $mntpt/$path ]; then
8408                                 echo "FAILED test_60a wrong obj path" \
8409                                       "$montpt/$path, should be $obj_file"
8410                                 pass=false
8411                                 break
8412                         fi
8413                 fi
8414         done
8415         rm -f $TMP/$tfile
8416         #restart mgs before "error", otherwise it will block the next test
8417         stop mgs || error "stop mgs failed"
8418         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8419         $pass || error "test failed, see FAILED test_60a messages for specifics"
8420 }
8421 run_test 60a "llog_test run from kernel module and test llog_reader"
8422
8423 test_60b() { # bug 6411
8424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8425
8426         dmesg > $DIR/$tfile
8427         LLOG_COUNT=$(do_facet mgs dmesg |
8428                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8429                           /llog_[a-z]*.c:[0-9]/ {
8430                                 if (marker)
8431                                         from_marker++
8432                                 from_begin++
8433                           }
8434                           END {
8435                                 if (marker)
8436                                         print from_marker
8437                                 else
8438                                         print from_begin
8439                           }")
8440
8441         [[ $LLOG_COUNT -gt 120 ]] &&
8442                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8443 }
8444 run_test 60b "limit repeated messages from CERROR/CWARN"
8445
8446 test_60c() {
8447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8448
8449         echo "create 5000 files"
8450         createmany -o $DIR/f60c- 5000
8451 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8452         lctl set_param fail_loc=0x80000137
8453         unlinkmany $DIR/f60c- 5000
8454         lctl set_param fail_loc=0
8455 }
8456 run_test 60c "unlink file when mds full"
8457
8458 test_60d() {
8459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8460
8461         SAVEPRINTK=$(lctl get_param -n printk)
8462         # verify "lctl mark" is even working"
8463         MESSAGE="test message ID $RANDOM $$"
8464         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8465         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8466
8467         lctl set_param printk=0 || error "set lnet.printk failed"
8468         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8469         MESSAGE="new test message ID $RANDOM $$"
8470         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8471         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8472         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8473
8474         lctl set_param -n printk="$SAVEPRINTK"
8475 }
8476 run_test 60d "test printk console message masking"
8477
8478 test_60e() {
8479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8480         remote_mds_nodsh && skip "remote MDS with nodsh"
8481
8482         touch $DIR/$tfile
8483 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8484         do_facet mds1 lctl set_param fail_loc=0x15b
8485         rm $DIR/$tfile
8486 }
8487 run_test 60e "no space while new llog is being created"
8488
8489 test_60f() {
8490         local old_path=$($LCTL get_param -n debug_path)
8491
8492         stack_trap "$LCTL set_param debug_path=$old_path"
8493         stack_trap "rm -f $TMP/$tfile*"
8494         rm -f $TMP/$tfile* 2> /dev/null
8495         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8496         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8497         test_mkdir $DIR/$tdir
8498         # retry in case the open is cached and not released
8499         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8500                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8501                 sleep 0.1
8502         done
8503         ls $TMP/$tfile*
8504         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8505 }
8506 run_test 60f "change debug_path works"
8507
8508 test_60g() {
8509         local pid
8510         local i
8511
8512         test_mkdir -c $MDSCOUNT $DIR/$tdir
8513
8514         (
8515                 local index=0
8516                 while true; do
8517                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8518                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8519                                 2>/dev/null
8520                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8521                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8522                         index=$((index + 1))
8523                 done
8524         ) &
8525
8526         pid=$!
8527
8528         for i in {0..100}; do
8529                 # define OBD_FAIL_OSD_TXN_START    0x19a
8530                 local index=$((i % MDSCOUNT + 1))
8531
8532                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8533                         > /dev/null
8534                 sleep 0.01
8535         done
8536
8537         kill -9 $pid
8538
8539         for i in $(seq $MDSCOUNT); do
8540                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8541         done
8542
8543         mkdir $DIR/$tdir/new || error "mkdir failed"
8544         rmdir $DIR/$tdir/new || error "rmdir failed"
8545
8546         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8547                 -t namespace
8548         for i in $(seq $MDSCOUNT); do
8549                 wait_update_facet mds$i "$LCTL get_param -n \
8550                         mdd.$(facet_svc mds$i).lfsck_namespace |
8551                         awk '/^status/ { print \\\$2 }'" "completed"
8552         done
8553
8554         ls -R $DIR/$tdir
8555         rm -rf $DIR/$tdir || error "rmdir failed"
8556 }
8557 run_test 60g "transaction abort won't cause MDT hung"
8558
8559 test_60h() {
8560         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8561                 skip "Need MDS version at least 2.12.52"
8562         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8563
8564         local f
8565
8566         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8567         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8568         for fail_loc in 0x80000188 0x80000189; do
8569                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8570                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8571                         error "mkdir $dir-$fail_loc failed"
8572                 for i in {0..10}; do
8573                         # create may fail on missing stripe
8574                         echo $i > $DIR/$tdir-$fail_loc/$i
8575                 done
8576                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8577                         error "getdirstripe $tdir-$fail_loc failed"
8578                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8579                         error "migrate $tdir-$fail_loc failed"
8580                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8581                         error "getdirstripe $tdir-$fail_loc failed"
8582                 pushd $DIR/$tdir-$fail_loc
8583                 for f in *; do
8584                         echo $f | cmp $f - || error "$f data mismatch"
8585                 done
8586                 popd
8587                 rm -rf $DIR/$tdir-$fail_loc
8588         done
8589 }
8590 run_test 60h "striped directory with missing stripes can be accessed"
8591
8592 function t60i_load() {
8593         mkdir $DIR/$tdir
8594         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8595         $LCTL set_param fail_loc=0x131c fail_val=1
8596         for ((i=0; i<5000; i++)); do
8597                 touch $DIR/$tdir/f$i
8598         done
8599 }
8600
8601 test_60i() {
8602         changelog_register || error "changelog_register failed"
8603         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8604         changelog_users $SINGLEMDS | grep -q $cl_user ||
8605                 error "User $cl_user not found in changelog_users"
8606         changelog_chmask "ALL"
8607         t60i_load &
8608         local PID=$!
8609         for((i=0; i<100; i++)); do
8610                 changelog_dump >/dev/null ||
8611                         error "can't read changelog"
8612         done
8613         kill $PID
8614         wait $PID
8615         changelog_deregister || error "changelog_deregister failed"
8616         $LCTL set_param fail_loc=0
8617 }
8618 run_test 60i "llog: new record vs reader race"
8619
8620 test_61a() {
8621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8622
8623         f="$DIR/f61"
8624         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8625         cancel_lru_locks osc
8626         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8627         sync
8628 }
8629 run_test 61a "mmap() writes don't make sync hang ================"
8630
8631 test_61b() {
8632         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8633 }
8634 run_test 61b "mmap() of unstriped file is successful"
8635
8636 # bug 2330 - insufficient obd_match error checking causes LBUG
8637 test_62() {
8638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8639
8640         f="$DIR/f62"
8641         echo foo > $f
8642         cancel_lru_locks osc
8643         lctl set_param fail_loc=0x405
8644         cat $f && error "cat succeeded, expect -EIO"
8645         lctl set_param fail_loc=0
8646 }
8647 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8648 # match every page all of the time.
8649 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8650
8651 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8652 # Though this test is irrelevant anymore, it helped to reveal some
8653 # other grant bugs (LU-4482), let's keep it.
8654 test_63a() {   # was test_63
8655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8656
8657         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8658
8659         for i in `seq 10` ; do
8660                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8661                 sleep 5
8662                 kill $!
8663                 sleep 1
8664         done
8665
8666         rm -f $DIR/f63 || true
8667 }
8668 run_test 63a "Verify oig_wait interruption does not crash ======="
8669
8670 # bug 2248 - async write errors didn't return to application on sync
8671 # bug 3677 - async write errors left page locked
8672 test_63b() {
8673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8674
8675         debugsave
8676         lctl set_param debug=-1
8677
8678         # ensure we have a grant to do async writes
8679         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8680         rm $DIR/$tfile
8681
8682         sync    # sync lest earlier test intercept the fail_loc
8683
8684         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8685         lctl set_param fail_loc=0x80000406
8686         $MULTIOP $DIR/$tfile Owy && \
8687                 error "sync didn't return ENOMEM"
8688         sync; sleep 2; sync     # do a real sync this time to flush page
8689         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8690                 error "locked page left in cache after async error" || true
8691         debugrestore
8692 }
8693 run_test 63b "async write errors should be returned to fsync ==="
8694
8695 test_64a () {
8696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8697
8698         lfs df $DIR
8699         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8700 }
8701 run_test 64a "verify filter grant calculations (in kernel) ====="
8702
8703 test_64b () {
8704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8705
8706         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8707 }
8708 run_test 64b "check out-of-space detection on client"
8709
8710 test_64c() {
8711         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8712 }
8713 run_test 64c "verify grant shrink"
8714
8715 import_param() {
8716         local tgt=$1
8717         local param=$2
8718
8719         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8720 }
8721
8722 # this does exactly what osc_request.c:osc_announce_cached() does in
8723 # order to calculate max amount of grants to ask from server
8724 want_grant() {
8725         local tgt=$1
8726
8727         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8728         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8729
8730         ((rpc_in_flight++));
8731         nrpages=$((nrpages * rpc_in_flight))
8732
8733         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8734
8735         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8736
8737         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8738         local undirty=$((nrpages * PAGE_SIZE))
8739
8740         local max_extent_pages
8741         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8742         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8743         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8744         local grant_extent_tax
8745         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8746
8747         undirty=$((undirty + nrextents * grant_extent_tax))
8748
8749         echo $undirty
8750 }
8751
8752 # this is size of unit for grant allocation. It should be equal to
8753 # what tgt_grant.c:tgt_grant_chunk() calculates
8754 grant_chunk() {
8755         local tgt=$1
8756         local max_brw_size
8757         local grant_extent_tax
8758
8759         max_brw_size=$(import_param $tgt max_brw_size)
8760
8761         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8762
8763         echo $(((max_brw_size + grant_extent_tax) * 2))
8764 }
8765
8766 test_64d() {
8767         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8768                 skip "OST < 2.10.55 doesn't limit grants enough"
8769
8770         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8771
8772         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8773                 skip "no grant_param connect flag"
8774
8775         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8776
8777         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8778         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8779
8780
8781         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8782         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8783
8784         $LFS setstripe $DIR/$tfile -i 0 -c 1
8785         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8786         ddpid=$!
8787
8788         while kill -0 $ddpid; do
8789                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8790
8791                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8792                         kill $ddpid
8793                         error "cur_grant $cur_grant > $max_cur_granted"
8794                 fi
8795
8796                 sleep 1
8797         done
8798 }
8799 run_test 64d "check grant limit exceed"
8800
8801 check_grants() {
8802         local tgt=$1
8803         local expected=$2
8804         local msg=$3
8805         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8806
8807         ((cur_grants == expected)) ||
8808                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8809 }
8810
8811 round_up_p2() {
8812         echo $((($1 + $2 - 1) & ~($2 - 1)))
8813 }
8814
8815 test_64e() {
8816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8817         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8818                 skip "Need OSS version at least 2.11.56"
8819
8820         # Remount client to reset grant
8821         remount_client $MOUNT || error "failed to remount client"
8822         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8823
8824         local init_grants=$(import_param $osc_tgt initial_grant)
8825
8826         check_grants $osc_tgt $init_grants "init grants"
8827
8828         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8829         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8830         local gbs=$(import_param $osc_tgt grant_block_size)
8831
8832         # write random number of bytes from max_brw_size / 4 to max_brw_size
8833         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8834         # align for direct io
8835         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8836         # round to grant consumption unit
8837         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8838
8839         local grants=$((wb_round_up + extent_tax))
8840
8841         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8842
8843         # define OBD_FAIL_TGT_NO_GRANT 0x725
8844         # make the server not grant more back
8845         do_facet ost1 $LCTL set_param fail_loc=0x725
8846         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8847
8848         do_facet ost1 $LCTL set_param fail_loc=0
8849
8850         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8851
8852         rm -f $DIR/$tfile || error "rm failed"
8853
8854         # Remount client to reset grant
8855         remount_client $MOUNT || error "failed to remount client"
8856         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8857
8858         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8859
8860         # define OBD_FAIL_TGT_NO_GRANT 0x725
8861         # make the server not grant more back
8862         do_facet ost1 $LCTL set_param fail_loc=0x725
8863         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8864         do_facet ost1 $LCTL set_param fail_loc=0
8865
8866         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8867 }
8868 run_test 64e "check grant consumption (no grant allocation)"
8869
8870 test_64f() {
8871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8872
8873         # Remount client to reset grant
8874         remount_client $MOUNT || error "failed to remount client"
8875         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8876
8877         local init_grants=$(import_param $osc_tgt initial_grant)
8878         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8879         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8880         local gbs=$(import_param $osc_tgt grant_block_size)
8881         local chunk=$(grant_chunk $osc_tgt)
8882
8883         # write random number of bytes from max_brw_size / 4 to max_brw_size
8884         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8885         # align for direct io
8886         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8887         # round to grant consumption unit
8888         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8889
8890         local grants=$((wb_round_up + extent_tax))
8891
8892         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8893         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8894                 error "error writing to $DIR/$tfile"
8895
8896         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8897                 "direct io with grant allocation"
8898
8899         rm -f $DIR/$tfile || error "rm failed"
8900
8901         # Remount client to reset grant
8902         remount_client $MOUNT || error "failed to remount client"
8903         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8904
8905         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8906
8907         local cmd="oO_WRONLY:w${write_bytes}_yc"
8908
8909         $MULTIOP $DIR/$tfile $cmd &
8910         MULTIPID=$!
8911         sleep 1
8912
8913         check_grants $osc_tgt $((init_grants - grants)) \
8914                 "buffered io, not write rpc"
8915
8916         kill -USR1 $MULTIPID
8917         wait
8918
8919         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8920                 "buffered io, one RPC"
8921 }
8922 run_test 64f "check grant consumption (with grant allocation)"
8923
8924 test_64g() {
8925         #[ $MDS1_VERSION -lt $(version_code 2.14.54) ] &&
8926         #       skip "Need MDS version at least 2.14.54"
8927
8928         local mdts=$(comma_list $(mdts_nodes))
8929
8930         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8931                         tr '\n' ' ')
8932         stack_trap "$LCTL set_param $old"
8933
8934         # generate dirty pages and increase dirty granted on MDT
8935         stack_trap "rm -f $DIR/$tfile-*"
8936         for (( i = 0; i < 10; i++)); do
8937                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8938                         error "can't set stripe"
8939                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8940                         error "can't dd"
8941                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8942                         $LFS getstripe $DIR/$tfile-$i
8943                         error "not DoM file"
8944                 }
8945         done
8946
8947         # flush dirty pages
8948         sync
8949
8950         # wait until grant shrink reset grant dirty on MDTs
8951         for ((i = 0; i < 120; i++)); do
8952                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8953                         awk '{sum=sum+$1} END {print sum}')
8954                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8955                 echo "$grant_dirty grants, $vm_dirty pages"
8956                 (( grant_dirty + vm_dirty == 0 )) && break
8957                 (( i == 3 )) && sync &&
8958                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8959                 sleep 1
8960         done
8961
8962         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8963                 awk '{sum=sum+$1} END {print sum}')
8964         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8965 }
8966 run_test 64g "grant shrink on MDT"
8967
8968 test_64h() {
8969         local instance=$($LFS getname -i $DIR)
8970         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8971         local num_exps=$(do_facet ost1 \
8972             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8973         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8974         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8975         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8976
8977         # 10MiB is for file to be written, max_brw_size * 16 *
8978         # num_exps is space reserve so that tgt_grant_shrink() decided
8979         # to not shrink
8980         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8981         (( avail * 1024 < expect )) &&
8982                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8983
8984         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8985         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
8986         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
8987         $LCTL set_param osc.*OST0000*.grant_shrink=1
8988         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
8989
8990         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8991         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
8992
8993         # drop cache so that coming read would do rpc
8994         cancel_lru_locks osc
8995
8996         # shrink interval is set to 10, pause for 7 seconds so that
8997         # grant thread did not wake up yet but coming read entered
8998         # shrink mode for rpc (osc_should_shrink_grant())
8999         sleep 7
9000
9001         declare -a cur_grant_bytes
9002         declare -a tot_granted
9003         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9004         tot_granted[0]=$(do_facet ost1 \
9005             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9006
9007         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9008
9009         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9010         tot_granted[1]=$(do_facet ost1 \
9011             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9012
9013         # grant change should be equal on both sides
9014         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9015                 tot_granted[0] - tot_granted[1])) ||
9016                 error "grant change mismatch, "                                \
9017                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9018                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9019 }
9020 run_test 64h "grant shrink on read"
9021
9022 test_64i() {
9023         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
9024                 skip "need OST at least 2.14.55 to avoid grant shrink on replay"
9025
9026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9027         remote_ost_nodsh && skip "remote OSTs with nodsh"
9028
9029         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9030
9031         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9032
9033         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9034         local instance=$($LFS getname -i $DIR)
9035
9036         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9037         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9038
9039         # shrink grants and simulate rpc loss
9040         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9041         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9042         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9043
9044         fail ost1
9045
9046         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9047
9048         local testid=$(echo $TESTNAME | tr '_' ' ')
9049
9050         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9051                 grep "GRANT, real grant" &&
9052                 error "client has more grants then it owns" || true
9053 }
9054 run_test 64i "shrink on reconnect"
9055
9056 # bug 1414 - set/get directories' stripe info
9057 test_65a() {
9058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9059
9060         test_mkdir $DIR/$tdir
9061         touch $DIR/$tdir/f1
9062         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9063 }
9064 run_test 65a "directory with no stripe info"
9065
9066 test_65b() {
9067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9068
9069         test_mkdir $DIR/$tdir
9070         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9071
9072         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9073                                                 error "setstripe"
9074         touch $DIR/$tdir/f2
9075         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9076 }
9077 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9078
9079 test_65c() {
9080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9081         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9082
9083         test_mkdir $DIR/$tdir
9084         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9085
9086         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9087                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9088         touch $DIR/$tdir/f3
9089         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9090 }
9091 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9092
9093 test_65d() {
9094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9095
9096         test_mkdir $DIR/$tdir
9097         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9098         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9099
9100         if [[ $STRIPECOUNT -le 0 ]]; then
9101                 sc=1
9102         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9103                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9104                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9105         else
9106                 sc=$(($STRIPECOUNT - 1))
9107         fi
9108         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9109         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9110         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9111                 error "lverify failed"
9112 }
9113 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9114
9115 test_65e() {
9116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9117
9118         test_mkdir $DIR/$tdir
9119
9120         $LFS setstripe $DIR/$tdir || error "setstripe"
9121         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9122                                         error "no stripe info failed"
9123         touch $DIR/$tdir/f6
9124         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9125 }
9126 run_test 65e "directory setstripe defaults"
9127
9128 test_65f() {
9129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9130
9131         test_mkdir $DIR/${tdir}f
9132         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9133                 error "setstripe succeeded" || true
9134 }
9135 run_test 65f "dir setstripe permission (should return error) ==="
9136
9137 test_65g() {
9138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9139
9140         test_mkdir $DIR/$tdir
9141         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9142
9143         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9144                 error "setstripe -S failed"
9145         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9146         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9147                 error "delete default stripe failed"
9148 }
9149 run_test 65g "directory setstripe -d"
9150
9151 test_65h() {
9152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9153
9154         test_mkdir $DIR/$tdir
9155         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9156
9157         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9158                 error "setstripe -S failed"
9159         test_mkdir $DIR/$tdir/dd1
9160         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9161                 error "stripe info inherit failed"
9162 }
9163 run_test 65h "directory stripe info inherit ===================="
9164
9165 test_65i() {
9166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9167
9168         save_layout_restore_at_exit $MOUNT
9169
9170         # bug6367: set non-default striping on root directory
9171         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9172
9173         # bug12836: getstripe on -1 default directory striping
9174         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9175
9176         # bug12836: getstripe -v on -1 default directory striping
9177         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9178
9179         # bug12836: new find on -1 default directory striping
9180         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9181 }
9182 run_test 65i "various tests to set root directory striping"
9183
9184 test_65j() { # bug6367
9185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9186
9187         sync; sleep 1
9188
9189         # if we aren't already remounting for each test, do so for this test
9190         if [ "$I_MOUNTED" = "yes" ]; then
9191                 cleanup || error "failed to unmount"
9192                 setup
9193         fi
9194
9195         save_layout_restore_at_exit $MOUNT
9196
9197         $LFS setstripe -d $MOUNT || error "setstripe failed"
9198 }
9199 run_test 65j "set default striping on root directory (bug 6367)="
9200
9201 cleanup_65k() {
9202         rm -rf $DIR/$tdir
9203         wait_delete_completed
9204         do_facet $SINGLEMDS "lctl set_param -n \
9205                 osp.$ost*MDT0000.max_create_count=$max_count"
9206         do_facet $SINGLEMDS "lctl set_param -n \
9207                 osp.$ost*MDT0000.create_count=$count"
9208         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9209         echo $INACTIVE_OSC "is Activate"
9210
9211         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9212 }
9213
9214 test_65k() { # bug11679
9215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9216         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9217         remote_mds_nodsh && skip "remote MDS with nodsh"
9218
9219         local disable_precreate=true
9220         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9221                 disable_precreate=false
9222
9223         echo "Check OST status: "
9224         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9225                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9226
9227         for OSC in $MDS_OSCS; do
9228                 echo $OSC "is active"
9229                 do_facet $SINGLEMDS lctl --device %$OSC activate
9230         done
9231
9232         for INACTIVE_OSC in $MDS_OSCS; do
9233                 local ost=$(osc_to_ost $INACTIVE_OSC)
9234                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9235                                lov.*md*.target_obd |
9236                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9237
9238                 mkdir -p $DIR/$tdir
9239                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9240                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9241
9242                 echo "Deactivate: " $INACTIVE_OSC
9243                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9244
9245                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9246                               osp.$ost*MDT0000.create_count")
9247                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9248                                   osp.$ost*MDT0000.max_create_count")
9249                 $disable_precreate &&
9250                         do_facet $SINGLEMDS "lctl set_param -n \
9251                                 osp.$ost*MDT0000.max_create_count=0"
9252
9253                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9254                         [ -f $DIR/$tdir/$idx ] && continue
9255                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9256                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9257                                 { cleanup_65k;
9258                                   error "setstripe $idx should succeed"; }
9259                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9260                 done
9261                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9262                 rmdir $DIR/$tdir
9263
9264                 do_facet $SINGLEMDS "lctl set_param -n \
9265                         osp.$ost*MDT0000.max_create_count=$max_count"
9266                 do_facet $SINGLEMDS "lctl set_param -n \
9267                         osp.$ost*MDT0000.create_count=$count"
9268                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9269                 echo $INACTIVE_OSC "is Activate"
9270
9271                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9272         done
9273 }
9274 run_test 65k "validate manual striping works properly with deactivated OSCs"
9275
9276 test_65l() { # bug 12836
9277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9278
9279         test_mkdir -p $DIR/$tdir/test_dir
9280         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9281         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9282 }
9283 run_test 65l "lfs find on -1 stripe dir ========================"
9284
9285 test_65m() {
9286         local layout=$(save_layout $MOUNT)
9287         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9288                 restore_layout $MOUNT $layout
9289                 error "setstripe should fail by non-root users"
9290         }
9291         true
9292 }
9293 run_test 65m "normal user can't set filesystem default stripe"
9294
9295 test_65n() {
9296         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9297         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9298                 skip "Need MDS version at least 2.12.50"
9299         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9300
9301         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9302         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9303         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9304
9305         save_layout_restore_at_exit $MOUNT
9306
9307         # new subdirectory under root directory should not inherit
9308         # the default layout from root
9309         local dir1=$MOUNT/$tdir-1
9310         mkdir $dir1 || error "mkdir $dir1 failed"
9311         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9312                 error "$dir1 shouldn't have LOV EA"
9313
9314         # delete the default layout on root directory
9315         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9316
9317         local dir2=$MOUNT/$tdir-2
9318         mkdir $dir2 || error "mkdir $dir2 failed"
9319         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9320                 error "$dir2 shouldn't have LOV EA"
9321
9322         # set a new striping pattern on root directory
9323         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9324         local new_def_stripe_size=$((def_stripe_size * 2))
9325         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9326                 error "set stripe size on $MOUNT failed"
9327
9328         # new file created in $dir2 should inherit the new stripe size from
9329         # the filesystem default
9330         local file2=$dir2/$tfile-2
9331         touch $file2 || error "touch $file2 failed"
9332
9333         local file2_stripe_size=$($LFS getstripe -S $file2)
9334         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9335         {
9336                 echo "file2_stripe_size: '$file2_stripe_size'"
9337                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9338                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9339         }
9340
9341         local dir3=$MOUNT/$tdir-3
9342         mkdir $dir3 || error "mkdir $dir3 failed"
9343         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9344         # the root layout, which is the actual default layout that will be used
9345         # when new files are created in $dir3.
9346         local dir3_layout=$(get_layout_param $dir3)
9347         local root_dir_layout=$(get_layout_param $MOUNT)
9348         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9349         {
9350                 echo "dir3_layout: '$dir3_layout'"
9351                 echo "root_dir_layout: '$root_dir_layout'"
9352                 error "$dir3 should show the default layout from $MOUNT"
9353         }
9354
9355         # set OST pool on root directory
9356         local pool=$TESTNAME
9357         pool_add $pool || error "add $pool failed"
9358         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9359                 error "add targets to $pool failed"
9360
9361         $LFS setstripe -p $pool $MOUNT ||
9362                 error "set OST pool on $MOUNT failed"
9363
9364         # new file created in $dir3 should inherit the pool from
9365         # the filesystem default
9366         local file3=$dir3/$tfile-3
9367         touch $file3 || error "touch $file3 failed"
9368
9369         local file3_pool=$($LFS getstripe -p $file3)
9370         [[ "$file3_pool" = "$pool" ]] ||
9371                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9372
9373         local dir4=$MOUNT/$tdir-4
9374         mkdir $dir4 || error "mkdir $dir4 failed"
9375         local dir4_layout=$(get_layout_param $dir4)
9376         root_dir_layout=$(get_layout_param $MOUNT)
9377         echo "$LFS getstripe -d $dir4"
9378         $LFS getstripe -d $dir4
9379         echo "$LFS getstripe -d $MOUNT"
9380         $LFS getstripe -d $MOUNT
9381         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9382         {
9383                 echo "dir4_layout: '$dir4_layout'"
9384                 echo "root_dir_layout: '$root_dir_layout'"
9385                 error "$dir4 should show the default layout from $MOUNT"
9386         }
9387
9388         # new file created in $dir4 should inherit the pool from
9389         # the filesystem default
9390         local file4=$dir4/$tfile-4
9391         touch $file4 || error "touch $file4 failed"
9392
9393         local file4_pool=$($LFS getstripe -p $file4)
9394         [[ "$file4_pool" = "$pool" ]] ||
9395                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9396
9397         # new subdirectory under non-root directory should inherit
9398         # the default layout from its parent directory
9399         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9400                 error "set directory layout on $dir4 failed"
9401
9402         local dir5=$dir4/$tdir-5
9403         mkdir $dir5 || error "mkdir $dir5 failed"
9404
9405         dir4_layout=$(get_layout_param $dir4)
9406         local dir5_layout=$(get_layout_param $dir5)
9407         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9408         {
9409                 echo "dir4_layout: '$dir4_layout'"
9410                 echo "dir5_layout: '$dir5_layout'"
9411                 error "$dir5 should inherit the default layout from $dir4"
9412         }
9413
9414         # though subdir under ROOT doesn't inherit default layout, but
9415         # its sub dir/file should be created with default layout.
9416         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9417         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9418                 skip "Need MDS version at least 2.12.59"
9419
9420         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9421         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9422         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9423
9424         if [ $default_lmv_hash == "none" ]; then
9425                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9426         else
9427                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9428                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9429         fi
9430
9431         $LFS setdirstripe -D -c 2 $MOUNT ||
9432                 error "setdirstripe -D -c 2 failed"
9433         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9434         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9435         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9436
9437         # $dir4 layout includes pool
9438         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9439         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9440                 error "pool lost on setstripe"
9441         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9442         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9443                 error "pool lost on compound layout setstripe"
9444 }
9445 run_test 65n "don't inherit default layout from root for new subdirectories"
9446
9447 # bug 2543 - update blocks count on client
9448 test_66() {
9449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9450
9451         COUNT=${COUNT:-8}
9452         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9453         sync; sync_all_data; sync; sync_all_data
9454         cancel_lru_locks osc
9455         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9456         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9457 }
9458 run_test 66 "update inode blocks count on client ==============="
9459
9460 meminfo() {
9461         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9462 }
9463
9464 swap_used() {
9465         swapon -s | awk '($1 == "'$1'") { print $4 }'
9466 }
9467
9468 # bug5265, obdfilter oa2dentry return -ENOENT
9469 # #define OBD_FAIL_SRV_ENOENT 0x217
9470 test_69() {
9471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9472         remote_ost_nodsh && skip "remote OST with nodsh"
9473
9474         f="$DIR/$tfile"
9475         $LFS setstripe -c 1 -i 0 $f
9476
9477         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9478
9479         do_facet ost1 lctl set_param fail_loc=0x217
9480         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9481         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9482
9483         do_facet ost1 lctl set_param fail_loc=0
9484         $DIRECTIO write $f 0 2 || error "write error"
9485
9486         cancel_lru_locks osc
9487         $DIRECTIO read $f 0 1 || error "read error"
9488
9489         do_facet ost1 lctl set_param fail_loc=0x217
9490         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9491
9492         do_facet ost1 lctl set_param fail_loc=0
9493         rm -f $f
9494 }
9495 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9496
9497 test_71() {
9498         test_mkdir $DIR/$tdir
9499         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9500         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9501 }
9502 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9503
9504 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9506         [ "$RUNAS_ID" = "$UID" ] &&
9507                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9508         # Check that testing environment is properly set up. Skip if not
9509         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9510                 skip_env "User $RUNAS_ID does not exist - skipping"
9511
9512         touch $DIR/$tfile
9513         chmod 777 $DIR/$tfile
9514         chmod ug+s $DIR/$tfile
9515         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9516                 error "$RUNAS dd $DIR/$tfile failed"
9517         # See if we are still setuid/sgid
9518         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9519                 error "S/gid is not dropped on write"
9520         # Now test that MDS is updated too
9521         cancel_lru_locks mdc
9522         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9523                 error "S/gid is not dropped on MDS"
9524         rm -f $DIR/$tfile
9525 }
9526 run_test 72a "Test that remove suid works properly (bug5695) ===="
9527
9528 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9529         local perm
9530
9531         [ "$RUNAS_ID" = "$UID" ] &&
9532                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9533         [ "$RUNAS_ID" -eq 0 ] &&
9534                 skip_env "RUNAS_ID = 0 -- skipping"
9535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9536         # Check that testing environment is properly set up. Skip if not
9537         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9538                 skip_env "User $RUNAS_ID does not exist - skipping"
9539
9540         touch $DIR/${tfile}-f{g,u}
9541         test_mkdir $DIR/${tfile}-dg
9542         test_mkdir $DIR/${tfile}-du
9543         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9544         chmod g+s $DIR/${tfile}-{f,d}g
9545         chmod u+s $DIR/${tfile}-{f,d}u
9546         for perm in 777 2777 4777; do
9547                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9548                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9549                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9550                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9551         done
9552         true
9553 }
9554 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9555
9556 # bug 3462 - multiple simultaneous MDC requests
9557 test_73() {
9558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9559
9560         test_mkdir $DIR/d73-1
9561         test_mkdir $DIR/d73-2
9562         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9563         pid1=$!
9564
9565         lctl set_param fail_loc=0x80000129
9566         $MULTIOP $DIR/d73-1/f73-2 Oc &
9567         sleep 1
9568         lctl set_param fail_loc=0
9569
9570         $MULTIOP $DIR/d73-2/f73-3 Oc &
9571         pid3=$!
9572
9573         kill -USR1 $pid1
9574         wait $pid1 || return 1
9575
9576         sleep 25
9577
9578         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9579         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9580         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9581
9582         rm -rf $DIR/d73-*
9583 }
9584 run_test 73 "multiple MDC requests (should not deadlock)"
9585
9586 test_74a() { # bug 6149, 6184
9587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9588
9589         touch $DIR/f74a
9590         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9591         #
9592         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9593         # will spin in a tight reconnection loop
9594         $LCTL set_param fail_loc=0x8000030e
9595         # get any lock that won't be difficult - lookup works.
9596         ls $DIR/f74a
9597         $LCTL set_param fail_loc=0
9598         rm -f $DIR/f74a
9599         true
9600 }
9601 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9602
9603 test_74b() { # bug 13310
9604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9605
9606         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9607         #
9608         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9609         # will spin in a tight reconnection loop
9610         $LCTL set_param fail_loc=0x8000030e
9611         # get a "difficult" lock
9612         touch $DIR/f74b
9613         $LCTL set_param fail_loc=0
9614         rm -f $DIR/f74b
9615         true
9616 }
9617 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9618
9619 test_74c() {
9620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9621
9622         #define OBD_FAIL_LDLM_NEW_LOCK
9623         $LCTL set_param fail_loc=0x319
9624         touch $DIR/$tfile && error "touch successful"
9625         $LCTL set_param fail_loc=0
9626         true
9627 }
9628 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9629
9630 slab_lic=/sys/kernel/slab/lustre_inode_cache
9631 num_objects() {
9632         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9633         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9634                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9635 }
9636
9637 test_76a() { # Now for b=20433, added originally in b=1443
9638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9639
9640         cancel_lru_locks osc
9641         # there may be some slab objects cached per core
9642         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9643         local before=$(num_objects)
9644         local count=$((512 * cpus))
9645         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9646         local margin=$((count / 10))
9647         if [[ -f $slab_lic/aliases ]]; then
9648                 local aliases=$(cat $slab_lic/aliases)
9649                 (( aliases > 0 )) && margin=$((margin * aliases))
9650         fi
9651
9652         echo "before slab objects: $before"
9653         for i in $(seq $count); do
9654                 touch $DIR/$tfile
9655                 rm -f $DIR/$tfile
9656         done
9657         cancel_lru_locks osc
9658         local after=$(num_objects)
9659         echo "created: $count, after slab objects: $after"
9660         # shared slab counts are not very accurate, allow significant margin
9661         # the main goal is that the cache growth is not permanently > $count
9662         while (( after > before + margin )); do
9663                 sleep 1
9664                 after=$(num_objects)
9665                 wait=$((wait + 1))
9666                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9667                 if (( wait > 60 )); then
9668                         error "inode slab grew from $before+$margin to $after"
9669                 fi
9670         done
9671 }
9672 run_test 76a "confirm clients recycle inodes properly ===="
9673
9674 test_76b() {
9675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9676         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9677
9678         local count=512
9679         local before=$(num_objects)
9680
9681         for i in $(seq $count); do
9682                 mkdir $DIR/$tdir
9683                 rmdir $DIR/$tdir
9684         done
9685
9686         local after=$(num_objects)
9687         local wait=0
9688
9689         while (( after > before )); do
9690                 sleep 1
9691                 after=$(num_objects)
9692                 wait=$((wait + 1))
9693                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9694                 if (( wait > 60 )); then
9695                         error "inode slab grew from $before to $after"
9696                 fi
9697         done
9698
9699         echo "slab objects before: $before, after: $after"
9700 }
9701 run_test 76b "confirm clients recycle directory inodes properly ===="
9702
9703 export ORIG_CSUM=""
9704 set_checksums()
9705 {
9706         # Note: in sptlrpc modes which enable its own bulk checksum, the
9707         # original crc32_le bulk checksum will be automatically disabled,
9708         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9709         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9710         # In this case set_checksums() will not be no-op, because sptlrpc
9711         # bulk checksum will be enabled all through the test.
9712
9713         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9714         lctl set_param -n osc.*.checksums $1
9715         return 0
9716 }
9717
9718 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9719                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9720 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9721                              tr -d [] | head -n1)}
9722 set_checksum_type()
9723 {
9724         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9725         rc=$?
9726         log "set checksum type to $1, rc = $rc"
9727         return $rc
9728 }
9729
9730 get_osc_checksum_type()
9731 {
9732         # arugment 1: OST name, like OST0000
9733         ost=$1
9734         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9735                         sed 's/.*\[\(.*\)\].*/\1/g')
9736         rc=$?
9737         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9738         echo $checksum_type
9739 }
9740
9741 F77_TMP=$TMP/f77-temp
9742 F77SZ=8
9743 setup_f77() {
9744         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9745                 error "error writing to $F77_TMP"
9746 }
9747
9748 test_77a() { # bug 10889
9749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9750         $GSS && skip_env "could not run with gss"
9751
9752         [ ! -f $F77_TMP ] && setup_f77
9753         set_checksums 1
9754         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9755         set_checksums 0
9756         rm -f $DIR/$tfile
9757 }
9758 run_test 77a "normal checksum read/write operation"
9759
9760 test_77b() { # bug 10889
9761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9762         $GSS && skip_env "could not run with gss"
9763
9764         [ ! -f $F77_TMP ] && setup_f77
9765         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9766         $LCTL set_param fail_loc=0x80000409
9767         set_checksums 1
9768
9769         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9770                 error "dd error: $?"
9771         $LCTL set_param fail_loc=0
9772
9773         for algo in $CKSUM_TYPES; do
9774                 cancel_lru_locks osc
9775                 set_checksum_type $algo
9776                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9777                 $LCTL set_param fail_loc=0x80000408
9778                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9779                 $LCTL set_param fail_loc=0
9780         done
9781         set_checksums 0
9782         set_checksum_type $ORIG_CSUM_TYPE
9783         rm -f $DIR/$tfile
9784 }
9785 run_test 77b "checksum error on client write, read"
9786
9787 cleanup_77c() {
9788         trap 0
9789         set_checksums 0
9790         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9791         $check_ost &&
9792                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9793         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9794         $check_ost && [ -n "$ost_file_prefix" ] &&
9795                 do_facet ost1 rm -f ${ost_file_prefix}\*
9796 }
9797
9798 test_77c() {
9799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9800         $GSS && skip_env "could not run with gss"
9801         remote_ost_nodsh && skip "remote OST with nodsh"
9802
9803         local bad1
9804         local osc_file_prefix
9805         local osc_file
9806         local check_ost=false
9807         local ost_file_prefix
9808         local ost_file
9809         local orig_cksum
9810         local dump_cksum
9811         local fid
9812
9813         # ensure corruption will occur on first OSS/OST
9814         $LFS setstripe -i 0 $DIR/$tfile
9815
9816         [ ! -f $F77_TMP ] && setup_f77
9817         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9818                 error "dd write error: $?"
9819         fid=$($LFS path2fid $DIR/$tfile)
9820
9821         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9822         then
9823                 check_ost=true
9824                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9825                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9826         else
9827                 echo "OSS do not support bulk pages dump upon error"
9828         fi
9829
9830         osc_file_prefix=$($LCTL get_param -n debug_path)
9831         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9832
9833         trap cleanup_77c EXIT
9834
9835         set_checksums 1
9836         # enable bulk pages dump upon error on Client
9837         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9838         # enable bulk pages dump upon error on OSS
9839         $check_ost &&
9840                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9841
9842         # flush Client cache to allow next read to reach OSS
9843         cancel_lru_locks osc
9844
9845         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9846         $LCTL set_param fail_loc=0x80000408
9847         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9848         $LCTL set_param fail_loc=0
9849
9850         rm -f $DIR/$tfile
9851
9852         # check cksum dump on Client
9853         osc_file=$(ls ${osc_file_prefix}*)
9854         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9855         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9856         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9857         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9858         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9859                      cksum)
9860         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9861         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9862                 error "dump content does not match on Client"
9863
9864         $check_ost || skip "No need to check cksum dump on OSS"
9865
9866         # check cksum dump on OSS
9867         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9868         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9869         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9870         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9871         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9872                 error "dump content does not match on OSS"
9873
9874         cleanup_77c
9875 }
9876 run_test 77c "checksum error on client read with debug"
9877
9878 test_77d() { # bug 10889
9879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9880         $GSS && skip_env "could not run with gss"
9881
9882         stack_trap "rm -f $DIR/$tfile"
9883         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9884         $LCTL set_param fail_loc=0x80000409
9885         set_checksums 1
9886         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9887                 error "direct write: rc=$?"
9888         $LCTL set_param fail_loc=0
9889         set_checksums 0
9890
9891         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9892         $LCTL set_param fail_loc=0x80000408
9893         set_checksums 1
9894         cancel_lru_locks osc
9895         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9896                 error "direct read: rc=$?"
9897         $LCTL set_param fail_loc=0
9898         set_checksums 0
9899 }
9900 run_test 77d "checksum error on OST direct write, read"
9901
9902 test_77f() { # bug 10889
9903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9904         $GSS && skip_env "could not run with gss"
9905
9906         set_checksums 1
9907         stack_trap "rm -f $DIR/$tfile"
9908         for algo in $CKSUM_TYPES; do
9909                 cancel_lru_locks osc
9910                 set_checksum_type $algo
9911                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9912                 $LCTL set_param fail_loc=0x409
9913                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9914                         error "direct write succeeded"
9915                 $LCTL set_param fail_loc=0
9916         done
9917         set_checksum_type $ORIG_CSUM_TYPE
9918         set_checksums 0
9919 }
9920 run_test 77f "repeat checksum error on write (expect error)"
9921
9922 test_77g() { # bug 10889
9923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9924         $GSS && skip_env "could not run with gss"
9925         remote_ost_nodsh && skip "remote OST with nodsh"
9926
9927         [ ! -f $F77_TMP ] && setup_f77
9928
9929         local file=$DIR/$tfile
9930         stack_trap "rm -f $file" EXIT
9931
9932         $LFS setstripe -c 1 -i 0 $file
9933         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9934         do_facet ost1 lctl set_param fail_loc=0x8000021a
9935         set_checksums 1
9936         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9937                 error "write error: rc=$?"
9938         do_facet ost1 lctl set_param fail_loc=0
9939         set_checksums 0
9940
9941         cancel_lru_locks osc
9942         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9943         do_facet ost1 lctl set_param fail_loc=0x8000021b
9944         set_checksums 1
9945         cmp $F77_TMP $file || error "file compare failed"
9946         do_facet ost1 lctl set_param fail_loc=0
9947         set_checksums 0
9948 }
9949 run_test 77g "checksum error on OST write, read"
9950
9951 test_77k() { # LU-10906
9952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9953         $GSS && skip_env "could not run with gss"
9954
9955         local cksum_param="osc.$FSNAME*.checksums"
9956         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9957         local checksum
9958         local i
9959
9960         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9961         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9962         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9963
9964         for i in 0 1; do
9965                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9966                         error "failed to set checksum=$i on MGS"
9967                 wait_update $HOSTNAME "$get_checksum" $i
9968                 #remount
9969                 echo "remount client, checksum should be $i"
9970                 remount_client $MOUNT || error "failed to remount client"
9971                 checksum=$(eval $get_checksum)
9972                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9973         done
9974         # remove persistent param to avoid races with checksum mountopt below
9975         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9976                 error "failed to delete checksum on MGS"
9977
9978         for opt in "checksum" "nochecksum"; do
9979                 #remount with mount option
9980                 echo "remount client with option $opt, checksum should be $i"
9981                 umount_client $MOUNT || error "failed to umount client"
9982                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9983                         error "failed to mount client with option '$opt'"
9984                 checksum=$(eval $get_checksum)
9985                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9986                 i=$((i - 1))
9987         done
9988
9989         remount_client $MOUNT || error "failed to remount client"
9990 }
9991 run_test 77k "enable/disable checksum correctly"
9992
9993 test_77l() {
9994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9995         $GSS && skip_env "could not run with gss"
9996
9997         set_checksums 1
9998         stack_trap "set_checksums $ORIG_CSUM" EXIT
9999         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10000
10001         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10002
10003         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10004         for algo in $CKSUM_TYPES; do
10005                 set_checksum_type $algo || error "fail to set checksum type $algo"
10006                 osc_algo=$(get_osc_checksum_type OST0000)
10007                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10008
10009                 # no locks, no reqs to let the connection idle
10010                 cancel_lru_locks osc
10011                 lru_resize_disable osc
10012                 wait_osc_import_state client ost1 IDLE
10013
10014                 # ensure ost1 is connected
10015                 stat $DIR/$tfile >/dev/null || error "can't stat"
10016                 wait_osc_import_state client ost1 FULL
10017
10018                 osc_algo=$(get_osc_checksum_type OST0000)
10019                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10020         done
10021         return 0
10022 }
10023 run_test 77l "preferred checksum type is remembered after reconnected"
10024
10025 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10026 rm -f $F77_TMP
10027 unset F77_TMP
10028
10029 test_77m() {
10030         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10031                 skip "Need at least version 2.14.52"
10032         local param=checksum_speed
10033
10034         $LCTL get_param $param || error "reading $param failed"
10035
10036         csum_speeds=$($LCTL get_param -n $param)
10037
10038         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10039                 error "known checksum types are missing"
10040 }
10041 run_test 77m "Verify checksum_speed is correctly read"
10042
10043 check_filefrag_77n() {
10044         local nr_ext=0
10045         local starts=()
10046         local ends=()
10047
10048         while read extidx a b start end rest; do
10049                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10050                         nr_ext=$(( $nr_ext + 1 ))
10051                         starts+=( ${start%..} )
10052                         ends+=( ${end%:} )
10053                 fi
10054         done < <( filefrag -sv $1 )
10055
10056         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10057         return 1
10058 }
10059
10060 test_77n() {
10061         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10062
10063         touch $DIR/$tfile
10064         $TRUNCATE $DIR/$tfile 0
10065         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10066         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10067         check_filefrag_77n $DIR/$tfile ||
10068                 skip "$tfile blocks not contiguous around hole"
10069
10070         set_checksums 1
10071         stack_trap "set_checksums $ORIG_CSUM" EXIT
10072         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10073         stack_trap "rm -f $DIR/$tfile"
10074
10075         for algo in $CKSUM_TYPES; do
10076                 if [[ "$algo" =~ ^t10 ]]; then
10077                         set_checksum_type $algo ||
10078                                 error "fail to set checksum type $algo"
10079                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10080                                 error "fail to read $tfile with $algo"
10081                 fi
10082         done
10083         rm -f $DIR/$tfile
10084         return 0
10085 }
10086 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10087
10088 test_77o() {
10089         (( $CLIENT_VERSION >= $(version_code 2.14.54) )) ||
10090                 skip "Need at least version 2.14.54"
10091         local ofd=obdfilter
10092         local mdt=mdt
10093
10094         # print OST checksum_type
10095         echo "$ofd.$FSNAME-*.checksum_type:"
10096         do_nodes $(comma_list $(osts_nodes)) \
10097                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10098
10099         # print MDT checksum_type
10100         echo "$mdt.$FSNAME-*.checksum_type:"
10101         do_nodes $(comma_list $(mdts_nodes)) \
10102                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10103
10104         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10105                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10106
10107         (( $o_count == $OSTCOUNT )) ||
10108                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10109
10110         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10111                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10112
10113         (( $m_count == $MDSCOUNT )) ||
10114                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10115 }
10116 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10117
10118 cleanup_test_78() {
10119         trap 0
10120         rm -f $DIR/$tfile
10121 }
10122
10123 test_78() { # bug 10901
10124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10125         remote_ost || skip_env "local OST"
10126
10127         NSEQ=5
10128         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10129         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10130         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10131         echo "MemTotal: $MEMTOTAL"
10132
10133         # reserve 256MB of memory for the kernel and other running processes,
10134         # and then take 1/2 of the remaining memory for the read/write buffers.
10135         if [ $MEMTOTAL -gt 512 ] ;then
10136                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10137         else
10138                 # for those poor memory-starved high-end clusters...
10139                 MEMTOTAL=$((MEMTOTAL / 2))
10140         fi
10141         echo "Mem to use for directio: $MEMTOTAL"
10142
10143         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10144         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10145         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10146         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10147                 head -n1)
10148         echo "Smallest OST: $SMALLESTOST"
10149         [[ $SMALLESTOST -lt 10240 ]] &&
10150                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10151
10152         trap cleanup_test_78 EXIT
10153
10154         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10155                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10156
10157         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10158         echo "File size: $F78SIZE"
10159         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10160         for i in $(seq 1 $NSEQ); do
10161                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10162                 echo directIO rdwr round $i of $NSEQ
10163                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10164         done
10165
10166         cleanup_test_78
10167 }
10168 run_test 78 "handle large O_DIRECT writes correctly ============"
10169
10170 test_79() { # bug 12743
10171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10172
10173         wait_delete_completed
10174
10175         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10176         BKFREE=$(calc_osc_kbytes kbytesfree)
10177         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10178
10179         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10180         DFTOTAL=`echo $STRING | cut -d, -f1`
10181         DFUSED=`echo $STRING  | cut -d, -f2`
10182         DFAVAIL=`echo $STRING | cut -d, -f3`
10183         DFFREE=$(($DFTOTAL - $DFUSED))
10184
10185         ALLOWANCE=$((64 * $OSTCOUNT))
10186
10187         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10188            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10189                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10190         fi
10191         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10192            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10193                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10194         fi
10195         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10196            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10197                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10198         fi
10199 }
10200 run_test 79 "df report consistency check ======================="
10201
10202 test_80() { # bug 10718
10203         remote_ost_nodsh && skip "remote OST with nodsh"
10204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10205
10206         # relax strong synchronous semantics for slow backends like ZFS
10207         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10208                 local soc="obdfilter.*.sync_lock_cancel"
10209                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10210
10211                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10212                 if [ -z "$save" ]; then
10213                         soc="obdfilter.*.sync_on_lock_cancel"
10214                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10215                 fi
10216
10217                 if [ "$save" != "never" ]; then
10218                         local hosts=$(comma_list $(osts_nodes))
10219
10220                         do_nodes $hosts $LCTL set_param $soc=never
10221                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10222                 fi
10223         fi
10224
10225         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10226         sync; sleep 1; sync
10227         local before=$(date +%s)
10228         cancel_lru_locks osc
10229         local after=$(date +%s)
10230         local diff=$((after - before))
10231         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10232
10233         rm -f $DIR/$tfile
10234 }
10235 run_test 80 "Page eviction is equally fast at high offsets too"
10236
10237 test_81a() { # LU-456
10238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10239         remote_ost_nodsh && skip "remote OST with nodsh"
10240
10241         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10242         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10243         do_facet ost1 lctl set_param fail_loc=0x80000228
10244
10245         # write should trigger a retry and success
10246         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10247         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10248         RC=$?
10249         if [ $RC -ne 0 ] ; then
10250                 error "write should success, but failed for $RC"
10251         fi
10252 }
10253 run_test 81a "OST should retry write when get -ENOSPC ==============="
10254
10255 test_81b() { # LU-456
10256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10257         remote_ost_nodsh && skip "remote OST with nodsh"
10258
10259         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10260         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10261         do_facet ost1 lctl set_param fail_loc=0x228
10262
10263         # write should retry several times and return -ENOSPC finally
10264         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10265         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10266         RC=$?
10267         ENOSPC=28
10268         if [ $RC -ne $ENOSPC ] ; then
10269                 error "dd should fail for -ENOSPC, but succeed."
10270         fi
10271 }
10272 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10273
10274 test_99() {
10275         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10276
10277         test_mkdir $DIR/$tdir.cvsroot
10278         chown $RUNAS_ID $DIR/$tdir.cvsroot
10279
10280         cd $TMP
10281         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10282
10283         cd /etc/init.d
10284         # some versions of cvs import exit(1) when asked to import links or
10285         # files they can't read.  ignore those files.
10286         local toignore=$(find . -type l -printf '-I %f\n' -o \
10287                          ! -perm /4 -printf '-I %f\n')
10288         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10289                 $tdir.reposname vtag rtag
10290
10291         cd $DIR
10292         test_mkdir $DIR/$tdir.reposname
10293         chown $RUNAS_ID $DIR/$tdir.reposname
10294         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10295
10296         cd $DIR/$tdir.reposname
10297         $RUNAS touch foo99
10298         $RUNAS cvs add -m 'addmsg' foo99
10299         $RUNAS cvs update
10300         $RUNAS cvs commit -m 'nomsg' foo99
10301         rm -fr $DIR/$tdir.cvsroot
10302 }
10303 run_test 99 "cvs strange file/directory operations"
10304
10305 test_100() {
10306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10307         [[ "$NETTYPE" =~ tcp ]] ||
10308                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10309         remote_ost_nodsh && skip "remote OST with nodsh"
10310         remote_mds_nodsh && skip "remote MDS with nodsh"
10311         remote_servers ||
10312                 skip "useless for local single node setup"
10313
10314         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10315                 [ "$PROT" != "tcp" ] && continue
10316                 RPORT=$(echo $REMOTE | cut -d: -f2)
10317                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10318
10319                 rc=0
10320                 LPORT=`echo $LOCAL | cut -d: -f2`
10321                 if [ $LPORT -ge 1024 ]; then
10322                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10323                         netstat -tna
10324                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10325                 fi
10326         done
10327         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10328 }
10329 run_test 100 "check local port using privileged port ==========="
10330
10331 function get_named_value()
10332 {
10333     local tag=$1
10334
10335     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10336 }
10337
10338 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10339                    awk '/^max_cached_mb/ { print $2 }')
10340
10341 cleanup_101a() {
10342         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10343         trap 0
10344 }
10345
10346 test_101a() {
10347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10348
10349         local s
10350         local discard
10351         local nreads=10000
10352         local cache_limit=32
10353
10354         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10355         trap cleanup_101a EXIT
10356         $LCTL set_param -n llite.*.read_ahead_stats=0
10357         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10358
10359         #
10360         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10361         #
10362         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10363         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10364
10365         discard=0
10366         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10367                    get_named_value 'read.but.discarded'); do
10368                         discard=$(($discard + $s))
10369         done
10370         cleanup_101a
10371
10372         $LCTL get_param osc.*-osc*.rpc_stats
10373         $LCTL get_param llite.*.read_ahead_stats
10374
10375         # Discard is generally zero, but sometimes a few random reads line up
10376         # and trigger larger readahead, which is wasted & leads to discards.
10377         if [[ $(($discard)) -gt $nreads ]]; then
10378                 error "too many ($discard) discarded pages"
10379         fi
10380         rm -f $DIR/$tfile || true
10381 }
10382 run_test 101a "check read-ahead for random reads"
10383
10384 setup_test101bc() {
10385         test_mkdir $DIR/$tdir
10386         local ssize=$1
10387         local FILE_LENGTH=$2
10388         STRIPE_OFFSET=0
10389
10390         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10391
10392         local list=$(comma_list $(osts_nodes))
10393         set_osd_param $list '' read_cache_enable 0
10394         set_osd_param $list '' writethrough_cache_enable 0
10395
10396         trap cleanup_test101bc EXIT
10397         # prepare the read-ahead file
10398         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10399
10400         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10401                                 count=$FILE_SIZE_MB 2> /dev/null
10402
10403 }
10404
10405 cleanup_test101bc() {
10406         trap 0
10407         rm -rf $DIR/$tdir
10408         rm -f $DIR/$tfile
10409
10410         local list=$(comma_list $(osts_nodes))
10411         set_osd_param $list '' read_cache_enable 1
10412         set_osd_param $list '' writethrough_cache_enable 1
10413 }
10414
10415 calc_total() {
10416         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10417 }
10418
10419 ra_check_101() {
10420         local READ_SIZE=$1
10421         local STRIPE_SIZE=$2
10422         local FILE_LENGTH=$3
10423         local RA_INC=1048576
10424         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10425         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10426                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10427         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10428                   get_named_value 'read.but.discarded' | calc_total)
10429         if [[ $DISCARD -gt $discard_limit ]]; then
10430                 $LCTL get_param llite.*.read_ahead_stats
10431                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10432         else
10433                 echo "Read-ahead success for size ${READ_SIZE}"
10434         fi
10435 }
10436
10437 test_101b() {
10438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10439         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10440
10441         local STRIPE_SIZE=1048576
10442         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10443
10444         if [ $SLOW == "yes" ]; then
10445                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10446         else
10447                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10448         fi
10449
10450         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10451
10452         # prepare the read-ahead file
10453         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10454         cancel_lru_locks osc
10455         for BIDX in 2 4 8 16 32 64 128 256
10456         do
10457                 local BSIZE=$((BIDX*4096))
10458                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10459                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10460                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10461                 $LCTL set_param -n llite.*.read_ahead_stats=0
10462                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10463                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10464                 cancel_lru_locks osc
10465                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10466         done
10467         cleanup_test101bc
10468         true
10469 }
10470 run_test 101b "check stride-io mode read-ahead ================="
10471
10472 test_101c() {
10473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10474
10475         local STRIPE_SIZE=1048576
10476         local FILE_LENGTH=$((STRIPE_SIZE*100))
10477         local nreads=10000
10478         local rsize=65536
10479         local osc_rpc_stats
10480
10481         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10482
10483         cancel_lru_locks osc
10484         $LCTL set_param osc.*.rpc_stats=0
10485         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10486         $LCTL get_param osc.*.rpc_stats
10487         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10488                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10489                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10490                 local size
10491
10492                 if [ $lines -le 20 ]; then
10493                         echo "continue debug"
10494                         continue
10495                 fi
10496                 for size in 1 2 4 8; do
10497                         local rpc=$(echo "$stats" |
10498                                     awk '($1 == "'$size':") {print $2; exit; }')
10499                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10500                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10501                 done
10502                 echo "$osc_rpc_stats check passed!"
10503         done
10504         cleanup_test101bc
10505         true
10506 }
10507 run_test 101c "check stripe_size aligned read-ahead"
10508
10509 test_101d() {
10510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10511
10512         local file=$DIR/$tfile
10513         local sz_MB=${FILESIZE_101d:-80}
10514         local ra_MB=${READAHEAD_MB:-40}
10515
10516         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10517         [ $free_MB -lt $sz_MB ] &&
10518                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10519
10520         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10521         $LFS setstripe -c -1 $file || error "setstripe failed"
10522
10523         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10524         echo Cancel LRU locks on lustre client to flush the client cache
10525         cancel_lru_locks osc
10526
10527         echo Disable read-ahead
10528         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10529         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10530         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10531         $LCTL get_param -n llite.*.max_read_ahead_mb
10532
10533         echo "Reading the test file $file with read-ahead disabled"
10534         local sz_KB=$((sz_MB * 1024 / 4))
10535         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10536         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10537         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10538                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10539
10540         echo "Cancel LRU locks on lustre client to flush the client cache"
10541         cancel_lru_locks osc
10542         echo Enable read-ahead with ${ra_MB}MB
10543         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10544
10545         echo "Reading the test file $file with read-ahead enabled"
10546         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10547                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10548
10549         echo "read-ahead disabled time read $raOFF"
10550         echo "read-ahead enabled time read $raON"
10551
10552         rm -f $file
10553         wait_delete_completed
10554
10555         # use awk for this check instead of bash because it handles decimals
10556         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10557                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10558 }
10559 run_test 101d "file read with and without read-ahead enabled"
10560
10561 test_101e() {
10562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10563
10564         local file=$DIR/$tfile
10565         local size_KB=500  #KB
10566         local count=100
10567         local bsize=1024
10568
10569         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10570         local need_KB=$((count * size_KB))
10571         [[ $free_KB -le $need_KB ]] &&
10572                 skip_env "Need free space $need_KB, have $free_KB"
10573
10574         echo "Creating $count ${size_KB}K test files"
10575         for ((i = 0; i < $count; i++)); do
10576                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10577         done
10578
10579         echo "Cancel LRU locks on lustre client to flush the client cache"
10580         cancel_lru_locks $OSC
10581
10582         echo "Reset readahead stats"
10583         $LCTL set_param -n llite.*.read_ahead_stats=0
10584
10585         for ((i = 0; i < $count; i++)); do
10586                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10587         done
10588
10589         $LCTL get_param llite.*.max_cached_mb
10590         $LCTL get_param llite.*.read_ahead_stats
10591         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10592                      get_named_value 'misses' | calc_total)
10593
10594         for ((i = 0; i < $count; i++)); do
10595                 rm -rf $file.$i 2>/dev/null
10596         done
10597
10598         #10000 means 20% reads are missing in readahead
10599         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10600 }
10601 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10602
10603 test_101f() {
10604         which iozone || skip_env "no iozone installed"
10605
10606         local old_debug=$($LCTL get_param debug)
10607         old_debug=${old_debug#*=}
10608         $LCTL set_param debug="reada mmap"
10609
10610         # create a test file
10611         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10612
10613         echo Cancel LRU locks on lustre client to flush the client cache
10614         cancel_lru_locks osc
10615
10616         echo Reset readahead stats
10617         $LCTL set_param -n llite.*.read_ahead_stats=0
10618
10619         echo mmap read the file with small block size
10620         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10621                 > /dev/null 2>&1
10622
10623         echo checking missing pages
10624         $LCTL get_param llite.*.read_ahead_stats
10625         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10626                         get_named_value 'misses' | calc_total)
10627
10628         $LCTL set_param debug="$old_debug"
10629         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10630         rm -f $DIR/$tfile
10631 }
10632 run_test 101f "check mmap read performance"
10633
10634 test_101g_brw_size_test() {
10635         local mb=$1
10636         local pages=$((mb * 1048576 / PAGE_SIZE))
10637         local file=$DIR/$tfile
10638
10639         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10640                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10641         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10642                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10643                         return 2
10644         done
10645
10646         stack_trap "rm -f $file" EXIT
10647         $LCTL set_param -n osc.*.rpc_stats=0
10648
10649         # 10 RPCs should be enough for the test
10650         local count=10
10651         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10652                 { error "dd write ${mb} MB blocks failed"; return 3; }
10653         cancel_lru_locks osc
10654         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10655                 { error "dd write ${mb} MB blocks failed"; return 4; }
10656
10657         # calculate number of full-sized read and write RPCs
10658         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10659                 sed -n '/pages per rpc/,/^$/p' |
10660                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10661                 END { print reads,writes }'))
10662         # allow one extra full-sized read RPC for async readahead
10663         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10664                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10665         [[ ${rpcs[1]} == $count ]] ||
10666                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10667 }
10668
10669 test_101g() {
10670         remote_ost_nodsh && skip "remote OST with nodsh"
10671
10672         local rpcs
10673         local osts=$(get_facets OST)
10674         local list=$(comma_list $(osts_nodes))
10675         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10676         local brw_size="obdfilter.*.brw_size"
10677
10678         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10679
10680         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10681
10682         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10683                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10684                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10685            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10686                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10687                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10688
10689                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10690                         suffix="M"
10691
10692                 if [[ $orig_mb -lt 16 ]]; then
10693                         save_lustre_params $osts "$brw_size" > $p
10694                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10695                                 error "set 16MB RPC size failed"
10696
10697                         echo "remount client to enable new RPC size"
10698                         remount_client $MOUNT || error "remount_client failed"
10699                 fi
10700
10701                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10702                 # should be able to set brw_size=12, but no rpc_stats for that
10703                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10704         fi
10705
10706         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10707
10708         if [[ $orig_mb -lt 16 ]]; then
10709                 restore_lustre_params < $p
10710                 remount_client $MOUNT || error "remount_client restore failed"
10711         fi
10712
10713         rm -f $p $DIR/$tfile
10714 }
10715 run_test 101g "Big bulk(4/16 MiB) readahead"
10716
10717 test_101h() {
10718         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10719
10720         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10721                 error "dd 70M file failed"
10722         echo Cancel LRU locks on lustre client to flush the client cache
10723         cancel_lru_locks osc
10724
10725         echo "Reset readahead stats"
10726         $LCTL set_param -n llite.*.read_ahead_stats 0
10727
10728         echo "Read 10M of data but cross 64M bundary"
10729         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10730         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10731                      get_named_value 'misses' | calc_total)
10732         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10733         rm -f $p $DIR/$tfile
10734 }
10735 run_test 101h "Readahead should cover current read window"
10736
10737 test_101i() {
10738         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10739                 error "dd 10M file failed"
10740
10741         local max_per_file_mb=$($LCTL get_param -n \
10742                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10743         cancel_lru_locks osc
10744         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10745         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10746                 error "set max_read_ahead_per_file_mb to 1 failed"
10747
10748         echo "Reset readahead stats"
10749         $LCTL set_param llite.*.read_ahead_stats=0
10750
10751         dd if=$DIR/$tfile of=/dev/null bs=2M
10752
10753         $LCTL get_param llite.*.read_ahead_stats
10754         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10755                      awk '/misses/ { print $2 }')
10756         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10757         rm -f $DIR/$tfile
10758 }
10759 run_test 101i "allow current readahead to exceed reservation"
10760
10761 test_101j() {
10762         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10763                 error "setstripe $DIR/$tfile failed"
10764         local file_size=$((1048576 * 16))
10765         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10766         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10767
10768         echo Disable read-ahead
10769         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10770
10771         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10772         for blk in $PAGE_SIZE 1048576 $file_size; do
10773                 cancel_lru_locks osc
10774                 echo "Reset readahead stats"
10775                 $LCTL set_param -n llite.*.read_ahead_stats=0
10776                 local count=$(($file_size / $blk))
10777                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10778                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10779                              get_named_value 'failed.to.fast.read' | calc_total)
10780                 $LCTL get_param -n llite.*.read_ahead_stats
10781                 [ $miss -eq $count ] || error "expected $count got $miss"
10782         done
10783
10784         rm -f $p $DIR/$tfile
10785 }
10786 run_test 101j "A complete read block should be submitted when no RA"
10787
10788 setup_test102() {
10789         test_mkdir $DIR/$tdir
10790         chown $RUNAS_ID $DIR/$tdir
10791         STRIPE_SIZE=65536
10792         STRIPE_OFFSET=1
10793         STRIPE_COUNT=$OSTCOUNT
10794         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10795
10796         trap cleanup_test102 EXIT
10797         cd $DIR
10798         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10799         cd $DIR/$tdir
10800         for num in 1 2 3 4; do
10801                 for count in $(seq 1 $STRIPE_COUNT); do
10802                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10803                                 local size=`expr $STRIPE_SIZE \* $num`
10804                                 local file=file"$num-$idx-$count"
10805                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10806                         done
10807                 done
10808         done
10809
10810         cd $DIR
10811         $1 tar cf $TMP/f102.tar $tdir --xattrs
10812 }
10813
10814 cleanup_test102() {
10815         trap 0
10816         rm -f $TMP/f102.tar
10817         rm -rf $DIR/d0.sanity/d102
10818 }
10819
10820 test_102a() {
10821         [ "$UID" != 0 ] && skip "must run as root"
10822         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10823                 skip_env "must have user_xattr"
10824
10825         [ -z "$(which setfattr 2>/dev/null)" ] &&
10826                 skip_env "could not find setfattr"
10827
10828         local testfile=$DIR/$tfile
10829
10830         touch $testfile
10831         echo "set/get xattr..."
10832         setfattr -n trusted.name1 -v value1 $testfile ||
10833                 error "setfattr -n trusted.name1=value1 $testfile failed"
10834         getfattr -n trusted.name1 $testfile 2> /dev/null |
10835           grep "trusted.name1=.value1" ||
10836                 error "$testfile missing trusted.name1=value1"
10837
10838         setfattr -n user.author1 -v author1 $testfile ||
10839                 error "setfattr -n user.author1=author1 $testfile failed"
10840         getfattr -n user.author1 $testfile 2> /dev/null |
10841           grep "user.author1=.author1" ||
10842                 error "$testfile missing trusted.author1=author1"
10843
10844         echo "listxattr..."
10845         setfattr -n trusted.name2 -v value2 $testfile ||
10846                 error "$testfile unable to set trusted.name2"
10847         setfattr -n trusted.name3 -v value3 $testfile ||
10848                 error "$testfile unable to set trusted.name3"
10849         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10850             grep "trusted.name" | wc -l) -eq 3 ] ||
10851                 error "$testfile missing 3 trusted.name xattrs"
10852
10853         setfattr -n user.author2 -v author2 $testfile ||
10854                 error "$testfile unable to set user.author2"
10855         setfattr -n user.author3 -v author3 $testfile ||
10856                 error "$testfile unable to set user.author3"
10857         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10858             grep "user.author" | wc -l) -eq 3 ] ||
10859                 error "$testfile missing 3 user.author xattrs"
10860
10861         echo "remove xattr..."
10862         setfattr -x trusted.name1 $testfile ||
10863                 error "$testfile error deleting trusted.name1"
10864         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10865                 error "$testfile did not delete trusted.name1 xattr"
10866
10867         setfattr -x user.author1 $testfile ||
10868                 error "$testfile error deleting user.author1"
10869         echo "set lustre special xattr ..."
10870         $LFS setstripe -c1 $testfile
10871         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10872                 awk -F "=" '/trusted.lov/ { print $2 }' )
10873         setfattr -n "trusted.lov" -v $lovea $testfile ||
10874                 error "$testfile doesn't ignore setting trusted.lov again"
10875         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10876                 error "$testfile allow setting invalid trusted.lov"
10877         rm -f $testfile
10878 }
10879 run_test 102a "user xattr test =================================="
10880
10881 check_102b_layout() {
10882         local layout="$*"
10883         local testfile=$DIR/$tfile
10884
10885         echo "test layout '$layout'"
10886         $LFS setstripe $layout $testfile || error "setstripe failed"
10887         $LFS getstripe -y $testfile
10888
10889         echo "get/set/list trusted.lov xattr ..." # b=10930
10890         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10891         [[ "$value" =~ "trusted.lov" ]] ||
10892                 error "can't get trusted.lov from $testfile"
10893         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10894                 error "getstripe failed"
10895
10896         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10897
10898         value=$(cut -d= -f2 <<<$value)
10899         # LU-13168: truncated xattr should fail if short lov_user_md header
10900         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10901                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10902         for len in $lens; do
10903                 echo "setfattr $len $testfile.2"
10904                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10905                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10906         done
10907         local stripe_size=$($LFS getstripe -S $testfile.2)
10908         local stripe_count=$($LFS getstripe -c $testfile.2)
10909         [[ $stripe_size -eq 65536 ]] ||
10910                 error "stripe size $stripe_size != 65536"
10911         [[ $stripe_count -eq $stripe_count_orig ]] ||
10912                 error "stripe count $stripe_count != $stripe_count_orig"
10913         rm $testfile $testfile.2
10914 }
10915
10916 test_102b() {
10917         [ -z "$(which setfattr 2>/dev/null)" ] &&
10918                 skip_env "could not find setfattr"
10919         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10920
10921         # check plain layout
10922         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10923
10924         # and also check composite layout
10925         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10926
10927 }
10928 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10929
10930 test_102c() {
10931         [ -z "$(which setfattr 2>/dev/null)" ] &&
10932                 skip_env "could not find setfattr"
10933         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10934
10935         # b10930: get/set/list lustre.lov xattr
10936         echo "get/set/list lustre.lov xattr ..."
10937         test_mkdir $DIR/$tdir
10938         chown $RUNAS_ID $DIR/$tdir
10939         local testfile=$DIR/$tdir/$tfile
10940         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10941                 error "setstripe failed"
10942         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10943                 error "getstripe failed"
10944         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10945         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10946
10947         local testfile2=${testfile}2
10948         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10949                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10950
10951         $RUNAS $MCREATE $testfile2
10952         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10953         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10954         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10955         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10956         [ $stripe_count -eq $STRIPECOUNT ] ||
10957                 error "stripe count $stripe_count != $STRIPECOUNT"
10958 }
10959 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10960
10961 compare_stripe_info1() {
10962         local stripe_index_all_zero=true
10963
10964         for num in 1 2 3 4; do
10965                 for count in $(seq 1 $STRIPE_COUNT); do
10966                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10967                                 local size=$((STRIPE_SIZE * num))
10968                                 local file=file"$num-$offset-$count"
10969                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10970                                 [[ $stripe_size -ne $size ]] &&
10971                                     error "$file: size $stripe_size != $size"
10972                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10973                                 # allow fewer stripes to be created, ORI-601
10974                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10975                                     error "$file: count $stripe_count != $count"
10976                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10977                                 [[ $stripe_index -ne 0 ]] &&
10978                                         stripe_index_all_zero=false
10979                         done
10980                 done
10981         done
10982         $stripe_index_all_zero &&
10983                 error "all files are being extracted starting from OST index 0"
10984         return 0
10985 }
10986
10987 have_xattrs_include() {
10988         tar --help | grep -q xattrs-include &&
10989                 echo --xattrs-include="lustre.*"
10990 }
10991
10992 test_102d() {
10993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10994         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10995
10996         XINC=$(have_xattrs_include)
10997         setup_test102
10998         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10999         cd $DIR/$tdir/$tdir
11000         compare_stripe_info1
11001 }
11002 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11003
11004 test_102f() {
11005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11006         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11007
11008         XINC=$(have_xattrs_include)
11009         setup_test102
11010         test_mkdir $DIR/$tdir.restore
11011         cd $DIR
11012         tar cf - --xattrs $tdir | tar xf - \
11013                 -C $DIR/$tdir.restore --xattrs $XINC
11014         cd $DIR/$tdir.restore/$tdir
11015         compare_stripe_info1
11016 }
11017 run_test 102f "tar copy files, not keep osts"
11018
11019 grow_xattr() {
11020         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11021                 skip "must have user_xattr"
11022         [ -z "$(which setfattr 2>/dev/null)" ] &&
11023                 skip_env "could not find setfattr"
11024         [ -z "$(which getfattr 2>/dev/null)" ] &&
11025                 skip_env "could not find getfattr"
11026
11027         local xsize=${1:-1024}  # in bytes
11028         local file=$DIR/$tfile
11029         local value="$(generate_string $xsize)"
11030         local xbig=trusted.big
11031         local toobig=$2
11032
11033         touch $file
11034         log "save $xbig on $file"
11035         if [ -z "$toobig" ]
11036         then
11037                 setfattr -n $xbig -v $value $file ||
11038                         error "saving $xbig on $file failed"
11039         else
11040                 setfattr -n $xbig -v $value $file &&
11041                         error "saving $xbig on $file succeeded"
11042                 return 0
11043         fi
11044
11045         local orig=$(get_xattr_value $xbig $file)
11046         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11047
11048         local xsml=trusted.sml
11049         log "save $xsml on $file"
11050         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11051
11052         local new=$(get_xattr_value $xbig $file)
11053         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11054
11055         log "grow $xsml on $file"
11056         setfattr -n $xsml -v "$value" $file ||
11057                 error "growing $xsml on $file failed"
11058
11059         new=$(get_xattr_value $xbig $file)
11060         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11061         log "$xbig still valid after growing $xsml"
11062
11063         rm -f $file
11064 }
11065
11066 test_102h() { # bug 15777
11067         grow_xattr 1024
11068 }
11069 run_test 102h "grow xattr from inside inode to external block"
11070
11071 test_102ha() {
11072         large_xattr_enabled || skip_env "ea_inode feature disabled"
11073
11074         echo "setting xattr of max xattr size: $(max_xattr_size)"
11075         grow_xattr $(max_xattr_size)
11076
11077         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11078         echo "This should fail:"
11079         grow_xattr $(($(max_xattr_size) + 10)) 1
11080 }
11081 run_test 102ha "grow xattr from inside inode to external inode"
11082
11083 test_102i() { # bug 17038
11084         [ -z "$(which getfattr 2>/dev/null)" ] &&
11085                 skip "could not find getfattr"
11086
11087         touch $DIR/$tfile
11088         ln -s $DIR/$tfile $DIR/${tfile}link
11089         getfattr -n trusted.lov $DIR/$tfile ||
11090                 error "lgetxattr on $DIR/$tfile failed"
11091         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11092                 grep -i "no such attr" ||
11093                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11094         rm -f $DIR/$tfile $DIR/${tfile}link
11095 }
11096 run_test 102i "lgetxattr test on symbolic link ============"
11097
11098 test_102j() {
11099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11100         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11101
11102         XINC=$(have_xattrs_include)
11103         setup_test102 "$RUNAS"
11104         chown $RUNAS_ID $DIR/$tdir
11105         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11106         cd $DIR/$tdir/$tdir
11107         compare_stripe_info1 "$RUNAS"
11108 }
11109 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11110
11111 test_102k() {
11112         [ -z "$(which setfattr 2>/dev/null)" ] &&
11113                 skip "could not find setfattr"
11114
11115         touch $DIR/$tfile
11116         # b22187 just check that does not crash for regular file.
11117         setfattr -n trusted.lov $DIR/$tfile
11118         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11119         local test_kdir=$DIR/$tdir
11120         test_mkdir $test_kdir
11121         local default_size=$($LFS getstripe -S $test_kdir)
11122         local default_count=$($LFS getstripe -c $test_kdir)
11123         local default_offset=$($LFS getstripe -i $test_kdir)
11124         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11125                 error 'dir setstripe failed'
11126         setfattr -n trusted.lov $test_kdir
11127         local stripe_size=$($LFS getstripe -S $test_kdir)
11128         local stripe_count=$($LFS getstripe -c $test_kdir)
11129         local stripe_offset=$($LFS getstripe -i $test_kdir)
11130         [ $stripe_size -eq $default_size ] ||
11131                 error "stripe size $stripe_size != $default_size"
11132         [ $stripe_count -eq $default_count ] ||
11133                 error "stripe count $stripe_count != $default_count"
11134         [ $stripe_offset -eq $default_offset ] ||
11135                 error "stripe offset $stripe_offset != $default_offset"
11136         rm -rf $DIR/$tfile $test_kdir
11137 }
11138 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11139
11140 test_102l() {
11141         [ -z "$(which getfattr 2>/dev/null)" ] &&
11142                 skip "could not find getfattr"
11143
11144         # LU-532 trusted. xattr is invisible to non-root
11145         local testfile=$DIR/$tfile
11146
11147         touch $testfile
11148
11149         echo "listxattr as user..."
11150         chown $RUNAS_ID $testfile
11151         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11152             grep -q "trusted" &&
11153                 error "$testfile trusted xattrs are user visible"
11154
11155         return 0;
11156 }
11157 run_test 102l "listxattr size test =================================="
11158
11159 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11160         local path=$DIR/$tfile
11161         touch $path
11162
11163         listxattr_size_check $path || error "listattr_size_check $path failed"
11164 }
11165 run_test 102m "Ensure listxattr fails on small bufffer ========"
11166
11167 cleanup_test102
11168
11169 getxattr() { # getxattr path name
11170         # Return the base64 encoding of the value of xattr name on path.
11171         local path=$1
11172         local name=$2
11173
11174         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11175         # file: $path
11176         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11177         #
11178         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11179
11180         getfattr --absolute-names --encoding=base64 --name=$name $path |
11181                 awk -F= -v name=$name '$1 == name {
11182                         print substr($0, index($0, "=") + 1);
11183         }'
11184 }
11185
11186 test_102n() { # LU-4101 mdt: protect internal xattrs
11187         [ -z "$(which setfattr 2>/dev/null)" ] &&
11188                 skip "could not find setfattr"
11189         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11190         then
11191                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11192         fi
11193
11194         local file0=$DIR/$tfile.0
11195         local file1=$DIR/$tfile.1
11196         local xattr0=$TMP/$tfile.0
11197         local xattr1=$TMP/$tfile.1
11198         local namelist="lov lma lmv link fid version som hsm"
11199         local name
11200         local value
11201
11202         rm -rf $file0 $file1 $xattr0 $xattr1
11203         touch $file0 $file1
11204
11205         # Get 'before' xattrs of $file1.
11206         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11207
11208         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11209                 namelist+=" lfsck_namespace"
11210         for name in $namelist; do
11211                 # Try to copy xattr from $file0 to $file1.
11212                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11213
11214                 setfattr --name=trusted.$name --value="$value" $file1 ||
11215                         error "setxattr 'trusted.$name' failed"
11216
11217                 # Try to set a garbage xattr.
11218                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11219
11220                 if [[ x$name == "xlov" ]]; then
11221                         setfattr --name=trusted.lov --value="$value" $file1 &&
11222                         error "setxattr invalid 'trusted.lov' success"
11223                 else
11224                         setfattr --name=trusted.$name --value="$value" $file1 ||
11225                                 error "setxattr invalid 'trusted.$name' failed"
11226                 fi
11227
11228                 # Try to remove the xattr from $file1. We don't care if this
11229                 # appears to succeed or fail, we just don't want there to be
11230                 # any changes or crashes.
11231                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11232         done
11233
11234         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11235         then
11236                 name="lfsck_ns"
11237                 # Try to copy xattr from $file0 to $file1.
11238                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11239
11240                 setfattr --name=trusted.$name --value="$value" $file1 ||
11241                         error "setxattr 'trusted.$name' failed"
11242
11243                 # Try to set a garbage xattr.
11244                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11245
11246                 setfattr --name=trusted.$name --value="$value" $file1 ||
11247                         error "setxattr 'trusted.$name' failed"
11248
11249                 # Try to remove the xattr from $file1. We don't care if this
11250                 # appears to succeed or fail, we just don't want there to be
11251                 # any changes or crashes.
11252                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11253         fi
11254
11255         # Get 'after' xattrs of file1.
11256         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11257
11258         if ! diff $xattr0 $xattr1; then
11259                 error "before and after xattrs of '$file1' differ"
11260         fi
11261
11262         rm -rf $file0 $file1 $xattr0 $xattr1
11263
11264         return 0
11265 }
11266 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11267
11268 test_102p() { # LU-4703 setxattr did not check ownership
11269         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11270                 skip "MDS needs to be at least 2.5.56"
11271
11272         local testfile=$DIR/$tfile
11273
11274         touch $testfile
11275
11276         echo "setfacl as user..."
11277         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11278         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11279
11280         echo "setfattr as user..."
11281         setfacl -m "u:$RUNAS_ID:---" $testfile
11282         $RUNAS setfattr -x system.posix_acl_access $testfile
11283         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11284 }
11285 run_test 102p "check setxattr(2) correctly fails without permission"
11286
11287 test_102q() {
11288         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11289                 skip "MDS needs to be at least 2.6.92"
11290
11291         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11292 }
11293 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11294
11295 test_102r() {
11296         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11297                 skip "MDS needs to be at least 2.6.93"
11298
11299         touch $DIR/$tfile || error "touch"
11300         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11301         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11302         rm $DIR/$tfile || error "rm"
11303
11304         #normal directory
11305         mkdir -p $DIR/$tdir || error "mkdir"
11306         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11307         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11308         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11309                 error "$testfile error deleting user.author1"
11310         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11311                 grep "user.$(basename $tdir)" &&
11312                 error "$tdir did not delete user.$(basename $tdir)"
11313         rmdir $DIR/$tdir || error "rmdir"
11314
11315         #striped directory
11316         test_mkdir $DIR/$tdir
11317         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11318         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11319         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11320                 error "$testfile error deleting user.author1"
11321         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11322                 grep "user.$(basename $tdir)" &&
11323                 error "$tdir did not delete user.$(basename $tdir)"
11324         rmdir $DIR/$tdir || error "rm striped dir"
11325 }
11326 run_test 102r "set EAs with empty values"
11327
11328 test_102s() {
11329         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11330                 skip "MDS needs to be at least 2.11.52"
11331
11332         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11333
11334         save_lustre_params client "llite.*.xattr_cache" > $save
11335
11336         for cache in 0 1; do
11337                 lctl set_param llite.*.xattr_cache=$cache
11338
11339                 rm -f $DIR/$tfile
11340                 touch $DIR/$tfile || error "touch"
11341                 for prefix in lustre security system trusted user; do
11342                         # Note getxattr() may fail with 'Operation not
11343                         # supported' or 'No such attribute' depending
11344                         # on prefix and cache.
11345                         getfattr -n $prefix.n102s $DIR/$tfile &&
11346                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11347                 done
11348         done
11349
11350         restore_lustre_params < $save
11351 }
11352 run_test 102s "getting nonexistent xattrs should fail"
11353
11354 test_102t() {
11355         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11356                 skip "MDS needs to be at least 2.11.52"
11357
11358         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11359
11360         save_lustre_params client "llite.*.xattr_cache" > $save
11361
11362         for cache in 0 1; do
11363                 lctl set_param llite.*.xattr_cache=$cache
11364
11365                 for buf_size in 0 256; do
11366                         rm -f $DIR/$tfile
11367                         touch $DIR/$tfile || error "touch"
11368                         setfattr -n user.multiop $DIR/$tfile
11369                         $MULTIOP $DIR/$tfile oa$buf_size ||
11370                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11371                 done
11372         done
11373
11374         restore_lustre_params < $save
11375 }
11376 run_test 102t "zero length xattr values handled correctly"
11377
11378 run_acl_subtest()
11379 {
11380     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11381     return $?
11382 }
11383
11384 test_103a() {
11385         [ "$UID" != 0 ] && skip "must run as root"
11386         $GSS && skip_env "could not run under gss"
11387         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11388                 skip_env "must have acl enabled"
11389         [ -z "$(which setfacl 2>/dev/null)" ] &&
11390                 skip_env "could not find setfacl"
11391         remote_mds_nodsh && skip "remote MDS with nodsh"
11392
11393         gpasswd -a daemon bin                           # LU-5641
11394         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11395
11396         declare -a identity_old
11397
11398         for num in $(seq $MDSCOUNT); do
11399                 switch_identity $num true || identity_old[$num]=$?
11400         done
11401
11402         SAVE_UMASK=$(umask)
11403         umask 0022
11404         mkdir -p $DIR/$tdir
11405         cd $DIR/$tdir
11406
11407         echo "performing cp ..."
11408         run_acl_subtest cp || error "run_acl_subtest cp failed"
11409         echo "performing getfacl-noacl..."
11410         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11411         echo "performing misc..."
11412         run_acl_subtest misc || error  "misc test failed"
11413         echo "performing permissions..."
11414         run_acl_subtest permissions || error "permissions failed"
11415         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11416         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11417                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11418                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11419         then
11420                 echo "performing permissions xattr..."
11421                 run_acl_subtest permissions_xattr ||
11422                         error "permissions_xattr failed"
11423         fi
11424         echo "performing setfacl..."
11425         run_acl_subtest setfacl || error  "setfacl test failed"
11426
11427         # inheritance test got from HP
11428         echo "performing inheritance..."
11429         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11430         chmod +x make-tree || error "chmod +x failed"
11431         run_acl_subtest inheritance || error "inheritance test failed"
11432         rm -f make-tree
11433
11434         echo "LU-974 ignore umask when acl is enabled..."
11435         run_acl_subtest 974 || error "LU-974 umask test failed"
11436         if [ $MDSCOUNT -ge 2 ]; then
11437                 run_acl_subtest 974_remote ||
11438                         error "LU-974 umask test failed under remote dir"
11439         fi
11440
11441         echo "LU-2561 newly created file is same size as directory..."
11442         if [ "$mds1_FSTYPE" != "zfs" ]; then
11443                 run_acl_subtest 2561 || error "LU-2561 test failed"
11444         else
11445                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11446         fi
11447
11448         run_acl_subtest 4924 || error "LU-4924 test failed"
11449
11450         cd $SAVE_PWD
11451         umask $SAVE_UMASK
11452
11453         for num in $(seq $MDSCOUNT); do
11454                 if [ "${identity_old[$num]}" = 1 ]; then
11455                         switch_identity $num false || identity_old[$num]=$?
11456                 fi
11457         done
11458 }
11459 run_test 103a "acl test"
11460
11461 test_103b() {
11462         declare -a pids
11463         local U
11464
11465         for U in {0..511}; do
11466                 {
11467                 local O=$(printf "%04o" $U)
11468
11469                 umask $(printf "%04o" $((511 ^ $O)))
11470                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11471                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11472
11473                 (( $S == ($O & 0666) )) ||
11474                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11475
11476                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11477                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11478                 (( $S == ($O & 0666) )) ||
11479                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11480
11481                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11482                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11483                 (( $S == ($O & 0666) )) ||
11484                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11485                 rm -f $DIR/$tfile.[smp]$0
11486                 } &
11487                 local pid=$!
11488
11489                 # limit the concurrently running threads to 64. LU-11878
11490                 local idx=$((U % 64))
11491                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11492                 pids[idx]=$pid
11493         done
11494         wait
11495 }
11496 run_test 103b "umask lfs setstripe"
11497
11498 test_103c() {
11499         mkdir -p $DIR/$tdir
11500         cp -rp $DIR/$tdir $DIR/$tdir.bak
11501
11502         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11503                 error "$DIR/$tdir shouldn't contain default ACL"
11504         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11505                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11506         true
11507 }
11508 run_test 103c "'cp -rp' won't set empty acl"
11509
11510 test_103e() {
11511         local numacl
11512         local fileacl
11513         local saved_debug=$($LCTL get_param -n debug)
11514
11515         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11516                 skip "MDS needs to be at least 2.14.0"
11517
11518         large_xattr_enabled || skip_env "ea_inode feature disabled"
11519
11520         mkdir -p $DIR/$tdir
11521         # add big LOV EA to cause reply buffer overflow earlier
11522         $LFS setstripe -C 1000 $DIR/$tdir
11523         lctl set_param mdc.*-mdc*.stats=clear
11524
11525         $LCTL set_param debug=0
11526         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11527         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11528
11529         # add a large number of default ACLs (expect 8000+ for 2.13+)
11530         for U in {2..7000}; do
11531                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11532                         error "Able to add just $U default ACLs"
11533         done
11534         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11535         echo "$numacl default ACLs created"
11536
11537         stat $DIR/$tdir || error "Cannot stat directory"
11538         # check file creation
11539         touch $DIR/$tdir/$tfile ||
11540                 error "failed to create $tfile with $numacl default ACLs"
11541         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11542         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11543         echo "$fileacl ACLs were inherited"
11544         (( $fileacl == $numacl )) ||
11545                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11546         # check that new ACLs creation adds new ACLs to inherited ACLs
11547         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11548                 error "Cannot set new ACL"
11549         numacl=$((numacl + 1))
11550         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11551         (( $fileacl == $numacl )) ||
11552                 error "failed to add new ACL: $fileacl != $numacl as expected"
11553         # adds more ACLs to a file to reach their maximum at 8000+
11554         numacl=0
11555         for U in {20000..25000}; do
11556                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11557                 numacl=$((numacl + 1))
11558         done
11559         echo "Added $numacl more ACLs to the file"
11560         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11561         echo "Total $fileacl ACLs in file"
11562         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11563         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11564         rmdir $DIR/$tdir || error "Cannot remove directory"
11565 }
11566 run_test 103e "inheritance of big amount of default ACLs"
11567
11568 test_103f() {
11569         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11570                 skip "MDS needs to be at least 2.14.51"
11571
11572         large_xattr_enabled || skip_env "ea_inode feature disabled"
11573
11574         # enable changelog to consume more internal MDD buffers
11575         changelog_register
11576
11577         mkdir -p $DIR/$tdir
11578         # add big LOV EA
11579         $LFS setstripe -C 1000 $DIR/$tdir
11580         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11581         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11582         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11583         rmdir $DIR/$tdir || error "Cannot remove directory"
11584 }
11585 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11586
11587 test_104a() {
11588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11589
11590         touch $DIR/$tfile
11591         lfs df || error "lfs df failed"
11592         lfs df -ih || error "lfs df -ih failed"
11593         lfs df -h $DIR || error "lfs df -h $DIR failed"
11594         lfs df -i $DIR || error "lfs df -i $DIR failed"
11595         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11596         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11597
11598         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11599         lctl --device %$OSC deactivate
11600         lfs df || error "lfs df with deactivated OSC failed"
11601         lctl --device %$OSC activate
11602         # wait the osc back to normal
11603         wait_osc_import_ready client ost
11604
11605         lfs df || error "lfs df with reactivated OSC failed"
11606         rm -f $DIR/$tfile
11607 }
11608 run_test 104a "lfs df [-ih] [path] test ========================="
11609
11610 test_104b() {
11611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11612         [ $RUNAS_ID -eq $UID ] &&
11613                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11614
11615         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11616                         grep "Permission denied" | wc -l)))
11617         if [ $denied_cnt -ne 0 ]; then
11618                 error "lfs check servers test failed"
11619         fi
11620 }
11621 run_test 104b "$RUNAS lfs check servers test ===================="
11622
11623 #
11624 # Verify $1 is within range of $2.
11625 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11626 # $1 is <= 2% of $2. Else Fail.
11627 #
11628 value_in_range() {
11629         # Strip all units (M, G, T)
11630         actual=$(echo $1 | tr -d A-Z)
11631         expect=$(echo $2 | tr -d A-Z)
11632
11633         expect_lo=$(($expect * 98 / 100)) # 2% below
11634         expect_hi=$(($expect * 102 / 100)) # 2% above
11635
11636         # permit 2% drift above and below
11637         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11638 }
11639
11640 test_104c() {
11641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11642         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11643
11644         local ost_param="osd-zfs.$FSNAME-OST0000."
11645         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11646         local ofacets=$(get_facets OST)
11647         local mfacets=$(get_facets MDS)
11648         local saved_ost_blocks=
11649         local saved_mdt_blocks=
11650
11651         echo "Before recordsize change"
11652         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11653         df=($(df -h | grep "/mnt/lustre"$))
11654
11655         # For checking.
11656         echo "lfs output : ${lfs_df[*]}"
11657         echo "df  output : ${df[*]}"
11658
11659         for facet in ${ofacets//,/ }; do
11660                 if [ -z $saved_ost_blocks ]; then
11661                         saved_ost_blocks=$(do_facet $facet \
11662                                 lctl get_param -n $ost_param.blocksize)
11663                         echo "OST Blocksize: $saved_ost_blocks"
11664                 fi
11665                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11666                 do_facet $facet zfs set recordsize=32768 $ost
11667         done
11668
11669         # BS too small. Sufficient for functional testing.
11670         for facet in ${mfacets//,/ }; do
11671                 if [ -z $saved_mdt_blocks ]; then
11672                         saved_mdt_blocks=$(do_facet $facet \
11673                                 lctl get_param -n $mdt_param.blocksize)
11674                         echo "MDT Blocksize: $saved_mdt_blocks"
11675                 fi
11676                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11677                 do_facet $facet zfs set recordsize=32768 $mdt
11678         done
11679
11680         # Give new values chance to reflect change
11681         sleep 2
11682
11683         echo "After recordsize change"
11684         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11685         df_after=($(df -h | grep "/mnt/lustre"$))
11686
11687         # For checking.
11688         echo "lfs output : ${lfs_df_after[*]}"
11689         echo "df  output : ${df_after[*]}"
11690
11691         # Verify lfs df
11692         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11693                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11694         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11695                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11696         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11697                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11698
11699         # Verify df
11700         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11701                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11702         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11703                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11704         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11705                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11706
11707         # Restore MDT recordize back to original
11708         for facet in ${mfacets//,/ }; do
11709                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11710                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11711         done
11712
11713         # Restore OST recordize back to original
11714         for facet in ${ofacets//,/ }; do
11715                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11716                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11717         done
11718
11719         return 0
11720 }
11721 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11722
11723 test_105a() {
11724         # doesn't work on 2.4 kernels
11725         touch $DIR/$tfile
11726         if $(flock_is_enabled); then
11727                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11728         else
11729                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11730         fi
11731         rm -f $DIR/$tfile
11732 }
11733 run_test 105a "flock when mounted without -o flock test ========"
11734
11735 test_105b() {
11736         touch $DIR/$tfile
11737         if $(flock_is_enabled); then
11738                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11739         else
11740                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11741         fi
11742         rm -f $DIR/$tfile
11743 }
11744 run_test 105b "fcntl when mounted without -o flock test ========"
11745
11746 test_105c() {
11747         touch $DIR/$tfile
11748         if $(flock_is_enabled); then
11749                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11750         else
11751                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11752         fi
11753         rm -f $DIR/$tfile
11754 }
11755 run_test 105c "lockf when mounted without -o flock test"
11756
11757 test_105d() { # bug 15924
11758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11759
11760         test_mkdir $DIR/$tdir
11761         flock_is_enabled || skip_env "mount w/o flock enabled"
11762         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11763         $LCTL set_param fail_loc=0x80000315
11764         flocks_test 2 $DIR/$tdir
11765 }
11766 run_test 105d "flock race (should not freeze) ========"
11767
11768 test_105e() { # bug 22660 && 22040
11769         flock_is_enabled || skip_env "mount w/o flock enabled"
11770
11771         touch $DIR/$tfile
11772         flocks_test 3 $DIR/$tfile
11773 }
11774 run_test 105e "Two conflicting flocks from same process"
11775
11776 test_106() { #bug 10921
11777         test_mkdir $DIR/$tdir
11778         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11779         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11780 }
11781 run_test 106 "attempt exec of dir followed by chown of that dir"
11782
11783 test_107() {
11784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11785
11786         CDIR=`pwd`
11787         local file=core
11788
11789         cd $DIR
11790         rm -f $file
11791
11792         local save_pattern=$(sysctl -n kernel.core_pattern)
11793         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11794         sysctl -w kernel.core_pattern=$file
11795         sysctl -w kernel.core_uses_pid=0
11796
11797         ulimit -c unlimited
11798         sleep 60 &
11799         SLEEPPID=$!
11800
11801         sleep 1
11802
11803         kill -s 11 $SLEEPPID
11804         wait $SLEEPPID
11805         if [ -e $file ]; then
11806                 size=`stat -c%s $file`
11807                 [ $size -eq 0 ] && error "Fail to create core file $file"
11808         else
11809                 error "Fail to create core file $file"
11810         fi
11811         rm -f $file
11812         sysctl -w kernel.core_pattern=$save_pattern
11813         sysctl -w kernel.core_uses_pid=$save_uses_pid
11814         cd $CDIR
11815 }
11816 run_test 107 "Coredump on SIG"
11817
11818 test_110() {
11819         test_mkdir $DIR/$tdir
11820         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11821         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11822                 error "mkdir with 256 char should fail, but did not"
11823         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11824                 error "create with 255 char failed"
11825         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11826                 error "create with 256 char should fail, but did not"
11827
11828         ls -l $DIR/$tdir
11829         rm -rf $DIR/$tdir
11830 }
11831 run_test 110 "filename length checking"
11832
11833 #
11834 # Purpose: To verify dynamic thread (OSS) creation.
11835 #
11836 test_115() {
11837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11838         remote_ost_nodsh && skip "remote OST with nodsh"
11839
11840         # Lustre does not stop service threads once they are started.
11841         # Reset number of running threads to default.
11842         stopall
11843         setupall
11844
11845         local OSTIO_pre
11846         local save_params="$TMP/sanity-$TESTNAME.parameters"
11847
11848         # Get ll_ost_io count before I/O
11849         OSTIO_pre=$(do_facet ost1 \
11850                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11851         # Exit if lustre is not running (ll_ost_io not running).
11852         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11853
11854         echo "Starting with $OSTIO_pre threads"
11855         local thread_max=$((OSTIO_pre * 2))
11856         local rpc_in_flight=$((thread_max * 2))
11857         # this is limited to OSC_MAX_RIF_MAX (256)
11858         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
11859         thread_max=$((rpc_in_flight / 2))
11860         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
11861                 return
11862
11863         # Number of I/O Process proposed to be started.
11864         local nfiles
11865         local facets=$(get_facets OST)
11866
11867         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11868         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11869
11870         # Set in_flight to $rpc_in_flight
11871         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11872                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11873         nfiles=${rpc_in_flight}
11874         # Set ost thread_max to $thread_max
11875         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11876
11877         # 5 Minutes should be sufficient for max number of OSS
11878         # threads(thread_max) to be created.
11879         local timeout=300
11880
11881         # Start I/O.
11882         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11883         test_mkdir $DIR/$tdir
11884         for i in $(seq $nfiles); do
11885                 local file=$DIR/$tdir/${tfile}-$i
11886                 $LFS setstripe -c -1 -i 0 $file
11887                 ($WTL $file $timeout)&
11888         done
11889
11890         # I/O Started - Wait for thread_started to reach thread_max or report
11891         # error if thread_started is more than thread_max.
11892         echo "Waiting for thread_started to reach thread_max"
11893         local thread_started=0
11894         local end_time=$((SECONDS + timeout))
11895
11896         while [ $SECONDS -le $end_time ] ; do
11897                 echo -n "."
11898                 # Get ost i/o thread_started count.
11899                 thread_started=$(do_facet ost1 \
11900                         "$LCTL get_param \
11901                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11902                 # Break out if thread_started is equal/greater than thread_max
11903                 if [[ $thread_started -ge $thread_max ]]; then
11904                         echo ll_ost_io thread_started $thread_started, \
11905                                 equal/greater than thread_max $thread_max
11906                         break
11907                 fi
11908                 sleep 1
11909         done
11910
11911         # Cleanup - We have the numbers, Kill i/o jobs if running.
11912         jobcount=($(jobs -p))
11913         for i in $(seq 0 $((${#jobcount[@]}-1)))
11914         do
11915                 kill -9 ${jobcount[$i]}
11916                 if [ $? -ne 0 ] ; then
11917                         echo Warning: \
11918                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11919                 fi
11920         done
11921
11922         # Cleanup files left by WTL binary.
11923         for i in $(seq $nfiles); do
11924                 local file=$DIR/$tdir/${tfile}-$i
11925                 rm -rf $file
11926                 if [ $? -ne 0 ] ; then
11927                         echo "Warning: Failed to delete file $file"
11928                 fi
11929         done
11930
11931         restore_lustre_params <$save_params
11932         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11933
11934         # Error out if no new thread has started or Thread started is greater
11935         # than thread max.
11936         if [[ $thread_started -le $OSTIO_pre ||
11937                         $thread_started -gt $thread_max ]]; then
11938                 error "ll_ost_io: thread_started $thread_started" \
11939                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11940                       "No new thread started or thread started greater " \
11941                       "than thread_max."
11942         fi
11943 }
11944 run_test 115 "verify dynamic thread creation===================="
11945
11946 free_min_max () {
11947         wait_delete_completed
11948         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11949         echo "OST kbytes available: ${AVAIL[@]}"
11950         MAXV=${AVAIL[0]}
11951         MAXI=0
11952         MINV=${AVAIL[0]}
11953         MINI=0
11954         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11955                 #echo OST $i: ${AVAIL[i]}kb
11956                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11957                         MAXV=${AVAIL[i]}
11958                         MAXI=$i
11959                 fi
11960                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11961                         MINV=${AVAIL[i]}
11962                         MINI=$i
11963                 fi
11964         done
11965         echo "Min free space: OST $MINI: $MINV"
11966         echo "Max free space: OST $MAXI: $MAXV"
11967 }
11968
11969 test_116a() { # was previously test_116()
11970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11971         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11972         remote_mds_nodsh && skip "remote MDS with nodsh"
11973
11974         echo -n "Free space priority "
11975         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11976                 head -n1
11977         declare -a AVAIL
11978         free_min_max
11979
11980         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11981         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11982         stack_trap simple_cleanup_common
11983
11984         # Check if we need to generate uneven OSTs
11985         test_mkdir -p $DIR/$tdir/OST${MINI}
11986         local FILL=$((MINV / 4))
11987         local DIFF=$((MAXV - MINV))
11988         local DIFF2=$((DIFF * 100 / MINV))
11989
11990         local threshold=$(do_facet $SINGLEMDS \
11991                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11992         threshold=${threshold%%%}
11993         echo -n "Check for uneven OSTs: "
11994         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11995
11996         if [[ $DIFF2 -gt $threshold ]]; then
11997                 echo "ok"
11998                 echo "Don't need to fill OST$MINI"
11999         else
12000                 # generate uneven OSTs. Write 2% over the QOS threshold value
12001                 echo "no"
12002                 DIFF=$((threshold - DIFF2 + 2))
12003                 DIFF2=$((MINV * DIFF / 100))
12004                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12005                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12006                         error "setstripe failed"
12007                 DIFF=$((DIFF2 / 2048))
12008                 i=0
12009                 while [ $i -lt $DIFF ]; do
12010                         i=$((i + 1))
12011                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12012                                 bs=2M count=1 2>/dev/null
12013                         echo -n .
12014                 done
12015                 echo .
12016                 sync
12017                 sleep_maxage
12018                 free_min_max
12019         fi
12020
12021         DIFF=$((MAXV - MINV))
12022         DIFF2=$((DIFF * 100 / MINV))
12023         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12024         if [ $DIFF2 -gt $threshold ]; then
12025                 echo "ok"
12026         else
12027                 skip "QOS imbalance criteria not met"
12028         fi
12029
12030         MINI1=$MINI
12031         MINV1=$MINV
12032         MAXI1=$MAXI
12033         MAXV1=$MAXV
12034
12035         # now fill using QOS
12036         $LFS setstripe -c 1 $DIR/$tdir
12037         FILL=$((FILL / 200))
12038         if [ $FILL -gt 600 ]; then
12039                 FILL=600
12040         fi
12041         echo "writing $FILL files to QOS-assigned OSTs"
12042         i=0
12043         while [ $i -lt $FILL ]; do
12044                 i=$((i + 1))
12045                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12046                         count=1 2>/dev/null
12047                 echo -n .
12048         done
12049         echo "wrote $i 200k files"
12050         sync
12051         sleep_maxage
12052
12053         echo "Note: free space may not be updated, so measurements might be off"
12054         free_min_max
12055         DIFF2=$((MAXV - MINV))
12056         echo "free space delta: orig $DIFF final $DIFF2"
12057         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12058         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12059         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12060         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12061         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12062         if [[ $DIFF -gt 0 ]]; then
12063                 FILL=$((DIFF2 * 100 / DIFF - 100))
12064                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12065         fi
12066
12067         # Figure out which files were written where
12068         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12069                awk '/'$MINI1': / {print $2; exit}')
12070         echo $UUID
12071         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12072         echo "$MINC files created on smaller OST $MINI1"
12073         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12074                awk '/'$MAXI1': / {print $2; exit}')
12075         echo $UUID
12076         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12077         echo "$MAXC files created on larger OST $MAXI1"
12078         if [[ $MINC -gt 0 ]]; then
12079                 FILL=$((MAXC * 100 / MINC - 100))
12080                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12081         fi
12082         [[ $MAXC -gt $MINC ]] ||
12083                 error_ignore LU-9 "stripe QOS didn't balance free space"
12084 }
12085 run_test 116a "stripe QOS: free space balance ==================="
12086
12087 test_116b() { # LU-2093
12088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12089         remote_mds_nodsh && skip "remote MDS with nodsh"
12090
12091 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12092         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12093                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12094         [ -z "$old_rr" ] && skip "no QOS"
12095         do_facet $SINGLEMDS lctl set_param \
12096                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12097         mkdir -p $DIR/$tdir
12098         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12099         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12100         do_facet $SINGLEMDS lctl set_param fail_loc=0
12101         rm -rf $DIR/$tdir
12102         do_facet $SINGLEMDS lctl set_param \
12103                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12104 }
12105 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12106
12107 test_117() # bug 10891
12108 {
12109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12110
12111         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12112         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12113         lctl set_param fail_loc=0x21e
12114         > $DIR/$tfile || error "truncate failed"
12115         lctl set_param fail_loc=0
12116         echo "Truncate succeeded."
12117         rm -f $DIR/$tfile
12118 }
12119 run_test 117 "verify osd extend =========="
12120
12121 NO_SLOW_RESENDCOUNT=4
12122 export OLD_RESENDCOUNT=""
12123 set_resend_count () {
12124         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12125         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12126         lctl set_param -n $PROC_RESENDCOUNT $1
12127         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12128 }
12129
12130 # for reduce test_118* time (b=14842)
12131 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12132
12133 # Reset async IO behavior after error case
12134 reset_async() {
12135         FILE=$DIR/reset_async
12136
12137         # Ensure all OSCs are cleared
12138         $LFS setstripe -c -1 $FILE
12139         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12140         sync
12141         rm $FILE
12142 }
12143
12144 test_118a() #bug 11710
12145 {
12146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12147
12148         reset_async
12149
12150         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12151         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12152         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12153
12154         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12155                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12156                 return 1;
12157         fi
12158         rm -f $DIR/$tfile
12159 }
12160 run_test 118a "verify O_SYNC works =========="
12161
12162 test_118b()
12163 {
12164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12165         remote_ost_nodsh && skip "remote OST with nodsh"
12166
12167         reset_async
12168
12169         #define OBD_FAIL_SRV_ENOENT 0x217
12170         set_nodes_failloc "$(osts_nodes)" 0x217
12171         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12172         RC=$?
12173         set_nodes_failloc "$(osts_nodes)" 0
12174         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12175         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12176                     grep -c writeback)
12177
12178         if [[ $RC -eq 0 ]]; then
12179                 error "Must return error due to dropped pages, rc=$RC"
12180                 return 1;
12181         fi
12182
12183         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12184                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12185                 return 1;
12186         fi
12187
12188         echo "Dirty pages not leaked on ENOENT"
12189
12190         # Due to the above error the OSC will issue all RPCs syncronously
12191         # until a subsequent RPC completes successfully without error.
12192         $MULTIOP $DIR/$tfile Ow4096yc
12193         rm -f $DIR/$tfile
12194
12195         return 0
12196 }
12197 run_test 118b "Reclaim dirty pages on fatal error =========="
12198
12199 test_118c()
12200 {
12201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12202
12203         # for 118c, restore the original resend count, LU-1940
12204         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12205                                 set_resend_count $OLD_RESENDCOUNT
12206         remote_ost_nodsh && skip "remote OST with nodsh"
12207
12208         reset_async
12209
12210         #define OBD_FAIL_OST_EROFS               0x216
12211         set_nodes_failloc "$(osts_nodes)" 0x216
12212
12213         # multiop should block due to fsync until pages are written
12214         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12215         MULTIPID=$!
12216         sleep 1
12217
12218         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12219                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12220         fi
12221
12222         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12223                     grep -c writeback)
12224         if [[ $WRITEBACK -eq 0 ]]; then
12225                 error "No page in writeback, writeback=$WRITEBACK"
12226         fi
12227
12228         set_nodes_failloc "$(osts_nodes)" 0
12229         wait $MULTIPID
12230         RC=$?
12231         if [[ $RC -ne 0 ]]; then
12232                 error "Multiop fsync failed, rc=$RC"
12233         fi
12234
12235         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12236         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12237                     grep -c writeback)
12238         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12239                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12240         fi
12241
12242         rm -f $DIR/$tfile
12243         echo "Dirty pages flushed via fsync on EROFS"
12244         return 0
12245 }
12246 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12247
12248 # continue to use small resend count to reduce test_118* time (b=14842)
12249 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12250
12251 test_118d()
12252 {
12253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12254         remote_ost_nodsh && skip "remote OST with nodsh"
12255
12256         reset_async
12257
12258         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12259         set_nodes_failloc "$(osts_nodes)" 0x214
12260         # multiop should block due to fsync until pages are written
12261         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12262         MULTIPID=$!
12263         sleep 1
12264
12265         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12266                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12267         fi
12268
12269         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12270                     grep -c writeback)
12271         if [[ $WRITEBACK -eq 0 ]]; then
12272                 error "No page in writeback, writeback=$WRITEBACK"
12273         fi
12274
12275         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12276         set_nodes_failloc "$(osts_nodes)" 0
12277
12278         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12279         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12280                     grep -c writeback)
12281         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12282                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12283         fi
12284
12285         rm -f $DIR/$tfile
12286         echo "Dirty pages gaurenteed flushed via fsync"
12287         return 0
12288 }
12289 run_test 118d "Fsync validation inject a delay of the bulk =========="
12290
12291 test_118f() {
12292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12293
12294         reset_async
12295
12296         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12297         lctl set_param fail_loc=0x8000040a
12298
12299         # Should simulate EINVAL error which is fatal
12300         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12301         RC=$?
12302         if [[ $RC -eq 0 ]]; then
12303                 error "Must return error due to dropped pages, rc=$RC"
12304         fi
12305
12306         lctl set_param fail_loc=0x0
12307
12308         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12309         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12310         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12311                     grep -c writeback)
12312         if [[ $LOCKED -ne 0 ]]; then
12313                 error "Locked pages remain in cache, locked=$LOCKED"
12314         fi
12315
12316         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12317                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12318         fi
12319
12320         rm -f $DIR/$tfile
12321         echo "No pages locked after fsync"
12322
12323         reset_async
12324         return 0
12325 }
12326 run_test 118f "Simulate unrecoverable OSC side error =========="
12327
12328 test_118g() {
12329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12330
12331         reset_async
12332
12333         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12334         lctl set_param fail_loc=0x406
12335
12336         # simulate local -ENOMEM
12337         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12338         RC=$?
12339
12340         lctl set_param fail_loc=0
12341         if [[ $RC -eq 0 ]]; then
12342                 error "Must return error due to dropped pages, rc=$RC"
12343         fi
12344
12345         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12346         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12347         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12348                         grep -c writeback)
12349         if [[ $LOCKED -ne 0 ]]; then
12350                 error "Locked pages remain in cache, locked=$LOCKED"
12351         fi
12352
12353         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12354                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12355         fi
12356
12357         rm -f $DIR/$tfile
12358         echo "No pages locked after fsync"
12359
12360         reset_async
12361         return 0
12362 }
12363 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12364
12365 test_118h() {
12366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12367         remote_ost_nodsh && skip "remote OST with nodsh"
12368
12369         reset_async
12370
12371         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12372         set_nodes_failloc "$(osts_nodes)" 0x20e
12373         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12374         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12375         RC=$?
12376
12377         set_nodes_failloc "$(osts_nodes)" 0
12378         if [[ $RC -eq 0 ]]; then
12379                 error "Must return error due to dropped pages, rc=$RC"
12380         fi
12381
12382         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12383         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12384         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12385                     grep -c writeback)
12386         if [[ $LOCKED -ne 0 ]]; then
12387                 error "Locked pages remain in cache, locked=$LOCKED"
12388         fi
12389
12390         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12391                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12392         fi
12393
12394         rm -f $DIR/$tfile
12395         echo "No pages locked after fsync"
12396
12397         return 0
12398 }
12399 run_test 118h "Verify timeout in handling recoverables errors  =========="
12400
12401 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12402
12403 test_118i() {
12404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12405         remote_ost_nodsh && skip "remote OST with nodsh"
12406
12407         reset_async
12408
12409         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12410         set_nodes_failloc "$(osts_nodes)" 0x20e
12411
12412         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12413         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12414         PID=$!
12415         sleep 5
12416         set_nodes_failloc "$(osts_nodes)" 0
12417
12418         wait $PID
12419         RC=$?
12420         if [[ $RC -ne 0 ]]; then
12421                 error "got error, but should be not, rc=$RC"
12422         fi
12423
12424         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12425         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12426         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12427         if [[ $LOCKED -ne 0 ]]; then
12428                 error "Locked pages remain in cache, locked=$LOCKED"
12429         fi
12430
12431         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12432                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12433         fi
12434
12435         rm -f $DIR/$tfile
12436         echo "No pages locked after fsync"
12437
12438         return 0
12439 }
12440 run_test 118i "Fix error before timeout in recoverable error  =========="
12441
12442 [ "$SLOW" = "no" ] && set_resend_count 4
12443
12444 test_118j() {
12445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12446         remote_ost_nodsh && skip "remote OST with nodsh"
12447
12448         reset_async
12449
12450         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12451         set_nodes_failloc "$(osts_nodes)" 0x220
12452
12453         # return -EIO from OST
12454         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12455         RC=$?
12456         set_nodes_failloc "$(osts_nodes)" 0x0
12457         if [[ $RC -eq 0 ]]; then
12458                 error "Must return error due to dropped pages, rc=$RC"
12459         fi
12460
12461         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12462         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12463         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12464         if [[ $LOCKED -ne 0 ]]; then
12465                 error "Locked pages remain in cache, locked=$LOCKED"
12466         fi
12467
12468         # in recoverable error on OST we want resend and stay until it finished
12469         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12470                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12471         fi
12472
12473         rm -f $DIR/$tfile
12474         echo "No pages locked after fsync"
12475
12476         return 0
12477 }
12478 run_test 118j "Simulate unrecoverable OST side error =========="
12479
12480 test_118k()
12481 {
12482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12483         remote_ost_nodsh && skip "remote OSTs with nodsh"
12484
12485         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12486         set_nodes_failloc "$(osts_nodes)" 0x20e
12487         test_mkdir $DIR/$tdir
12488
12489         for ((i=0;i<10;i++)); do
12490                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12491                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12492                 SLEEPPID=$!
12493                 sleep 0.500s
12494                 kill $SLEEPPID
12495                 wait $SLEEPPID
12496         done
12497
12498         set_nodes_failloc "$(osts_nodes)" 0
12499         rm -rf $DIR/$tdir
12500 }
12501 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12502
12503 test_118l() # LU-646
12504 {
12505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12506
12507         test_mkdir $DIR/$tdir
12508         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12509         rm -rf $DIR/$tdir
12510 }
12511 run_test 118l "fsync dir"
12512
12513 test_118m() # LU-3066
12514 {
12515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12516
12517         test_mkdir $DIR/$tdir
12518         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12519         rm -rf $DIR/$tdir
12520 }
12521 run_test 118m "fdatasync dir ========="
12522
12523 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12524
12525 test_118n()
12526 {
12527         local begin
12528         local end
12529
12530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12531         remote_ost_nodsh && skip "remote OSTs with nodsh"
12532
12533         # Sleep to avoid a cached response.
12534         #define OBD_STATFS_CACHE_SECONDS 1
12535         sleep 2
12536
12537         # Inject a 10 second delay in the OST_STATFS handler.
12538         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12539         set_nodes_failloc "$(osts_nodes)" 0x242
12540
12541         begin=$SECONDS
12542         stat --file-system $MOUNT > /dev/null
12543         end=$SECONDS
12544
12545         set_nodes_failloc "$(osts_nodes)" 0
12546
12547         if ((end - begin > 20)); then
12548             error "statfs took $((end - begin)) seconds, expected 10"
12549         fi
12550 }
12551 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12552
12553 test_119a() # bug 11737
12554 {
12555         BSIZE=$((512 * 1024))
12556         directio write $DIR/$tfile 0 1 $BSIZE
12557         # We ask to read two blocks, which is more than a file size.
12558         # directio will indicate an error when requested and actual
12559         # sizes aren't equeal (a normal situation in this case) and
12560         # print actual read amount.
12561         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12562         if [ "$NOB" != "$BSIZE" ]; then
12563                 error "read $NOB bytes instead of $BSIZE"
12564         fi
12565         rm -f $DIR/$tfile
12566 }
12567 run_test 119a "Short directIO read must return actual read amount"
12568
12569 test_119b() # bug 11737
12570 {
12571         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12572
12573         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12574         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12575         sync
12576         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12577                 error "direct read failed"
12578         rm -f $DIR/$tfile
12579 }
12580 run_test 119b "Sparse directIO read must return actual read amount"
12581
12582 test_119c() # bug 13099
12583 {
12584         BSIZE=1048576
12585         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12586         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12587         rm -f $DIR/$tfile
12588 }
12589 run_test 119c "Testing for direct read hitting hole"
12590
12591 test_119d() # bug 15950
12592 {
12593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12594
12595         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12596         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12597         BSIZE=1048576
12598         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12599         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12600         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12601         lctl set_param fail_loc=0x40d
12602         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12603         pid_dio=$!
12604         sleep 1
12605         cat $DIR/$tfile > /dev/null &
12606         lctl set_param fail_loc=0
12607         pid_reads=$!
12608         wait $pid_dio
12609         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12610         sleep 2
12611         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12612         error "the read rpcs have not completed in 2s"
12613         rm -f $DIR/$tfile
12614         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12615 }
12616 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12617
12618 test_120a() {
12619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12620         remote_mds_nodsh && skip "remote MDS with nodsh"
12621         test_mkdir -i0 -c1 $DIR/$tdir
12622         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12623                 skip_env "no early lock cancel on server"
12624
12625         lru_resize_disable mdc
12626         lru_resize_disable osc
12627         cancel_lru_locks mdc
12628         # asynchronous object destroy at MDT could cause bl ast to client
12629         cancel_lru_locks osc
12630
12631         stat $DIR/$tdir > /dev/null
12632         can1=$(do_facet mds1 \
12633                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12634                awk '/ldlm_cancel/ {print $2}')
12635         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12636                awk '/ldlm_bl_callback/ {print $2}')
12637         test_mkdir -i0 -c1 $DIR/$tdir/d1
12638         can2=$(do_facet mds1 \
12639                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12640                awk '/ldlm_cancel/ {print $2}')
12641         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12642                awk '/ldlm_bl_callback/ {print $2}')
12643         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12644         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12645         lru_resize_enable mdc
12646         lru_resize_enable osc
12647 }
12648 run_test 120a "Early Lock Cancel: mkdir test"
12649
12650 test_120b() {
12651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12652         remote_mds_nodsh && skip "remote MDS with nodsh"
12653         test_mkdir $DIR/$tdir
12654         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12655                 skip_env "no early lock cancel on server"
12656
12657         lru_resize_disable mdc
12658         lru_resize_disable osc
12659         cancel_lru_locks mdc
12660         stat $DIR/$tdir > /dev/null
12661         can1=$(do_facet $SINGLEMDS \
12662                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12663                awk '/ldlm_cancel/ {print $2}')
12664         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12665                awk '/ldlm_bl_callback/ {print $2}')
12666         touch $DIR/$tdir/f1
12667         can2=$(do_facet $SINGLEMDS \
12668                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12669                awk '/ldlm_cancel/ {print $2}')
12670         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12671                awk '/ldlm_bl_callback/ {print $2}')
12672         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12673         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12674         lru_resize_enable mdc
12675         lru_resize_enable osc
12676 }
12677 run_test 120b "Early Lock Cancel: create test"
12678
12679 test_120c() {
12680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12681         remote_mds_nodsh && skip "remote MDS with nodsh"
12682         test_mkdir -i0 -c1 $DIR/$tdir
12683         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12684                 skip "no early lock cancel on server"
12685
12686         lru_resize_disable mdc
12687         lru_resize_disable osc
12688         test_mkdir -i0 -c1 $DIR/$tdir/d1
12689         test_mkdir -i0 -c1 $DIR/$tdir/d2
12690         touch $DIR/$tdir/d1/f1
12691         cancel_lru_locks mdc
12692         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12693         can1=$(do_facet mds1 \
12694                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12695                awk '/ldlm_cancel/ {print $2}')
12696         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12697                awk '/ldlm_bl_callback/ {print $2}')
12698         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12699         can2=$(do_facet mds1 \
12700                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12701                awk '/ldlm_cancel/ {print $2}')
12702         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12703                awk '/ldlm_bl_callback/ {print $2}')
12704         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12705         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12706         lru_resize_enable mdc
12707         lru_resize_enable osc
12708 }
12709 run_test 120c "Early Lock Cancel: link test"
12710
12711 test_120d() {
12712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12713         remote_mds_nodsh && skip "remote MDS with nodsh"
12714         test_mkdir -i0 -c1 $DIR/$tdir
12715         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12716                 skip_env "no early lock cancel on server"
12717
12718         lru_resize_disable mdc
12719         lru_resize_disable osc
12720         touch $DIR/$tdir
12721         cancel_lru_locks mdc
12722         stat $DIR/$tdir > /dev/null
12723         can1=$(do_facet mds1 \
12724                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12725                awk '/ldlm_cancel/ {print $2}')
12726         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12727                awk '/ldlm_bl_callback/ {print $2}')
12728         chmod a+x $DIR/$tdir
12729         can2=$(do_facet mds1 \
12730                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12731                awk '/ldlm_cancel/ {print $2}')
12732         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12733                awk '/ldlm_bl_callback/ {print $2}')
12734         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12735         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12736         lru_resize_enable mdc
12737         lru_resize_enable osc
12738 }
12739 run_test 120d "Early Lock Cancel: setattr test"
12740
12741 test_120e() {
12742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12743         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12744                 skip_env "no early lock cancel on server"
12745         remote_mds_nodsh && skip "remote MDS with nodsh"
12746
12747         local dlmtrace_set=false
12748
12749         test_mkdir -i0 -c1 $DIR/$tdir
12750         lru_resize_disable mdc
12751         lru_resize_disable osc
12752         ! $LCTL get_param debug | grep -q dlmtrace &&
12753                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12754         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12755         cancel_lru_locks mdc
12756         cancel_lru_locks osc
12757         dd if=$DIR/$tdir/f1 of=/dev/null
12758         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12759         # XXX client can not do early lock cancel of OST lock
12760         # during unlink (LU-4206), so cancel osc lock now.
12761         sleep 2
12762         cancel_lru_locks osc
12763         can1=$(do_facet mds1 \
12764                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12765                awk '/ldlm_cancel/ {print $2}')
12766         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12767                awk '/ldlm_bl_callback/ {print $2}')
12768         unlink $DIR/$tdir/f1
12769         sleep 5
12770         can2=$(do_facet mds1 \
12771                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12772                awk '/ldlm_cancel/ {print $2}')
12773         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12774                awk '/ldlm_bl_callback/ {print $2}')
12775         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12776                 $LCTL dk $TMP/cancel.debug.txt
12777         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12778                 $LCTL dk $TMP/blocking.debug.txt
12779         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12780         lru_resize_enable mdc
12781         lru_resize_enable osc
12782 }
12783 run_test 120e "Early Lock Cancel: unlink test"
12784
12785 test_120f() {
12786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12787         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12788                 skip_env "no early lock cancel on server"
12789         remote_mds_nodsh && skip "remote MDS with nodsh"
12790
12791         test_mkdir -i0 -c1 $DIR/$tdir
12792         lru_resize_disable mdc
12793         lru_resize_disable osc
12794         test_mkdir -i0 -c1 $DIR/$tdir/d1
12795         test_mkdir -i0 -c1 $DIR/$tdir/d2
12796         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12797         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12798         cancel_lru_locks mdc
12799         cancel_lru_locks osc
12800         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12801         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12802         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12803         # XXX client can not do early lock cancel of OST lock
12804         # during rename (LU-4206), so cancel osc lock now.
12805         sleep 2
12806         cancel_lru_locks osc
12807         can1=$(do_facet mds1 \
12808                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12809                awk '/ldlm_cancel/ {print $2}')
12810         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12811                awk '/ldlm_bl_callback/ {print $2}')
12812         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12813         sleep 5
12814         can2=$(do_facet mds1 \
12815                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12816                awk '/ldlm_cancel/ {print $2}')
12817         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12818                awk '/ldlm_bl_callback/ {print $2}')
12819         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12820         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12821         lru_resize_enable mdc
12822         lru_resize_enable osc
12823 }
12824 run_test 120f "Early Lock Cancel: rename test"
12825
12826 test_120g() {
12827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12828         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12829                 skip_env "no early lock cancel on server"
12830         remote_mds_nodsh && skip "remote MDS with nodsh"
12831
12832         lru_resize_disable mdc
12833         lru_resize_disable osc
12834         count=10000
12835         echo create $count files
12836         test_mkdir $DIR/$tdir
12837         cancel_lru_locks mdc
12838         cancel_lru_locks osc
12839         t0=$(date +%s)
12840
12841         can0=$(do_facet $SINGLEMDS \
12842                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12843                awk '/ldlm_cancel/ {print $2}')
12844         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12845                awk '/ldlm_bl_callback/ {print $2}')
12846         createmany -o $DIR/$tdir/f $count
12847         sync
12848         can1=$(do_facet $SINGLEMDS \
12849                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12850                awk '/ldlm_cancel/ {print $2}')
12851         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12852                awk '/ldlm_bl_callback/ {print $2}')
12853         t1=$(date +%s)
12854         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12855         echo rm $count files
12856         rm -r $DIR/$tdir
12857         sync
12858         can2=$(do_facet $SINGLEMDS \
12859                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12860                awk '/ldlm_cancel/ {print $2}')
12861         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12862                awk '/ldlm_bl_callback/ {print $2}')
12863         t2=$(date +%s)
12864         echo total: $count removes in $((t2-t1))
12865         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12866         sleep 2
12867         # wait for commitment of removal
12868         lru_resize_enable mdc
12869         lru_resize_enable osc
12870 }
12871 run_test 120g "Early Lock Cancel: performance test"
12872
12873 test_121() { #bug #10589
12874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12875
12876         rm -rf $DIR/$tfile
12877         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12878 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12879         lctl set_param fail_loc=0x310
12880         cancel_lru_locks osc > /dev/null
12881         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12882         lctl set_param fail_loc=0
12883         [[ $reads -eq $writes ]] ||
12884                 error "read $reads blocks, must be $writes blocks"
12885 }
12886 run_test 121 "read cancel race ========="
12887
12888 test_123a_base() { # was test 123, statahead(bug 11401)
12889         local lsx="$1"
12890
12891         SLOWOK=0
12892         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12893                 log "testing UP system. Performance may be lower than expected."
12894                 SLOWOK=1
12895         fi
12896
12897         rm -rf $DIR/$tdir
12898         test_mkdir $DIR/$tdir
12899         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12900         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12901         MULT=10
12902         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12903                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12904
12905                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12906                 lctl set_param -n llite.*.statahead_max 0
12907                 lctl get_param llite.*.statahead_max
12908                 cancel_lru_locks mdc
12909                 cancel_lru_locks osc
12910                 stime=$(date +%s)
12911                 time $lsx $DIR/$tdir | wc -l
12912                 etime=$(date +%s)
12913                 delta=$((etime - stime))
12914                 log "$lsx $i files without statahead: $delta sec"
12915                 lctl set_param llite.*.statahead_max=$max
12916
12917                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12918                         grep "statahead wrong:" | awk '{print $3}')
12919                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12920                 cancel_lru_locks mdc
12921                 cancel_lru_locks osc
12922                 stime=$(date +%s)
12923                 time $lsx $DIR/$tdir | wc -l
12924                 etime=$(date +%s)
12925                 delta_sa=$((etime - stime))
12926                 log "$lsx $i files with statahead: $delta_sa sec"
12927                 lctl get_param -n llite.*.statahead_stats
12928                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12929                         grep "statahead wrong:" | awk '{print $3}')
12930
12931                 [[ $swrong -lt $ewrong ]] &&
12932                         log "statahead was stopped, maybe too many locks held!"
12933                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12934
12935                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12936                         max=$(lctl get_param -n llite.*.statahead_max |
12937                                 head -n 1)
12938                         lctl set_param -n llite.*.statahead_max 0
12939                         lctl get_param llite.*.statahead_max
12940                         cancel_lru_locks mdc
12941                         cancel_lru_locks osc
12942                         stime=$(date +%s)
12943                         time $lsx $DIR/$tdir | wc -l
12944                         etime=$(date +%s)
12945                         delta=$((etime - stime))
12946                         log "$lsx $i files again without statahead: $delta sec"
12947                         lctl set_param llite.*.statahead_max=$max
12948                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12949                                 if [  $SLOWOK -eq 0 ]; then
12950                                         error "$lsx $i files is slower with statahead!"
12951                                 else
12952                                         log "$lsx $i files is slower with statahead!"
12953                                 fi
12954                                 break
12955                         fi
12956                 fi
12957
12958                 [ $delta -gt 20 ] && break
12959                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12960                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12961         done
12962         log "$lsx done"
12963
12964         stime=$(date +%s)
12965         rm -r $DIR/$tdir
12966         sync
12967         etime=$(date +%s)
12968         delta=$((etime - stime))
12969         log "rm -r $DIR/$tdir/: $delta seconds"
12970         log "rm done"
12971         lctl get_param -n llite.*.statahead_stats
12972 }
12973
12974 test_123aa() {
12975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12976
12977         test_123a_base "ls -l"
12978 }
12979 run_test 123aa "verify statahead work"
12980
12981 test_123ab() {
12982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12983
12984         statx_supported || skip_env "Test must be statx() syscall supported"
12985
12986         test_123a_base "$STATX -l"
12987 }
12988 run_test 123ab "verify statahead work by using statx"
12989
12990 test_123ac() {
12991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12992
12993         statx_supported || skip_env "Test must be statx() syscall supported"
12994
12995         local rpcs_before
12996         local rpcs_after
12997         local agl_before
12998         local agl_after
12999
13000         cancel_lru_locks $OSC
13001         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13002         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13003                 awk '/agl.total:/ {print $3}')
13004         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13005         test_123a_base "$STATX --cached=always -D"
13006         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13007                 awk '/agl.total:/ {print $3}')
13008         [ $agl_before -eq $agl_after ] ||
13009                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13010         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13011         [ $rpcs_after -eq $rpcs_before ] ||
13012                 error "$STATX should not send glimpse RPCs to $OSC"
13013 }
13014 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13015
13016 test_123b () { # statahead(bug 15027)
13017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13018
13019         test_mkdir $DIR/$tdir
13020         createmany -o $DIR/$tdir/$tfile-%d 1000
13021
13022         cancel_lru_locks mdc
13023         cancel_lru_locks osc
13024
13025 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13026         lctl set_param fail_loc=0x80000803
13027         ls -lR $DIR/$tdir > /dev/null
13028         log "ls done"
13029         lctl set_param fail_loc=0x0
13030         lctl get_param -n llite.*.statahead_stats
13031         rm -r $DIR/$tdir
13032         sync
13033
13034 }
13035 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13036
13037 test_123c() {
13038         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13039
13040         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13041         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13042         touch $DIR/$tdir.1/{1..3}
13043         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13044
13045         remount_client $MOUNT
13046
13047         $MULTIOP $DIR/$tdir.0 Q
13048
13049         # let statahead to complete
13050         ls -l $DIR/$tdir.0 > /dev/null
13051
13052         testid=$(echo $TESTNAME | tr '_' ' ')
13053         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13054                 error "statahead warning" || true
13055 }
13056 run_test 123c "Can not initialize inode warning on DNE statahead"
13057
13058 test_124a() {
13059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13060         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13061                 skip_env "no lru resize on server"
13062
13063         local NR=2000
13064
13065         test_mkdir $DIR/$tdir
13066
13067         log "create $NR files at $DIR/$tdir"
13068         createmany -o $DIR/$tdir/f $NR ||
13069                 error "failed to create $NR files in $DIR/$tdir"
13070
13071         cancel_lru_locks mdc
13072         ls -l $DIR/$tdir > /dev/null
13073
13074         local NSDIR=""
13075         local LRU_SIZE=0
13076         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13077                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13078                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13079                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13080                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13081                         log "NSDIR=$NSDIR"
13082                         log "NS=$(basename $NSDIR)"
13083                         break
13084                 fi
13085         done
13086
13087         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13088                 skip "Not enough cached locks created!"
13089         fi
13090         log "LRU=$LRU_SIZE"
13091
13092         local SLEEP=30
13093
13094         # We know that lru resize allows one client to hold $LIMIT locks
13095         # for 10h. After that locks begin to be killed by client.
13096         local MAX_HRS=10
13097         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13098         log "LIMIT=$LIMIT"
13099         if [ $LIMIT -lt $LRU_SIZE ]; then
13100                 skip "Limit is too small $LIMIT"
13101         fi
13102
13103         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13104         # killing locks. Some time was spent for creating locks. This means
13105         # that up to the moment of sleep finish we must have killed some of
13106         # them (10-100 locks). This depends on how fast ther were created.
13107         # Many of them were touched in almost the same moment and thus will
13108         # be killed in groups.
13109         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13110
13111         # Use $LRU_SIZE_B here to take into account real number of locks
13112         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13113         local LRU_SIZE_B=$LRU_SIZE
13114         log "LVF=$LVF"
13115         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13116         log "OLD_LVF=$OLD_LVF"
13117         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13118
13119         # Let's make sure that we really have some margin. Client checks
13120         # cached locks every 10 sec.
13121         SLEEP=$((SLEEP+20))
13122         log "Sleep ${SLEEP} sec"
13123         local SEC=0
13124         while ((SEC<$SLEEP)); do
13125                 echo -n "..."
13126                 sleep 5
13127                 SEC=$((SEC+5))
13128                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13129                 echo -n "$LRU_SIZE"
13130         done
13131         echo ""
13132         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13133         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13134
13135         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13136                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13137                 unlinkmany $DIR/$tdir/f $NR
13138                 return
13139         }
13140
13141         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13142         log "unlink $NR files at $DIR/$tdir"
13143         unlinkmany $DIR/$tdir/f $NR
13144 }
13145 run_test 124a "lru resize ======================================="
13146
13147 get_max_pool_limit()
13148 {
13149         local limit=$($LCTL get_param \
13150                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13151         local max=0
13152         for l in $limit; do
13153                 if [[ $l -gt $max ]]; then
13154                         max=$l
13155                 fi
13156         done
13157         echo $max
13158 }
13159
13160 test_124b() {
13161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13162         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13163                 skip_env "no lru resize on server"
13164
13165         LIMIT=$(get_max_pool_limit)
13166
13167         NR=$(($(default_lru_size)*20))
13168         if [[ $NR -gt $LIMIT ]]; then
13169                 log "Limit lock number by $LIMIT locks"
13170                 NR=$LIMIT
13171         fi
13172
13173         IFree=$(mdsrate_inodes_available)
13174         if [ $IFree -lt $NR ]; then
13175                 log "Limit lock number by $IFree inodes"
13176                 NR=$IFree
13177         fi
13178
13179         lru_resize_disable mdc
13180         test_mkdir -p $DIR/$tdir/disable_lru_resize
13181
13182         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13183         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13184         cancel_lru_locks mdc
13185         stime=`date +%s`
13186         PID=""
13187         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13188         PID="$PID $!"
13189         sleep 2
13190         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13191         PID="$PID $!"
13192         sleep 2
13193         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13194         PID="$PID $!"
13195         wait $PID
13196         etime=`date +%s`
13197         nolruresize_delta=$((etime-stime))
13198         log "ls -la time: $nolruresize_delta seconds"
13199         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13200         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13201
13202         lru_resize_enable mdc
13203         test_mkdir -p $DIR/$tdir/enable_lru_resize
13204
13205         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13206         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13207         cancel_lru_locks mdc
13208         stime=`date +%s`
13209         PID=""
13210         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13211         PID="$PID $!"
13212         sleep 2
13213         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13214         PID="$PID $!"
13215         sleep 2
13216         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13217         PID="$PID $!"
13218         wait $PID
13219         etime=`date +%s`
13220         lruresize_delta=$((etime-stime))
13221         log "ls -la time: $lruresize_delta seconds"
13222         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13223
13224         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13225                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13226         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13227                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13228         else
13229                 log "lru resize performs the same with no lru resize"
13230         fi
13231         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13232 }
13233 run_test 124b "lru resize (performance test) ======================="
13234
13235 test_124c() {
13236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13237         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13238                 skip_env "no lru resize on server"
13239
13240         # cache ununsed locks on client
13241         local nr=100
13242         cancel_lru_locks mdc
13243         test_mkdir $DIR/$tdir
13244         createmany -o $DIR/$tdir/f $nr ||
13245                 error "failed to create $nr files in $DIR/$tdir"
13246         ls -l $DIR/$tdir > /dev/null
13247
13248         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13249         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13250         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13251         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13252         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13253
13254         # set lru_max_age to 1 sec
13255         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13256         echo "sleep $((recalc_p * 2)) seconds..."
13257         sleep $((recalc_p * 2))
13258
13259         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13260         # restore lru_max_age
13261         $LCTL set_param -n $nsdir.lru_max_age $max_age
13262         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13263         unlinkmany $DIR/$tdir/f $nr
13264 }
13265 run_test 124c "LRUR cancel very aged locks"
13266
13267 test_124d() {
13268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13269         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13270                 skip_env "no lru resize on server"
13271
13272         # cache ununsed locks on client
13273         local nr=100
13274
13275         lru_resize_disable mdc
13276         stack_trap "lru_resize_enable mdc" EXIT
13277
13278         cancel_lru_locks mdc
13279
13280         # asynchronous object destroy at MDT could cause bl ast to client
13281         test_mkdir $DIR/$tdir
13282         createmany -o $DIR/$tdir/f $nr ||
13283                 error "failed to create $nr files in $DIR/$tdir"
13284         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13285
13286         ls -l $DIR/$tdir > /dev/null
13287
13288         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13289         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13290         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13291         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13292
13293         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13294
13295         # set lru_max_age to 1 sec
13296         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13297         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13298
13299         echo "sleep $((recalc_p * 2)) seconds..."
13300         sleep $((recalc_p * 2))
13301
13302         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13303
13304         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13305 }
13306 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13307
13308 test_125() { # 13358
13309         $LCTL get_param -n llite.*.client_type | grep -q local ||
13310                 skip "must run as local client"
13311         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13312                 skip_env "must have acl enabled"
13313         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13314
13315         test_mkdir $DIR/$tdir
13316         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13317         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13318         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13319 }
13320 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13321
13322 test_126() { # bug 12829/13455
13323         $GSS && skip_env "must run as gss disabled"
13324         $LCTL get_param -n llite.*.client_type | grep -q local ||
13325                 skip "must run as local client"
13326         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13327
13328         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13329         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13330         rm -f $DIR/$tfile
13331         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13332 }
13333 run_test 126 "check that the fsgid provided by the client is taken into account"
13334
13335 test_127a() { # bug 15521
13336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13337         local name count samp unit min max sum sumsq
13338
13339         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13340         echo "stats before reset"
13341         $LCTL get_param osc.*.stats
13342         $LCTL set_param osc.*.stats=0
13343         local fsize=$((2048 * 1024))
13344
13345         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13346         cancel_lru_locks osc
13347         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13348
13349         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13350         stack_trap "rm -f $TMP/$tfile.tmp"
13351         while read name count samp unit min max sum sumsq; do
13352                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13353                 [ ! $min ] && error "Missing min value for $name proc entry"
13354                 eval $name=$count || error "Wrong proc format"
13355
13356                 case $name in
13357                 read_bytes|write_bytes)
13358                         [[ "$unit" =~ "bytes" ]] ||
13359                                 error "unit is not 'bytes': $unit"
13360                         (( $min >= 4096 )) || error "min is too small: $min"
13361                         (( $min <= $fsize )) || error "min is too big: $min"
13362                         (( $max >= 4096 )) || error "max is too small: $max"
13363                         (( $max <= $fsize )) || error "max is too big: $max"
13364                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13365                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13366                                 error "sumsquare is too small: $sumsq"
13367                         (( $sumsq <= $fsize * $fsize )) ||
13368                                 error "sumsquare is too big: $sumsq"
13369                         ;;
13370                 ost_read|ost_write)
13371                         [[ "$unit" =~ "usec" ]] ||
13372                                 error "unit is not 'usec': $unit"
13373                         ;;
13374                 *)      ;;
13375                 esac
13376         done < $DIR/$tfile.tmp
13377
13378         #check that we actually got some stats
13379         [ "$read_bytes" ] || error "Missing read_bytes stats"
13380         [ "$write_bytes" ] || error "Missing write_bytes stats"
13381         [ "$read_bytes" != 0 ] || error "no read done"
13382         [ "$write_bytes" != 0 ] || error "no write done"
13383 }
13384 run_test 127a "verify the client stats are sane"
13385
13386 test_127b() { # bug LU-333
13387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13388         local name count samp unit min max sum sumsq
13389
13390         echo "stats before reset"
13391         $LCTL get_param llite.*.stats
13392         $LCTL set_param llite.*.stats=0
13393
13394         # perform 2 reads and writes so MAX is different from SUM.
13395         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13396         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13397         cancel_lru_locks osc
13398         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13399         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13400
13401         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13402         stack_trap "rm -f $TMP/$tfile.tmp"
13403         while read name count samp unit min max sum sumsq; do
13404                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13405                 eval $name=$count || error "Wrong proc format"
13406
13407                 case $name in
13408                 read_bytes|write_bytes)
13409                         [[ "$unit" =~ "bytes" ]] ||
13410                                 error "unit is not 'bytes': $unit"
13411                         (( $count == 2 )) || error "count is not 2: $count"
13412                         (( $min == $PAGE_SIZE )) ||
13413                                 error "min is not $PAGE_SIZE: $min"
13414                         (( $max == $PAGE_SIZE )) ||
13415                                 error "max is not $PAGE_SIZE: $max"
13416                         (( $sum == $PAGE_SIZE * 2 )) ||
13417                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13418                         ;;
13419                 read|write)
13420                         [[ "$unit" =~ "usec" ]] ||
13421                                 error "unit is not 'usec': $unit"
13422                         ;;
13423                 *)      ;;
13424                 esac
13425         done < $TMP/$tfile.tmp
13426
13427         #check that we actually got some stats
13428         [ "$read_bytes" ] || error "Missing read_bytes stats"
13429         [ "$write_bytes" ] || error "Missing write_bytes stats"
13430         [ "$read_bytes" != 0 ] || error "no read done"
13431         [ "$write_bytes" != 0 ] || error "no write done"
13432 }
13433 run_test 127b "verify the llite client stats are sane"
13434
13435 test_127c() { # LU-12394
13436         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13437         local size
13438         local bsize
13439         local reads
13440         local writes
13441         local count
13442
13443         $LCTL set_param llite.*.extents_stats=1
13444         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13445
13446         # Use two stripes so there is enough space in default config
13447         $LFS setstripe -c 2 $DIR/$tfile
13448
13449         # Extent stats start at 0-4K and go in power of two buckets
13450         # LL_HIST_START = 12 --> 2^12 = 4K
13451         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13452         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13453         # small configs
13454         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13455                 do
13456                 # Write and read, 2x each, second time at a non-zero offset
13457                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13458                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13459                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13460                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13461                 rm -f $DIR/$tfile
13462         done
13463
13464         $LCTL get_param llite.*.extents_stats
13465
13466         count=2
13467         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13468                 do
13469                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13470                                 grep -m 1 $bsize)
13471                 reads=$(echo $bucket | awk '{print $5}')
13472                 writes=$(echo $bucket | awk '{print $9}')
13473                 [ "$reads" -eq $count ] ||
13474                         error "$reads reads in < $bsize bucket, expect $count"
13475                 [ "$writes" -eq $count ] ||
13476                         error "$writes writes in < $bsize bucket, expect $count"
13477         done
13478
13479         # Test mmap write and read
13480         $LCTL set_param llite.*.extents_stats=c
13481         size=512
13482         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13483         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13484         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13485
13486         $LCTL get_param llite.*.extents_stats
13487
13488         count=$(((size*1024) / PAGE_SIZE))
13489
13490         bsize=$((2 * PAGE_SIZE / 1024))K
13491
13492         bucket=$($LCTL get_param -n llite.*.extents_stats |
13493                         grep -m 1 $bsize)
13494         reads=$(echo $bucket | awk '{print $5}')
13495         writes=$(echo $bucket | awk '{print $9}')
13496         # mmap writes fault in the page first, creating an additonal read
13497         [ "$reads" -eq $((2 * count)) ] ||
13498                 error "$reads reads in < $bsize bucket, expect $count"
13499         [ "$writes" -eq $count ] ||
13500                 error "$writes writes in < $bsize bucket, expect $count"
13501 }
13502 run_test 127c "test llite extent stats with regular & mmap i/o"
13503
13504 test_128() { # bug 15212
13505         touch $DIR/$tfile
13506         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13507                 find $DIR/$tfile
13508                 find $DIR/$tfile
13509         EOF
13510
13511         result=$(grep error $TMP/$tfile.log)
13512         rm -f $DIR/$tfile $TMP/$tfile.log
13513         [ -z "$result" ] ||
13514                 error "consecutive find's under interactive lfs failed"
13515 }
13516 run_test 128 "interactive lfs for 2 consecutive find's"
13517
13518 set_dir_limits () {
13519         local mntdev
13520         local canondev
13521         local node
13522
13523         local ldproc=/proc/fs/ldiskfs
13524         local facets=$(get_facets MDS)
13525
13526         for facet in ${facets//,/ }; do
13527                 canondev=$(ldiskfs_canon \
13528                            *.$(convert_facet2label $facet).mntdev $facet)
13529                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13530                         ldproc=/sys/fs/ldiskfs
13531                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13532                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13533         done
13534 }
13535
13536 check_mds_dmesg() {
13537         local facets=$(get_facets MDS)
13538         for facet in ${facets//,/ }; do
13539                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13540         done
13541         return 1
13542 }
13543
13544 test_129() {
13545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13546         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13547                 skip "Need MDS version with at least 2.5.56"
13548         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13549                 skip_env "ldiskfs only test"
13550         fi
13551         remote_mds_nodsh && skip "remote MDS with nodsh"
13552
13553         local ENOSPC=28
13554         local has_warning=false
13555
13556         rm -rf $DIR/$tdir
13557         mkdir -p $DIR/$tdir
13558
13559         # block size of mds1
13560         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13561         set_dir_limits $maxsize $((maxsize * 6 / 8))
13562         stack_trap "set_dir_limits 0 0"
13563         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13564         local dirsize=$(stat -c%s "$DIR/$tdir")
13565         local nfiles=0
13566         while (( $dirsize <= $maxsize )); do
13567                 $MCREATE $DIR/$tdir/file_base_$nfiles
13568                 rc=$?
13569                 # check two errors:
13570                 # ENOSPC for ext4 max_dir_size, which has been used since
13571                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13572                 if (( rc == ENOSPC )); then
13573                         set_dir_limits 0 0
13574                         echo "rc=$rc returned as expected after $nfiles files"
13575
13576                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13577                                 error "create failed w/o dir size limit"
13578
13579                         # messages may be rate limited if test is run repeatedly
13580                         check_mds_dmesg '"is approaching max"' ||
13581                                 echo "warning message should be output"
13582                         check_mds_dmesg '"has reached max"' ||
13583                                 echo "reached message should be output"
13584
13585                         dirsize=$(stat -c%s "$DIR/$tdir")
13586
13587                         [[ $dirsize -ge $maxsize ]] && return 0
13588                         error "dirsize $dirsize < $maxsize after $nfiles files"
13589                 elif (( rc != 0 )); then
13590                         break
13591                 fi
13592                 nfiles=$((nfiles + 1))
13593                 dirsize=$(stat -c%s "$DIR/$tdir")
13594         done
13595
13596         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13597 }
13598 run_test 129 "test directory size limit ========================"
13599
13600 OLDIFS="$IFS"
13601 cleanup_130() {
13602         trap 0
13603         IFS="$OLDIFS"
13604 }
13605
13606 test_130a() {
13607         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13608         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13609
13610         trap cleanup_130 EXIT RETURN
13611
13612         local fm_file=$DIR/$tfile
13613         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13614         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13615                 error "dd failed for $fm_file"
13616
13617         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13618         filefrag -ves $fm_file
13619         RC=$?
13620         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13621                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13622         [ $RC != 0 ] && error "filefrag $fm_file failed"
13623
13624         filefrag_op=$(filefrag -ve -k $fm_file |
13625                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13626         lun=$($LFS getstripe -i $fm_file)
13627
13628         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13629         IFS=$'\n'
13630         tot_len=0
13631         for line in $filefrag_op
13632         do
13633                 frag_lun=`echo $line | cut -d: -f5`
13634                 ext_len=`echo $line | cut -d: -f4`
13635                 if (( $frag_lun != $lun )); then
13636                         cleanup_130
13637                         error "FIEMAP on 1-stripe file($fm_file) failed"
13638                         return
13639                 fi
13640                 (( tot_len += ext_len ))
13641         done
13642
13643         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13644                 cleanup_130
13645                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13646                 return
13647         fi
13648
13649         cleanup_130
13650
13651         echo "FIEMAP on single striped file succeeded"
13652 }
13653 run_test 130a "FIEMAP (1-stripe file)"
13654
13655 test_130b() {
13656         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13657
13658         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13659         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13660
13661         trap cleanup_130 EXIT RETURN
13662
13663         local fm_file=$DIR/$tfile
13664         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13665                         error "setstripe on $fm_file"
13666         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13667                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13668
13669         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13670                 error "dd failed on $fm_file"
13671
13672         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13673         filefrag_op=$(filefrag -ve -k $fm_file |
13674                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13675
13676         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13677                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13678
13679         IFS=$'\n'
13680         tot_len=0
13681         num_luns=1
13682         for line in $filefrag_op
13683         do
13684                 frag_lun=$(echo $line | cut -d: -f5 |
13685                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13686                 ext_len=$(echo $line | cut -d: -f4)
13687                 if (( $frag_lun != $last_lun )); then
13688                         if (( tot_len != 1024 )); then
13689                                 cleanup_130
13690                                 error "FIEMAP on $fm_file failed; returned " \
13691                                 "len $tot_len for OST $last_lun instead of 1024"
13692                                 return
13693                         else
13694                                 (( num_luns += 1 ))
13695                                 tot_len=0
13696                         fi
13697                 fi
13698                 (( tot_len += ext_len ))
13699                 last_lun=$frag_lun
13700         done
13701         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13702                 cleanup_130
13703                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13704                         "luns or wrong len for OST $last_lun"
13705                 return
13706         fi
13707
13708         cleanup_130
13709
13710         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13711 }
13712 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13713
13714 test_130c() {
13715         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13716
13717         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13718         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13719
13720         trap cleanup_130 EXIT RETURN
13721
13722         local fm_file=$DIR/$tfile
13723         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13724         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13725                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13726
13727         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
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                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13747                         if (( logical != 512 )); then
13748                                 cleanup_130
13749                                 error "FIEMAP on $fm_file failed; returned " \
13750                                 "logical start for lun $logical instead of 512"
13751                                 return
13752                         fi
13753                         if (( tot_len != 512 )); then
13754                                 cleanup_130
13755                                 error "FIEMAP on $fm_file failed; returned " \
13756                                 "len $tot_len for OST $last_lun instead of 1024"
13757                                 return
13758                         else
13759                                 (( num_luns += 1 ))
13760                                 tot_len=0
13761                         fi
13762                 fi
13763                 (( tot_len += ext_len ))
13764                 last_lun=$frag_lun
13765         done
13766         if (( num_luns != 2 || tot_len != 512 )); then
13767                 cleanup_130
13768                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13769                         "luns or wrong len for OST $last_lun"
13770                 return
13771         fi
13772
13773         cleanup_130
13774
13775         echo "FIEMAP on 2-stripe file with hole succeeded"
13776 }
13777 run_test 130c "FIEMAP (2-stripe file with hole)"
13778
13779 test_130d() {
13780         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13781
13782         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13783         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13784
13785         trap cleanup_130 EXIT RETURN
13786
13787         local fm_file=$DIR/$tfile
13788         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13789                         error "setstripe on $fm_file"
13790         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13791                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13792
13793         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13794         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13795                 error "dd failed on $fm_file"
13796
13797         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13798         filefrag_op=$(filefrag -ve -k $fm_file |
13799                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13800
13801         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13802                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13803
13804         IFS=$'\n'
13805         tot_len=0
13806         num_luns=1
13807         for line in $filefrag_op
13808         do
13809                 frag_lun=$(echo $line | cut -d: -f5 |
13810                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13811                 ext_len=$(echo $line | cut -d: -f4)
13812                 if (( $frag_lun != $last_lun )); then
13813                         if (( tot_len != 1024 )); then
13814                                 cleanup_130
13815                                 error "FIEMAP on $fm_file failed; returned " \
13816                                 "len $tot_len for OST $last_lun instead of 1024"
13817                                 return
13818                         else
13819                                 (( num_luns += 1 ))
13820                                 tot_len=0
13821                         fi
13822                 fi
13823                 (( tot_len += ext_len ))
13824                 last_lun=$frag_lun
13825         done
13826         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13827                 cleanup_130
13828                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13829                         "luns or wrong len for OST $last_lun"
13830                 return
13831         fi
13832
13833         cleanup_130
13834
13835         echo "FIEMAP on N-stripe file succeeded"
13836 }
13837 run_test 130d "FIEMAP (N-stripe file)"
13838
13839 test_130e() {
13840         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13841
13842         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13843         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13844
13845         trap cleanup_130 EXIT RETURN
13846
13847         local fm_file=$DIR/$tfile
13848         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13849
13850         NUM_BLKS=512
13851         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13852         for ((i = 0; i < $NUM_BLKS; i++)); do
13853                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13854                         conv=notrunc > /dev/null 2>&1
13855         done
13856
13857         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13858         filefrag_op=$(filefrag -ve -k $fm_file |
13859                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13860
13861         last_lun=$(echo $filefrag_op | cut -d: -f5)
13862
13863         IFS=$'\n'
13864         tot_len=0
13865         num_luns=1
13866         for line in $filefrag_op; do
13867                 frag_lun=$(echo $line | cut -d: -f5)
13868                 ext_len=$(echo $line | cut -d: -f4)
13869                 if [[ "$frag_lun" != "$last_lun" ]]; then
13870                         if (( tot_len != $EXPECTED_LEN )); then
13871                                 cleanup_130
13872                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13873                         else
13874                                 (( num_luns += 1 ))
13875                                 tot_len=0
13876                         fi
13877                 fi
13878                 (( tot_len += ext_len ))
13879                 last_lun=$frag_lun
13880         done
13881         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13882                 cleanup_130
13883                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13884         fi
13885
13886         echo "FIEMAP with continuation calls succeeded"
13887 }
13888 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13889
13890 test_130f() {
13891         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13892         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13893
13894         local fm_file=$DIR/$tfile
13895         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13896                 error "multiop create with lov_delay_create on $fm_file"
13897
13898         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13899         filefrag_extents=$(filefrag -vek $fm_file |
13900                            awk '/extents? found/ { print $2 }')
13901         if [[ "$filefrag_extents" != "0" ]]; then
13902                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13903         fi
13904
13905         rm -f $fm_file
13906 }
13907 run_test 130f "FIEMAP (unstriped file)"
13908
13909 test_130g() {
13910         local file=$DIR/$tfile
13911         local nr=$((OSTCOUNT * 100))
13912
13913         $LFS setstripe -C $nr $file ||
13914                 error "failed to setstripe -C $nr $file"
13915
13916         dd if=/dev/zero of=$file count=$nr bs=1M
13917         sync
13918         nr=$($LFS getstripe -c $file)
13919
13920         local extents=$(filefrag -v $file |
13921                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13922
13923         echo "filefrag list $extents extents in file with stripecount $nr"
13924         if (( extents < nr )); then
13925                 $LFS getstripe $file
13926                 filefrag -v $file
13927                 error "filefrag printed $extents < $nr extents"
13928         fi
13929
13930         rm -f $file
13931 }
13932 run_test 130g "FIEMAP (overstripe file)"
13933
13934 # Test for writev/readv
13935 test_131a() {
13936         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13937                 error "writev test failed"
13938         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13939                 error "readv failed"
13940         rm -f $DIR/$tfile
13941 }
13942 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13943
13944 test_131b() {
13945         local fsize=$((524288 + 1048576 + 1572864))
13946         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13947                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13948                         error "append writev test failed"
13949
13950         ((fsize += 1572864 + 1048576))
13951         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13952                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13953                         error "append writev test failed"
13954         rm -f $DIR/$tfile
13955 }
13956 run_test 131b "test append writev"
13957
13958 test_131c() {
13959         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13960         error "NOT PASS"
13961 }
13962 run_test 131c "test read/write on file w/o objects"
13963
13964 test_131d() {
13965         rwv -f $DIR/$tfile -w -n 1 1572864
13966         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13967         if [ "$NOB" != 1572864 ]; then
13968                 error "Short read filed: read $NOB bytes instead of 1572864"
13969         fi
13970         rm -f $DIR/$tfile
13971 }
13972 run_test 131d "test short read"
13973
13974 test_131e() {
13975         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13976         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13977         error "read hitting hole failed"
13978         rm -f $DIR/$tfile
13979 }
13980 run_test 131e "test read hitting hole"
13981
13982 check_stats() {
13983         local facet=$1
13984         local op=$2
13985         local want=${3:-0}
13986         local res
13987
13988         case $facet in
13989         mds*) res=$(do_facet $facet \
13990                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13991                  ;;
13992         ost*) res=$(do_facet $facet \
13993                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13994                  ;;
13995         *) error "Wrong facet '$facet'" ;;
13996         esac
13997         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13998         # if the argument $3 is zero, it means any stat increment is ok.
13999         if [[ $want -gt 0 ]]; then
14000                 local count=$(echo $res | awk '{ print $2 }')
14001                 [[ $count -ne $want ]] &&
14002                         error "The $op counter on $facet is $count, not $want"
14003         fi
14004 }
14005
14006 test_133a() {
14007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14008         remote_ost_nodsh && skip "remote OST with nodsh"
14009         remote_mds_nodsh && skip "remote MDS with nodsh"
14010         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14011                 skip_env "MDS doesn't support rename stats"
14012
14013         local testdir=$DIR/${tdir}/stats_testdir
14014
14015         mkdir -p $DIR/${tdir}
14016
14017         # clear stats.
14018         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14019         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14020
14021         # verify mdt stats first.
14022         mkdir ${testdir} || error "mkdir failed"
14023         check_stats $SINGLEMDS "mkdir" 1
14024         touch ${testdir}/${tfile} || error "touch failed"
14025         check_stats $SINGLEMDS "open" 1
14026         check_stats $SINGLEMDS "close" 1
14027         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14028                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14029                 check_stats $SINGLEMDS "mknod" 2
14030         }
14031         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14032         check_stats $SINGLEMDS "unlink" 1
14033         rm -f ${testdir}/${tfile} || error "file remove failed"
14034         check_stats $SINGLEMDS "unlink" 2
14035
14036         # remove working dir and check mdt stats again.
14037         rmdir ${testdir} || error "rmdir failed"
14038         check_stats $SINGLEMDS "rmdir" 1
14039
14040         local testdir1=$DIR/${tdir}/stats_testdir1
14041         mkdir -p ${testdir}
14042         mkdir -p ${testdir1}
14043         touch ${testdir1}/test1
14044         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14045         check_stats $SINGLEMDS "crossdir_rename" 1
14046
14047         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14048         check_stats $SINGLEMDS "samedir_rename" 1
14049
14050         rm -rf $DIR/${tdir}
14051 }
14052 run_test 133a "Verifying MDT stats ========================================"
14053
14054 test_133b() {
14055         local res
14056
14057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14058         remote_ost_nodsh && skip "remote OST with nodsh"
14059         remote_mds_nodsh && skip "remote MDS with nodsh"
14060
14061         local testdir=$DIR/${tdir}/stats_testdir
14062
14063         mkdir -p ${testdir} || error "mkdir failed"
14064         touch ${testdir}/${tfile} || error "touch failed"
14065         cancel_lru_locks mdc
14066
14067         # clear stats.
14068         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14069         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14070
14071         # extra mdt stats verification.
14072         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14073         check_stats $SINGLEMDS "setattr" 1
14074         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14075         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14076         then            # LU-1740
14077                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14078                 check_stats $SINGLEMDS "getattr" 1
14079         fi
14080         rm -rf $DIR/${tdir}
14081
14082         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14083         # so the check below is not reliable
14084         [ $MDSCOUNT -eq 1 ] || return 0
14085
14086         # Sleep to avoid a cached response.
14087         #define OBD_STATFS_CACHE_SECONDS 1
14088         sleep 2
14089         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14090         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14091         $LFS df || error "lfs failed"
14092         check_stats $SINGLEMDS "statfs" 1
14093
14094         # check aggregated statfs (LU-10018)
14095         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14096                 return 0
14097         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14098                 return 0
14099         sleep 2
14100         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14101         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14102         df $DIR
14103         check_stats $SINGLEMDS "statfs" 1
14104
14105         # We want to check that the client didn't send OST_STATFS to
14106         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14107         # extra care is needed here.
14108         if remote_mds; then
14109                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14110                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14111
14112                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14113                 [ "$res" ] && error "OST got STATFS"
14114         fi
14115
14116         return 0
14117 }
14118 run_test 133b "Verifying extra MDT stats =================================="
14119
14120 test_133c() {
14121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14122         remote_ost_nodsh && skip "remote OST with nodsh"
14123         remote_mds_nodsh && skip "remote MDS with nodsh"
14124
14125         local testdir=$DIR/$tdir/stats_testdir
14126
14127         test_mkdir -p $testdir
14128
14129         # verify obdfilter stats.
14130         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14131         sync
14132         cancel_lru_locks osc
14133         wait_delete_completed
14134
14135         # clear stats.
14136         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14137         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14138
14139         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14140                 error "dd failed"
14141         sync
14142         cancel_lru_locks osc
14143         check_stats ost1 "write" 1
14144
14145         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14146         check_stats ost1 "read" 1
14147
14148         > $testdir/$tfile || error "truncate failed"
14149         check_stats ost1 "punch" 1
14150
14151         rm -f $testdir/$tfile || error "file remove failed"
14152         wait_delete_completed
14153         check_stats ost1 "destroy" 1
14154
14155         rm -rf $DIR/$tdir
14156 }
14157 run_test 133c "Verifying OST stats ========================================"
14158
14159 order_2() {
14160         local value=$1
14161         local orig=$value
14162         local order=1
14163
14164         while [ $value -ge 2 ]; do
14165                 order=$((order*2))
14166                 value=$((value/2))
14167         done
14168
14169         if [ $orig -gt $order ]; then
14170                 order=$((order*2))
14171         fi
14172         echo $order
14173 }
14174
14175 size_in_KMGT() {
14176     local value=$1
14177     local size=('K' 'M' 'G' 'T');
14178     local i=0
14179     local size_string=$value
14180
14181     while [ $value -ge 1024 ]; do
14182         if [ $i -gt 3 ]; then
14183             #T is the biggest unit we get here, if that is bigger,
14184             #just return XXXT
14185             size_string=${value}T
14186             break
14187         fi
14188         value=$((value >> 10))
14189         if [ $value -lt 1024 ]; then
14190             size_string=${value}${size[$i]}
14191             break
14192         fi
14193         i=$((i + 1))
14194     done
14195
14196     echo $size_string
14197 }
14198
14199 get_rename_size() {
14200         local size=$1
14201         local context=${2:-.}
14202         local sample=$(do_facet $SINGLEMDS $LCTL \
14203                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14204                 grep -A1 $context |
14205                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14206         echo $sample
14207 }
14208
14209 test_133d() {
14210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14211         remote_ost_nodsh && skip "remote OST with nodsh"
14212         remote_mds_nodsh && skip "remote MDS with nodsh"
14213         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14214                 skip_env "MDS doesn't support rename stats"
14215
14216         local testdir1=$DIR/${tdir}/stats_testdir1
14217         local testdir2=$DIR/${tdir}/stats_testdir2
14218         mkdir -p $DIR/${tdir}
14219
14220         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14221
14222         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14223         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14224
14225         createmany -o $testdir1/test 512 || error "createmany failed"
14226
14227         # check samedir rename size
14228         mv ${testdir1}/test0 ${testdir1}/test_0
14229
14230         local testdir1_size=$(ls -l $DIR/${tdir} |
14231                 awk '/stats_testdir1/ {print $5}')
14232         local testdir2_size=$(ls -l $DIR/${tdir} |
14233                 awk '/stats_testdir2/ {print $5}')
14234
14235         testdir1_size=$(order_2 $testdir1_size)
14236         testdir2_size=$(order_2 $testdir2_size)
14237
14238         testdir1_size=$(size_in_KMGT $testdir1_size)
14239         testdir2_size=$(size_in_KMGT $testdir2_size)
14240
14241         echo "source rename dir size: ${testdir1_size}"
14242         echo "target rename dir size: ${testdir2_size}"
14243
14244         local cmd="do_facet $SINGLEMDS $LCTL "
14245         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14246
14247         eval $cmd || error "$cmd failed"
14248         local samedir=$($cmd | grep 'same_dir')
14249         local same_sample=$(get_rename_size $testdir1_size)
14250         [ -z "$samedir" ] && error "samedir_rename_size count error"
14251         [[ $same_sample -eq 1 ]] ||
14252                 error "samedir_rename_size error $same_sample"
14253         echo "Check same dir rename stats success"
14254
14255         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14256
14257         # check crossdir rename size
14258         mv ${testdir1}/test_0 ${testdir2}/test_0
14259
14260         testdir1_size=$(ls -l $DIR/${tdir} |
14261                 awk '/stats_testdir1/ {print $5}')
14262         testdir2_size=$(ls -l $DIR/${tdir} |
14263                 awk '/stats_testdir2/ {print $5}')
14264
14265         testdir1_size=$(order_2 $testdir1_size)
14266         testdir2_size=$(order_2 $testdir2_size)
14267
14268         testdir1_size=$(size_in_KMGT $testdir1_size)
14269         testdir2_size=$(size_in_KMGT $testdir2_size)
14270
14271         echo "source rename dir size: ${testdir1_size}"
14272         echo "target rename dir size: ${testdir2_size}"
14273
14274         eval $cmd || error "$cmd failed"
14275         local crossdir=$($cmd | grep 'crossdir')
14276         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14277         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14278         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14279         [[ $src_sample -eq 1 ]] ||
14280                 error "crossdir_rename_size error $src_sample"
14281         [[ $tgt_sample -eq 1 ]] ||
14282                 error "crossdir_rename_size error $tgt_sample"
14283         echo "Check cross dir rename stats success"
14284         rm -rf $DIR/${tdir}
14285 }
14286 run_test 133d "Verifying rename_stats ========================================"
14287
14288 test_133e() {
14289         remote_mds_nodsh && skip "remote MDS with nodsh"
14290         remote_ost_nodsh && skip "remote OST with nodsh"
14291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14292
14293         local testdir=$DIR/${tdir}/stats_testdir
14294         local ctr f0 f1 bs=32768 count=42 sum
14295
14296         mkdir -p ${testdir} || error "mkdir failed"
14297
14298         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14299
14300         for ctr in {write,read}_bytes; do
14301                 sync
14302                 cancel_lru_locks osc
14303
14304                 do_facet ost1 $LCTL set_param -n \
14305                         "obdfilter.*.exports.clear=clear"
14306
14307                 if [ $ctr = write_bytes ]; then
14308                         f0=/dev/zero
14309                         f1=${testdir}/${tfile}
14310                 else
14311                         f0=${testdir}/${tfile}
14312                         f1=/dev/null
14313                 fi
14314
14315                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14316                         error "dd failed"
14317                 sync
14318                 cancel_lru_locks osc
14319
14320                 sum=$(do_facet ost1 $LCTL get_param \
14321                         "obdfilter.*.exports.*.stats" |
14322                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14323                                 $1 == ctr { sum += $7 }
14324                                 END { printf("%0.0f", sum) }')
14325
14326                 if ((sum != bs * count)); then
14327                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14328                 fi
14329         done
14330
14331         rm -rf $DIR/${tdir}
14332 }
14333 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14334
14335 test_133f() {
14336         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14337                 skip "too old lustre for get_param -R ($facet_ver)"
14338
14339         # verifying readability.
14340         $LCTL get_param -R '*' &> /dev/null
14341
14342         # Verifing writability with badarea_io.
14343         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14344         local skipped_params='force_lbug|changelog_mask|daemon_file'
14345         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14346                 egrep -v "$skipped_params" |
14347                 xargs -n 1 find $proc_dirs -name |
14348                 xargs -n 1 badarea_io ||
14349                 error "client badarea_io failed"
14350
14351         # remount the FS in case writes/reads /proc break the FS
14352         cleanup || error "failed to unmount"
14353         setup || error "failed to setup"
14354 }
14355 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14356
14357 test_133g() {
14358         remote_mds_nodsh && skip "remote MDS with nodsh"
14359         remote_ost_nodsh && skip "remote OST with nodsh"
14360
14361         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14362         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14363         local facet
14364         for facet in mds1 ost1; do
14365                 local facet_ver=$(lustre_version_code $facet)
14366                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14367                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14368                 else
14369                         log "$facet: too old lustre for get_param -R"
14370                 fi
14371                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14372                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14373                                 tr -d = | egrep -v $skipped_params |
14374                                 xargs -n 1 find $proc_dirs -name |
14375                                 xargs -n 1 badarea_io" ||
14376                                         error "$facet badarea_io failed"
14377                 else
14378                         skip_noexit "$facet: too old lustre for get_param -R"
14379                 fi
14380         done
14381
14382         # remount the FS in case writes/reads /proc break the FS
14383         cleanup || error "failed to unmount"
14384         setup || error "failed to setup"
14385 }
14386 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14387
14388 test_133h() {
14389         remote_mds_nodsh && skip "remote MDS with nodsh"
14390         remote_ost_nodsh && skip "remote OST with nodsh"
14391         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14392                 skip "Need MDS version at least 2.9.54"
14393
14394         local facet
14395         for facet in client mds1 ost1; do
14396                 # Get the list of files that are missing the terminating newline
14397                 local plist=$(do_facet $facet
14398                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14399                 local ent
14400                 for ent in $plist; do
14401                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14402                                 awk -v FS='\v' -v RS='\v\v' \
14403                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14404                                         print FILENAME}'" 2>/dev/null)
14405                         [ -z $missing ] || {
14406                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14407                                 error "file does not end with newline: $facet-$ent"
14408                         }
14409                 done
14410         done
14411 }
14412 run_test 133h "Proc files should end with newlines"
14413
14414 test_134a() {
14415         remote_mds_nodsh && skip "remote MDS with nodsh"
14416         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14417                 skip "Need MDS version at least 2.7.54"
14418
14419         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14420         cancel_lru_locks mdc
14421
14422         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14423         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14424         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14425
14426         local nr=1000
14427         createmany -o $DIR/$tdir/f $nr ||
14428                 error "failed to create $nr files in $DIR/$tdir"
14429         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14430
14431         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14432         do_facet mds1 $LCTL set_param fail_loc=0x327
14433         do_facet mds1 $LCTL set_param fail_val=500
14434         touch $DIR/$tdir/m
14435
14436         echo "sleep 10 seconds ..."
14437         sleep 10
14438         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14439
14440         do_facet mds1 $LCTL set_param fail_loc=0
14441         do_facet mds1 $LCTL set_param fail_val=0
14442         [ $lck_cnt -lt $unused ] ||
14443                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14444
14445         rm $DIR/$tdir/m
14446         unlinkmany $DIR/$tdir/f $nr
14447 }
14448 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14449
14450 test_134b() {
14451         remote_mds_nodsh && skip "remote MDS with nodsh"
14452         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14453                 skip "Need MDS version at least 2.7.54"
14454
14455         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14456         cancel_lru_locks mdc
14457
14458         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14459                         ldlm.lock_reclaim_threshold_mb)
14460         # disable reclaim temporarily
14461         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14462
14463         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14464         do_facet mds1 $LCTL set_param fail_loc=0x328
14465         do_facet mds1 $LCTL set_param fail_val=500
14466
14467         $LCTL set_param debug=+trace
14468
14469         local nr=600
14470         createmany -o $DIR/$tdir/f $nr &
14471         local create_pid=$!
14472
14473         echo "Sleep $TIMEOUT seconds ..."
14474         sleep $TIMEOUT
14475         if ! ps -p $create_pid  > /dev/null 2>&1; then
14476                 do_facet mds1 $LCTL set_param fail_loc=0
14477                 do_facet mds1 $LCTL set_param fail_val=0
14478                 do_facet mds1 $LCTL set_param \
14479                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14480                 error "createmany finished incorrectly!"
14481         fi
14482         do_facet mds1 $LCTL set_param fail_loc=0
14483         do_facet mds1 $LCTL set_param fail_val=0
14484         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14485         wait $create_pid || return 1
14486
14487         unlinkmany $DIR/$tdir/f $nr
14488 }
14489 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14490
14491 test_135() {
14492         remote_mds_nodsh && skip "remote MDS with nodsh"
14493         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14494                 skip "Need MDS version at least 2.13.50"
14495         local fname
14496
14497         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14498
14499 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14500         #set only one record at plain llog
14501         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14502
14503         #fill already existed plain llog each 64767
14504         #wrapping whole catalog
14505         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14506
14507         createmany -o $DIR/$tdir/$tfile_ 64700
14508         for (( i = 0; i < 64700; i = i + 2 ))
14509         do
14510                 rm $DIR/$tdir/$tfile_$i &
14511                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14512                 local pid=$!
14513                 wait $pid
14514         done
14515
14516         #waiting osp synchronization
14517         wait_delete_completed
14518 }
14519 run_test 135 "Race catalog processing"
14520
14521 test_136() {
14522         remote_mds_nodsh && skip "remote MDS with nodsh"
14523         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14524                 skip "Need MDS version at least 2.13.50"
14525         local fname
14526
14527         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14528         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14529         #set only one record at plain llog
14530 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14531         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14532
14533         #fill already existed 2 plain llogs each 64767
14534         #wrapping whole catalog
14535         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14536         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14537         wait_delete_completed
14538
14539         createmany -o $DIR/$tdir/$tfile_ 10
14540         sleep 25
14541
14542         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14543         for (( i = 0; i < 10; i = i + 3 ))
14544         do
14545                 rm $DIR/$tdir/$tfile_$i &
14546                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14547                 local pid=$!
14548                 wait $pid
14549                 sleep 7
14550                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14551         done
14552
14553         #waiting osp synchronization
14554         wait_delete_completed
14555 }
14556 run_test 136 "Race catalog processing 2"
14557
14558 test_140() { #bug-17379
14559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14560
14561         test_mkdir $DIR/$tdir
14562         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14563         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14564
14565         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14566         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14567         local i=0
14568         while i=$((i + 1)); do
14569                 test_mkdir $i
14570                 cd $i || error "Changing to $i"
14571                 ln -s ../stat stat || error "Creating stat symlink"
14572                 # Read the symlink until ELOOP present,
14573                 # not LBUGing the system is considered success,
14574                 # we didn't overrun the stack.
14575                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14576                 if [ $ret -ne 0 ]; then
14577                         if [ $ret -eq 40 ]; then
14578                                 break  # -ELOOP
14579                         else
14580                                 error "Open stat symlink"
14581                                         return
14582                         fi
14583                 fi
14584         done
14585         i=$((i - 1))
14586         echo "The symlink depth = $i"
14587         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14588                 error "Invalid symlink depth"
14589
14590         # Test recursive symlink
14591         ln -s symlink_self symlink_self
14592         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14593         echo "open symlink_self returns $ret"
14594         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14595 }
14596 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14597
14598 test_150a() {
14599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14600
14601         local TF="$TMP/$tfile"
14602
14603         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14604         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14605         cp $TF $DIR/$tfile
14606         cancel_lru_locks $OSC
14607         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14608         remount_client $MOUNT
14609         df -P $MOUNT
14610         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14611
14612         $TRUNCATE $TF 6000
14613         $TRUNCATE $DIR/$tfile 6000
14614         cancel_lru_locks $OSC
14615         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14616
14617         echo "12345" >>$TF
14618         echo "12345" >>$DIR/$tfile
14619         cancel_lru_locks $OSC
14620         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14621
14622         echo "12345" >>$TF
14623         echo "12345" >>$DIR/$tfile
14624         cancel_lru_locks $OSC
14625         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14626 }
14627 run_test 150a "truncate/append tests"
14628
14629 test_150b() {
14630         check_set_fallocate_or_skip
14631
14632         touch $DIR/$tfile
14633         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14634         check_fallocate $DIR/$tfile || error "fallocate failed"
14635 }
14636 run_test 150b "Verify fallocate (prealloc) functionality"
14637
14638 test_150bb() {
14639         check_set_fallocate_or_skip
14640
14641         touch $DIR/$tfile
14642         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14643         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14644         > $DIR/$tfile
14645         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14646         # precomputed md5sum for 20MB of zeroes
14647         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14648         local sum=($(md5sum $DIR/$tfile))
14649
14650         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14651
14652         check_set_fallocate 1
14653
14654         > $DIR/$tfile
14655         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14656         sum=($(md5sum $DIR/$tfile))
14657
14658         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14659 }
14660 run_test 150bb "Verify fallocate modes both zero space"
14661
14662 test_150c() {
14663         check_set_fallocate_or_skip
14664         local striping="-c2"
14665
14666         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14667         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14668         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14669         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14670         local want=$((OSTCOUNT * 1048576))
14671
14672         # Must allocate all requested space, not more than 5% extra
14673         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14674                 error "bytes $bytes is not $want"
14675
14676         rm -f $DIR/$tfile
14677
14678         echo "verify fallocate on PFL file"
14679
14680         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14681
14682         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14683                 error "Create $DIR/$tfile failed"
14684         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14685                         error "fallocate failed"
14686         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14687         want=$((512 * 1048576))
14688
14689         # Must allocate all requested space, not more than 5% extra
14690         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14691                 error "bytes $bytes is not $want"
14692 }
14693 run_test 150c "Verify fallocate Size and Blocks"
14694
14695 test_150d() {
14696         check_set_fallocate_or_skip
14697         local striping="-c2"
14698
14699         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14700
14701         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14702         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14703                 error "setstripe failed"
14704         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14705         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14706         local want=$((OSTCOUNT * 1048576))
14707
14708         # Must allocate all requested space, not more than 5% extra
14709         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14710                 error "bytes $bytes is not $want"
14711 }
14712 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14713
14714 test_150e() {
14715         check_set_fallocate_or_skip
14716
14717         echo "df before:"
14718         $LFS df
14719         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14720         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14721                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14722
14723         # Find OST with Minimum Size
14724         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14725                        sort -un | head -1)
14726
14727         # Get 100MB per OST of the available space to reduce run time
14728         # else 60% of the available space if we are running SLOW tests
14729         if [ $SLOW == "no" ]; then
14730                 local space=$((1024 * 100 * OSTCOUNT))
14731         else
14732                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14733         fi
14734
14735         fallocate -l${space}k $DIR/$tfile ||
14736                 error "fallocate ${space}k $DIR/$tfile failed"
14737         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14738
14739         # get size immediately after fallocate. This should be correctly
14740         # updated
14741         local size=$(stat -c '%s' $DIR/$tfile)
14742         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14743
14744         # Sleep for a while for statfs to get updated. And not pull from cache.
14745         sleep 2
14746
14747         echo "df after fallocate:"
14748         $LFS df
14749
14750         (( size / 1024 == space )) || error "size $size != requested $space"
14751         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14752                 error "used $used < space $space"
14753
14754         rm $DIR/$tfile || error "rm failed"
14755         sync
14756         wait_delete_completed
14757
14758         echo "df after unlink:"
14759         $LFS df
14760 }
14761 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14762
14763 test_150f() {
14764         local size
14765         local blocks
14766         local want_size_before=20480 # in bytes
14767         local want_blocks_before=40 # 512 sized blocks
14768         local want_blocks_after=24  # 512 sized blocks
14769         local length=$(((want_blocks_before - want_blocks_after) * 512))
14770
14771         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14772                 skip "need at least 2.14.0 for fallocate punch"
14773
14774         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14775                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14776         fi
14777
14778         check_set_fallocate_or_skip
14779         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14780
14781         [[ "x$DOM" == "xyes" ]] &&
14782                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14783
14784         echo "Verify fallocate punch: Range within the file range"
14785         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14786                 error "dd failed for bs 4096 and count 5"
14787
14788         # Call fallocate with punch range which is within the file range
14789         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14790                 error "fallocate failed: offset 4096 and length $length"
14791         # client must see changes immediately after fallocate
14792         size=$(stat -c '%s' $DIR/$tfile)
14793         blocks=$(stat -c '%b' $DIR/$tfile)
14794
14795         # Verify punch worked.
14796         (( blocks == want_blocks_after )) ||
14797                 error "punch failed: blocks $blocks != $want_blocks_after"
14798
14799         (( size == want_size_before )) ||
14800                 error "punch failed: size $size != $want_size_before"
14801
14802         # Verify there is hole in file
14803         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14804         # precomputed md5sum
14805         local expect="4a9a834a2db02452929c0a348273b4aa"
14806
14807         cksum=($(md5sum $DIR/$tfile))
14808         [[ "${cksum[0]}" == "$expect" ]] ||
14809                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14810
14811         # Start second sub-case for fallocate punch.
14812         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14813         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14814                 error "dd failed for bs 4096 and count 5"
14815
14816         # Punch range less than block size will have no change in block count
14817         want_blocks_after=40  # 512 sized blocks
14818
14819         # Punch overlaps two blocks and less than blocksize
14820         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14821                 error "fallocate failed: offset 4000 length 3000"
14822         size=$(stat -c '%s' $DIR/$tfile)
14823         blocks=$(stat -c '%b' $DIR/$tfile)
14824
14825         # Verify punch worked.
14826         (( blocks == want_blocks_after )) ||
14827                 error "punch failed: blocks $blocks != $want_blocks_after"
14828
14829         (( size == want_size_before )) ||
14830                 error "punch failed: size $size != $want_size_before"
14831
14832         # Verify if range is really zero'ed out. We expect Zeros.
14833         # precomputed md5sum
14834         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14835         cksum=($(md5sum $DIR/$tfile))
14836         [[ "${cksum[0]}" == "$expect" ]] ||
14837                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14838 }
14839 run_test 150f "Verify fallocate punch functionality"
14840
14841 test_150g() {
14842         local space
14843         local size
14844         local blocks
14845         local blocks_after
14846         local size_after
14847         local BS=4096 # Block size in bytes
14848
14849         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14850                 skip "need at least 2.14.0 for fallocate punch"
14851
14852         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14853                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14854         fi
14855
14856         check_set_fallocate_or_skip
14857         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14858
14859         if [[ "x$DOM" == "xyes" ]]; then
14860                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14861                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14862         else
14863                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14864                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14865         fi
14866
14867         # Get 100MB per OST of the available space to reduce run time
14868         # else 60% of the available space if we are running SLOW tests
14869         if [ $SLOW == "no" ]; then
14870                 space=$((1024 * 100 * OSTCOUNT))
14871         else
14872                 # Find OST with Minimum Size
14873                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14874                         sort -un | head -1)
14875                 echo "min size OST: $space"
14876                 space=$(((space * 60)/100 * OSTCOUNT))
14877         fi
14878         # space in 1k units, round to 4k blocks
14879         local blkcount=$((space * 1024 / $BS))
14880
14881         echo "Verify fallocate punch: Very large Range"
14882         fallocate -l${space}k $DIR/$tfile ||
14883                 error "fallocate ${space}k $DIR/$tfile failed"
14884         # write 1M at the end, start and in the middle
14885         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14886                 error "dd failed: bs $BS count 256"
14887         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14888                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14889         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14890                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14891
14892         # Gather stats.
14893         size=$(stat -c '%s' $DIR/$tfile)
14894
14895         # gather punch length.
14896         local punch_size=$((size - (BS * 2)))
14897
14898         echo "punch_size = $punch_size"
14899         echo "size - punch_size: $((size - punch_size))"
14900         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14901
14902         # Call fallocate to punch all except 2 blocks. We leave the
14903         # first and the last block
14904         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14905         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14906                 error "fallocate failed: offset $BS length $punch_size"
14907
14908         size_after=$(stat -c '%s' $DIR/$tfile)
14909         blocks_after=$(stat -c '%b' $DIR/$tfile)
14910
14911         # Verify punch worked.
14912         # Size should be kept
14913         (( size == size_after )) ||
14914                 error "punch failed: size $size != $size_after"
14915
14916         # two 4k data blocks to remain plus possible 1 extra extent block
14917         (( blocks_after <= ((BS / 512) * 3) )) ||
14918                 error "too many blocks remains: $blocks_after"
14919
14920         # Verify that file has hole between the first and the last blocks
14921         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14922         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14923
14924         echo "Hole at [$hole_start, $hole_end)"
14925         (( hole_start == BS )) ||
14926                 error "no hole at offset $BS after punch"
14927
14928         (( hole_end == BS + punch_size )) ||
14929                 error "data at offset $hole_end < $((BS + punch_size))"
14930 }
14931 run_test 150g "Verify fallocate punch on large range"
14932
14933 #LU-2902 roc_hit was not able to read all values from lproc
14934 function roc_hit_init() {
14935         local list=$(comma_list $(osts_nodes))
14936         local dir=$DIR/$tdir-check
14937         local file=$dir/$tfile
14938         local BEFORE
14939         local AFTER
14940         local idx
14941
14942         test_mkdir $dir
14943         #use setstripe to do a write to every ost
14944         for i in $(seq 0 $((OSTCOUNT-1))); do
14945                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14946                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14947                 idx=$(printf %04x $i)
14948                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14949                         awk '$1 == "cache_access" {sum += $7}
14950                                 END { printf("%0.0f", sum) }')
14951
14952                 cancel_lru_locks osc
14953                 cat $file >/dev/null
14954
14955                 AFTER=$(get_osd_param $list *OST*$idx stats |
14956                         awk '$1 == "cache_access" {sum += $7}
14957                                 END { printf("%0.0f", sum) }')
14958
14959                 echo BEFORE:$BEFORE AFTER:$AFTER
14960                 if ! let "AFTER - BEFORE == 4"; then
14961                         rm -rf $dir
14962                         error "roc_hit is not safe to use"
14963                 fi
14964                 rm $file
14965         done
14966
14967         rm -rf $dir
14968 }
14969
14970 function roc_hit() {
14971         local list=$(comma_list $(osts_nodes))
14972         echo $(get_osd_param $list '' stats |
14973                 awk '$1 == "cache_hit" {sum += $7}
14974                         END { printf("%0.0f", sum) }')
14975 }
14976
14977 function set_cache() {
14978         local on=1
14979
14980         if [ "$2" == "off" ]; then
14981                 on=0;
14982         fi
14983         local list=$(comma_list $(osts_nodes))
14984         set_osd_param $list '' $1_cache_enable $on
14985
14986         cancel_lru_locks osc
14987 }
14988
14989 test_151() {
14990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14991         remote_ost_nodsh && skip "remote OST with nodsh"
14992
14993         local CPAGES=3
14994         local list=$(comma_list $(osts_nodes))
14995
14996         # check whether obdfilter is cache capable at all
14997         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14998                 skip "not cache-capable obdfilter"
14999         fi
15000
15001         # check cache is enabled on all obdfilters
15002         if get_osd_param $list '' read_cache_enable | grep 0; then
15003                 skip "oss cache is disabled"
15004         fi
15005
15006         set_osd_param $list '' writethrough_cache_enable 1
15007
15008         # check write cache is enabled on all obdfilters
15009         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15010                 skip "oss write cache is NOT enabled"
15011         fi
15012
15013         roc_hit_init
15014
15015         #define OBD_FAIL_OBD_NO_LRU  0x609
15016         do_nodes $list $LCTL set_param fail_loc=0x609
15017
15018         # pages should be in the case right after write
15019         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15020                 error "dd failed"
15021
15022         local BEFORE=$(roc_hit)
15023         cancel_lru_locks osc
15024         cat $DIR/$tfile >/dev/null
15025         local AFTER=$(roc_hit)
15026
15027         do_nodes $list $LCTL set_param fail_loc=0
15028
15029         if ! let "AFTER - BEFORE == CPAGES"; then
15030                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15031         fi
15032
15033         cancel_lru_locks osc
15034         # invalidates OST cache
15035         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15036         set_osd_param $list '' read_cache_enable 0
15037         cat $DIR/$tfile >/dev/null
15038
15039         # now data shouldn't be found in the cache
15040         BEFORE=$(roc_hit)
15041         cancel_lru_locks osc
15042         cat $DIR/$tfile >/dev/null
15043         AFTER=$(roc_hit)
15044         if let "AFTER - BEFORE != 0"; then
15045                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15046         fi
15047
15048         set_osd_param $list '' read_cache_enable 1
15049         rm -f $DIR/$tfile
15050 }
15051 run_test 151 "test cache on oss and controls ==============================="
15052
15053 test_152() {
15054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15055
15056         local TF="$TMP/$tfile"
15057
15058         # simulate ENOMEM during write
15059 #define OBD_FAIL_OST_NOMEM      0x226
15060         lctl set_param fail_loc=0x80000226
15061         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15062         cp $TF $DIR/$tfile
15063         sync || error "sync failed"
15064         lctl set_param fail_loc=0
15065
15066         # discard client's cache
15067         cancel_lru_locks osc
15068
15069         # simulate ENOMEM during read
15070         lctl set_param fail_loc=0x80000226
15071         cmp $TF $DIR/$tfile || error "cmp failed"
15072         lctl set_param fail_loc=0
15073
15074         rm -f $TF
15075 }
15076 run_test 152 "test read/write with enomem ============================"
15077
15078 test_153() {
15079         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15080 }
15081 run_test 153 "test if fdatasync does not crash ======================="
15082
15083 dot_lustre_fid_permission_check() {
15084         local fid=$1
15085         local ffid=$MOUNT/.lustre/fid/$fid
15086         local test_dir=$2
15087
15088         echo "stat fid $fid"
15089         stat $ffid > /dev/null || error "stat $ffid failed."
15090         echo "touch fid $fid"
15091         touch $ffid || error "touch $ffid failed."
15092         echo "write to fid $fid"
15093         cat /etc/hosts > $ffid || error "write $ffid failed."
15094         echo "read fid $fid"
15095         diff /etc/hosts $ffid || error "read $ffid failed."
15096         echo "append write to fid $fid"
15097         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15098         echo "rename fid $fid"
15099         mv $ffid $test_dir/$tfile.1 &&
15100                 error "rename $ffid to $tfile.1 should fail."
15101         touch $test_dir/$tfile.1
15102         mv $test_dir/$tfile.1 $ffid &&
15103                 error "rename $tfile.1 to $ffid should fail."
15104         rm -f $test_dir/$tfile.1
15105         echo "truncate fid $fid"
15106         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15107         echo "link fid $fid"
15108         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15109         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15110                 echo "setfacl fid $fid"
15111                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15112                 echo "getfacl fid $fid"
15113                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15114         fi
15115         echo "unlink fid $fid"
15116         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15117         echo "mknod fid $fid"
15118         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15119
15120         fid=[0xf00000400:0x1:0x0]
15121         ffid=$MOUNT/.lustre/fid/$fid
15122
15123         echo "stat non-exist fid $fid"
15124         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15125         echo "write to non-exist fid $fid"
15126         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15127         echo "link new fid $fid"
15128         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15129
15130         mkdir -p $test_dir/$tdir
15131         touch $test_dir/$tdir/$tfile
15132         fid=$($LFS path2fid $test_dir/$tdir)
15133         rc=$?
15134         [ $rc -ne 0 ] &&
15135                 error "error: could not get fid for $test_dir/$dir/$tfile."
15136
15137         ffid=$MOUNT/.lustre/fid/$fid
15138
15139         echo "ls $fid"
15140         ls $ffid > /dev/null || error "ls $ffid failed."
15141         echo "touch $fid/$tfile.1"
15142         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15143
15144         echo "touch $MOUNT/.lustre/fid/$tfile"
15145         touch $MOUNT/.lustre/fid/$tfile && \
15146                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15147
15148         echo "setxattr to $MOUNT/.lustre/fid"
15149         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15150
15151         echo "listxattr for $MOUNT/.lustre/fid"
15152         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15153
15154         echo "delxattr from $MOUNT/.lustre/fid"
15155         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15156
15157         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15158         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15159                 error "touch invalid fid should fail."
15160
15161         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15162         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15163                 error "touch non-normal fid should fail."
15164
15165         echo "rename $tdir to $MOUNT/.lustre/fid"
15166         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15167                 error "rename to $MOUNT/.lustre/fid should fail."
15168
15169         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15170         then            # LU-3547
15171                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15172                 local new_obf_mode=777
15173
15174                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15175                 chmod $new_obf_mode $DIR/.lustre/fid ||
15176                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15177
15178                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15179                 [ $obf_mode -eq $new_obf_mode ] ||
15180                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15181
15182                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15183                 chmod $old_obf_mode $DIR/.lustre/fid ||
15184                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15185         fi
15186
15187         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15188         fid=$($LFS path2fid $test_dir/$tfile-2)
15189
15190         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15191         then # LU-5424
15192                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15193                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15194                         error "create lov data thru .lustre failed"
15195         fi
15196         echo "cp /etc/passwd $test_dir/$tfile-2"
15197         cp /etc/passwd $test_dir/$tfile-2 ||
15198                 error "copy to $test_dir/$tfile-2 failed."
15199         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15200         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15201                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15202
15203         rm -rf $test_dir/tfile.lnk
15204         rm -rf $test_dir/$tfile-2
15205 }
15206
15207 test_154A() {
15208         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15209                 skip "Need MDS version at least 2.4.1"
15210
15211         local tf=$DIR/$tfile
15212         touch $tf
15213
15214         local fid=$($LFS path2fid $tf)
15215         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15216
15217         # check that we get the same pathname back
15218         local rootpath
15219         local found
15220         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15221                 echo "$rootpath $fid"
15222                 found=$($LFS fid2path $rootpath "$fid")
15223                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15224                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15225         done
15226
15227         # check wrong root path format
15228         rootpath=$MOUNT"_wrong"
15229         found=$($LFS fid2path $rootpath "$fid")
15230         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15231 }
15232 run_test 154A "lfs path2fid and fid2path basic checks"
15233
15234 test_154B() {
15235         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15236                 skip "Need MDS version at least 2.4.1"
15237
15238         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15239         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15240         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15241         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15242
15243         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15244         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15245
15246         # check that we get the same pathname
15247         echo "PFID: $PFID, name: $name"
15248         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15249         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15250         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15251                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15252
15253         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15254 }
15255 run_test 154B "verify the ll_decode_linkea tool"
15256
15257 test_154a() {
15258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15259         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15260         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15261                 skip "Need MDS version at least 2.2.51"
15262         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15263
15264         cp /etc/hosts $DIR/$tfile
15265
15266         fid=$($LFS path2fid $DIR/$tfile)
15267         rc=$?
15268         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15269
15270         dot_lustre_fid_permission_check "$fid" $DIR ||
15271                 error "dot lustre permission check $fid failed"
15272
15273         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15274
15275         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15276
15277         touch $MOUNT/.lustre/file &&
15278                 error "creation is not allowed under .lustre"
15279
15280         mkdir $MOUNT/.lustre/dir &&
15281                 error "mkdir is not allowed under .lustre"
15282
15283         rm -rf $DIR/$tfile
15284 }
15285 run_test 154a "Open-by-FID"
15286
15287 test_154b() {
15288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15289         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15290         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15291         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15292                 skip "Need MDS version at least 2.2.51"
15293
15294         local remote_dir=$DIR/$tdir/remote_dir
15295         local MDTIDX=1
15296         local rc=0
15297
15298         mkdir -p $DIR/$tdir
15299         $LFS mkdir -i $MDTIDX $remote_dir ||
15300                 error "create remote directory failed"
15301
15302         cp /etc/hosts $remote_dir/$tfile
15303
15304         fid=$($LFS path2fid $remote_dir/$tfile)
15305         rc=$?
15306         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15307
15308         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15309                 error "dot lustre permission check $fid failed"
15310         rm -rf $DIR/$tdir
15311 }
15312 run_test 154b "Open-by-FID for remote directory"
15313
15314 test_154c() {
15315         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15316                 skip "Need MDS version at least 2.4.1"
15317
15318         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15319         local FID1=$($LFS path2fid $DIR/$tfile.1)
15320         local FID2=$($LFS path2fid $DIR/$tfile.2)
15321         local FID3=$($LFS path2fid $DIR/$tfile.3)
15322
15323         local N=1
15324         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15325                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15326                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15327                 local want=FID$N
15328                 [ "$FID" = "${!want}" ] ||
15329                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15330                 N=$((N + 1))
15331         done
15332
15333         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15334         do
15335                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15336                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15337                 N=$((N + 1))
15338         done
15339 }
15340 run_test 154c "lfs path2fid and fid2path multiple arguments"
15341
15342 test_154d() {
15343         remote_mds_nodsh && skip "remote MDS with nodsh"
15344         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15345                 skip "Need MDS version at least 2.5.53"
15346
15347         if remote_mds; then
15348                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15349         else
15350                 nid="0@lo"
15351         fi
15352         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15353         local fd
15354         local cmd
15355
15356         rm -f $DIR/$tfile
15357         touch $DIR/$tfile
15358
15359         local fid=$($LFS path2fid $DIR/$tfile)
15360         # Open the file
15361         fd=$(free_fd)
15362         cmd="exec $fd<$DIR/$tfile"
15363         eval $cmd
15364         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15365         echo "$fid_list" | grep "$fid"
15366         rc=$?
15367
15368         cmd="exec $fd>/dev/null"
15369         eval $cmd
15370         if [ $rc -ne 0 ]; then
15371                 error "FID $fid not found in open files list $fid_list"
15372         fi
15373 }
15374 run_test 154d "Verify open file fid"
15375
15376 test_154e()
15377 {
15378         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15379                 skip "Need MDS version at least 2.6.50"
15380
15381         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15382                 error ".lustre returned by readdir"
15383         fi
15384 }
15385 run_test 154e ".lustre is not returned by readdir"
15386
15387 test_154f() {
15388         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15389
15390         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15391         mkdir_on_mdt0 $DIR/$tdir
15392         # test dirs inherit from its stripe
15393         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15394         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15395         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15396         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15397         touch $DIR/f
15398
15399         # get fid of parents
15400         local FID0=$($LFS path2fid $DIR/$tdir)
15401         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15402         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15403         local FID3=$($LFS path2fid $DIR)
15404
15405         # check that path2fid --parents returns expected <parent_fid>/name
15406         # 1) test for a directory (single parent)
15407         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15408         [ "$parent" == "$FID0/foo1" ] ||
15409                 error "expected parent: $FID0/foo1, got: $parent"
15410
15411         # 2) test for a file with nlink > 1 (multiple parents)
15412         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15413         echo "$parent" | grep -F "$FID1/$tfile" ||
15414                 error "$FID1/$tfile not returned in parent list"
15415         echo "$parent" | grep -F "$FID2/link" ||
15416                 error "$FID2/link not returned in parent list"
15417
15418         # 3) get parent by fid
15419         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15420         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15421         echo "$parent" | grep -F "$FID1/$tfile" ||
15422                 error "$FID1/$tfile not returned in parent list (by fid)"
15423         echo "$parent" | grep -F "$FID2/link" ||
15424                 error "$FID2/link not returned in parent list (by fid)"
15425
15426         # 4) test for entry in root directory
15427         parent=$($LFS path2fid --parents $DIR/f)
15428         echo "$parent" | grep -F "$FID3/f" ||
15429                 error "$FID3/f not returned in parent list"
15430
15431         # 5) test it on root directory
15432         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15433                 error "$MOUNT should not have parents"
15434
15435         # enable xattr caching and check that linkea is correctly updated
15436         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15437         save_lustre_params client "llite.*.xattr_cache" > $save
15438         lctl set_param llite.*.xattr_cache 1
15439
15440         # 6.1) linkea update on rename
15441         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15442
15443         # get parents by fid
15444         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15445         # foo1 should no longer be returned in parent list
15446         echo "$parent" | grep -F "$FID1" &&
15447                 error "$FID1 should no longer be in parent list"
15448         # the new path should appear
15449         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15450                 error "$FID2/$tfile.moved is not in parent list"
15451
15452         # 6.2) linkea update on unlink
15453         rm -f $DIR/$tdir/foo2/link
15454         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15455         # foo2/link should no longer be returned in parent list
15456         echo "$parent" | grep -F "$FID2/link" &&
15457                 error "$FID2/link should no longer be in parent list"
15458         true
15459
15460         rm -f $DIR/f
15461         restore_lustre_params < $save
15462         rm -f $save
15463 }
15464 run_test 154f "get parent fids by reading link ea"
15465
15466 test_154g()
15467 {
15468         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15469         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15470            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15471                 skip "Need MDS version at least 2.6.92"
15472
15473         mkdir_on_mdt0 $DIR/$tdir
15474         llapi_fid_test -d $DIR/$tdir
15475 }
15476 run_test 154g "various llapi FID tests"
15477
15478 test_155_small_load() {
15479     local temp=$TMP/$tfile
15480     local file=$DIR/$tfile
15481
15482     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15483         error "dd of=$temp bs=6096 count=1 failed"
15484     cp $temp $file
15485     cancel_lru_locks $OSC
15486     cmp $temp $file || error "$temp $file differ"
15487
15488     $TRUNCATE $temp 6000
15489     $TRUNCATE $file 6000
15490     cmp $temp $file || error "$temp $file differ (truncate1)"
15491
15492     echo "12345" >>$temp
15493     echo "12345" >>$file
15494     cmp $temp $file || error "$temp $file differ (append1)"
15495
15496     echo "12345" >>$temp
15497     echo "12345" >>$file
15498     cmp $temp $file || error "$temp $file differ (append2)"
15499
15500     rm -f $temp $file
15501     true
15502 }
15503
15504 test_155_big_load() {
15505         remote_ost_nodsh && skip "remote OST with nodsh"
15506
15507         local temp=$TMP/$tfile
15508         local file=$DIR/$tfile
15509
15510         free_min_max
15511         local cache_size=$(do_facet ost$((MAXI+1)) \
15512                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15513         local large_file_size=$((cache_size * 2))
15514
15515         echo "OSS cache size: $cache_size KB"
15516         echo "Large file size: $large_file_size KB"
15517
15518         [ $MAXV -le $large_file_size ] &&
15519                 skip_env "max available OST size needs > $large_file_size KB"
15520
15521         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15522
15523         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15524                 error "dd of=$temp bs=$large_file_size count=1k failed"
15525         cp $temp $file
15526         ls -lh $temp $file
15527         cancel_lru_locks osc
15528         cmp $temp $file || error "$temp $file differ"
15529
15530         rm -f $temp $file
15531         true
15532 }
15533
15534 save_writethrough() {
15535         local facets=$(get_facets OST)
15536
15537         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15538 }
15539
15540 test_155a() {
15541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15542
15543         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15544
15545         save_writethrough $p
15546
15547         set_cache read on
15548         set_cache writethrough on
15549         test_155_small_load
15550         restore_lustre_params < $p
15551         rm -f $p
15552 }
15553 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15554
15555 test_155b() {
15556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15557
15558         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15559
15560         save_writethrough $p
15561
15562         set_cache read on
15563         set_cache writethrough off
15564         test_155_small_load
15565         restore_lustre_params < $p
15566         rm -f $p
15567 }
15568 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15569
15570 test_155c() {
15571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15572
15573         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15574
15575         save_writethrough $p
15576
15577         set_cache read off
15578         set_cache writethrough on
15579         test_155_small_load
15580         restore_lustre_params < $p
15581         rm -f $p
15582 }
15583 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15584
15585 test_155d() {
15586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15587
15588         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15589
15590         save_writethrough $p
15591
15592         set_cache read off
15593         set_cache writethrough off
15594         test_155_small_load
15595         restore_lustre_params < $p
15596         rm -f $p
15597 }
15598 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15599
15600 test_155e() {
15601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15602
15603         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15604
15605         save_writethrough $p
15606
15607         set_cache read on
15608         set_cache writethrough on
15609         test_155_big_load
15610         restore_lustre_params < $p
15611         rm -f $p
15612 }
15613 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15614
15615 test_155f() {
15616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15617
15618         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15619
15620         save_writethrough $p
15621
15622         set_cache read on
15623         set_cache writethrough off
15624         test_155_big_load
15625         restore_lustre_params < $p
15626         rm -f $p
15627 }
15628 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15629
15630 test_155g() {
15631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15632
15633         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15634
15635         save_writethrough $p
15636
15637         set_cache read off
15638         set_cache writethrough on
15639         test_155_big_load
15640         restore_lustre_params < $p
15641         rm -f $p
15642 }
15643 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15644
15645 test_155h() {
15646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15647
15648         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15649
15650         save_writethrough $p
15651
15652         set_cache read off
15653         set_cache writethrough off
15654         test_155_big_load
15655         restore_lustre_params < $p
15656         rm -f $p
15657 }
15658 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15659
15660 test_156() {
15661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15662         remote_ost_nodsh && skip "remote OST with nodsh"
15663         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15664                 skip "stats not implemented on old servers"
15665         [ "$ost1_FSTYPE" = "zfs" ] &&
15666                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15667
15668         local CPAGES=3
15669         local BEFORE
15670         local AFTER
15671         local file="$DIR/$tfile"
15672         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15673
15674         save_writethrough $p
15675         roc_hit_init
15676
15677         log "Turn on read and write cache"
15678         set_cache read on
15679         set_cache writethrough on
15680
15681         log "Write data and read it back."
15682         log "Read should be satisfied from the cache."
15683         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15684         BEFORE=$(roc_hit)
15685         cancel_lru_locks osc
15686         cat $file >/dev/null
15687         AFTER=$(roc_hit)
15688         if ! let "AFTER - BEFORE == CPAGES"; then
15689                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15690         else
15691                 log "cache hits: before: $BEFORE, after: $AFTER"
15692         fi
15693
15694         log "Read again; it should be satisfied from the cache."
15695         BEFORE=$AFTER
15696         cancel_lru_locks osc
15697         cat $file >/dev/null
15698         AFTER=$(roc_hit)
15699         if ! let "AFTER - BEFORE == CPAGES"; then
15700                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15701         else
15702                 log "cache hits:: before: $BEFORE, after: $AFTER"
15703         fi
15704
15705         log "Turn off the read cache and turn on the write cache"
15706         set_cache read off
15707         set_cache writethrough on
15708
15709         log "Read again; it should be satisfied from the cache."
15710         BEFORE=$(roc_hit)
15711         cancel_lru_locks osc
15712         cat $file >/dev/null
15713         AFTER=$(roc_hit)
15714         if ! let "AFTER - BEFORE == CPAGES"; then
15715                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15716         else
15717                 log "cache hits:: before: $BEFORE, after: $AFTER"
15718         fi
15719
15720         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15721                 # > 2.12.56 uses pagecache if cached
15722                 log "Read again; it should not be satisfied from the cache."
15723                 BEFORE=$AFTER
15724                 cancel_lru_locks osc
15725                 cat $file >/dev/null
15726                 AFTER=$(roc_hit)
15727                 if ! let "AFTER - BEFORE == 0"; then
15728                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15729                 else
15730                         log "cache hits:: before: $BEFORE, after: $AFTER"
15731                 fi
15732         fi
15733
15734         log "Write data and read it back."
15735         log "Read should be satisfied from the cache."
15736         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15737         BEFORE=$(roc_hit)
15738         cancel_lru_locks osc
15739         cat $file >/dev/null
15740         AFTER=$(roc_hit)
15741         if ! let "AFTER - BEFORE == CPAGES"; then
15742                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15743         else
15744                 log "cache hits:: before: $BEFORE, after: $AFTER"
15745         fi
15746
15747         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15748                 # > 2.12.56 uses pagecache if cached
15749                 log "Read again; it should not be satisfied from the cache."
15750                 BEFORE=$AFTER
15751                 cancel_lru_locks osc
15752                 cat $file >/dev/null
15753                 AFTER=$(roc_hit)
15754                 if ! let "AFTER - BEFORE == 0"; then
15755                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15756                 else
15757                         log "cache hits:: before: $BEFORE, after: $AFTER"
15758                 fi
15759         fi
15760
15761         log "Turn off read and write cache"
15762         set_cache read off
15763         set_cache writethrough off
15764
15765         log "Write data and read it back"
15766         log "It should not be satisfied from the cache."
15767         rm -f $file
15768         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15769         cancel_lru_locks osc
15770         BEFORE=$(roc_hit)
15771         cat $file >/dev/null
15772         AFTER=$(roc_hit)
15773         if ! let "AFTER - BEFORE == 0"; then
15774                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15775         else
15776                 log "cache hits:: before: $BEFORE, after: $AFTER"
15777         fi
15778
15779         log "Turn on the read cache and turn off the write cache"
15780         set_cache read on
15781         set_cache writethrough off
15782
15783         log "Write data and read it back"
15784         log "It should not be satisfied from the cache."
15785         rm -f $file
15786         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15787         BEFORE=$(roc_hit)
15788         cancel_lru_locks osc
15789         cat $file >/dev/null
15790         AFTER=$(roc_hit)
15791         if ! let "AFTER - BEFORE == 0"; then
15792                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15793         else
15794                 log "cache hits:: before: $BEFORE, after: $AFTER"
15795         fi
15796
15797         log "Read again; it should be satisfied from the cache."
15798         BEFORE=$(roc_hit)
15799         cancel_lru_locks osc
15800         cat $file >/dev/null
15801         AFTER=$(roc_hit)
15802         if ! let "AFTER - BEFORE == CPAGES"; then
15803                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15804         else
15805                 log "cache hits:: before: $BEFORE, after: $AFTER"
15806         fi
15807
15808         restore_lustre_params < $p
15809         rm -f $p $file
15810 }
15811 run_test 156 "Verification of tunables"
15812
15813 test_160a() {
15814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15815         remote_mds_nodsh && skip "remote MDS with nodsh"
15816         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15817                 skip "Need MDS version at least 2.2.0"
15818
15819         changelog_register || error "changelog_register failed"
15820         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15821         changelog_users $SINGLEMDS | grep -q $cl_user ||
15822                 error "User $cl_user not found in changelog_users"
15823
15824         mkdir_on_mdt0 $DIR/$tdir
15825
15826         # change something
15827         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15828         changelog_clear 0 || error "changelog_clear failed"
15829         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15830         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15831         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15832         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15833         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15834         rm $DIR/$tdir/pics/desktop.jpg
15835
15836         echo "verifying changelog mask"
15837         changelog_chmask "-MKDIR"
15838         changelog_chmask "-CLOSE"
15839
15840         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15841         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15842
15843         changelog_chmask "+MKDIR"
15844         changelog_chmask "+CLOSE"
15845
15846         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15847         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15848
15849         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15850         CLOSES=$(changelog_dump | grep -c "CLOSE")
15851         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15852         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15853
15854         # verify contents
15855         echo "verifying target fid"
15856         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15857         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15858         [ "$fidc" == "$fidf" ] ||
15859                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15860         echo "verifying parent fid"
15861         # The FID returned from the Changelog may be the directory shard on
15862         # a different MDT, and not the FID returned by path2fid on the parent.
15863         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15864         # since this is what will matter when recreating this file in the tree.
15865         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15866         local pathp=$($LFS fid2path $MOUNT "$fidp")
15867         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15868                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15869
15870         echo "getting records for $cl_user"
15871         changelog_users $SINGLEMDS
15872         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15873         local nclr=3
15874         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15875                 error "changelog_clear failed"
15876         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15877         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15878         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15879                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15880
15881         local min0_rec=$(changelog_users $SINGLEMDS |
15882                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15883         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15884                           awk '{ print $1; exit; }')
15885
15886         changelog_dump | tail -n 5
15887         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15888         [ $first_rec == $((min0_rec + 1)) ] ||
15889                 error "first index should be $min0_rec + 1 not $first_rec"
15890
15891         # LU-3446 changelog index reset on MDT restart
15892         local cur_rec1=$(changelog_users $SINGLEMDS |
15893                          awk '/^current.index:/ { print $NF }')
15894         changelog_clear 0 ||
15895                 error "clear all changelog records for $cl_user failed"
15896         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15897         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15898                 error "Fail to start $SINGLEMDS"
15899         local cur_rec2=$(changelog_users $SINGLEMDS |
15900                          awk '/^current.index:/ { print $NF }')
15901         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15902         [ $cur_rec1 == $cur_rec2 ] ||
15903                 error "current index should be $cur_rec1 not $cur_rec2"
15904
15905         echo "verifying users from this test are deregistered"
15906         changelog_deregister || error "changelog_deregister failed"
15907         changelog_users $SINGLEMDS | grep -q $cl_user &&
15908                 error "User '$cl_user' still in changelog_users"
15909
15910         # lctl get_param -n mdd.*.changelog_users
15911         # current_index: 144
15912         # ID    index (idle seconds)
15913         # cl3   144   (2) mask=<list>
15914         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15915                 # this is the normal case where all users were deregistered
15916                 # make sure no new records are added when no users are present
15917                 local last_rec1=$(changelog_users $SINGLEMDS |
15918                                   awk '/^current.index:/ { print $NF }')
15919                 touch $DIR/$tdir/chloe
15920                 local last_rec2=$(changelog_users $SINGLEMDS |
15921                                   awk '/^current.index:/ { print $NF }')
15922                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15923                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15924         else
15925                 # any changelog users must be leftovers from a previous test
15926                 changelog_users $SINGLEMDS
15927                 echo "other changelog users; can't verify off"
15928         fi
15929 }
15930 run_test 160a "changelog sanity"
15931
15932 test_160b() { # LU-3587
15933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15934         remote_mds_nodsh && skip "remote MDS with nodsh"
15935         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15936                 skip "Need MDS version at least 2.2.0"
15937
15938         changelog_register || error "changelog_register failed"
15939         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15940         changelog_users $SINGLEMDS | grep -q $cl_user ||
15941                 error "User '$cl_user' not found in changelog_users"
15942
15943         local longname1=$(str_repeat a 255)
15944         local longname2=$(str_repeat b 255)
15945
15946         cd $DIR
15947         echo "creating very long named file"
15948         touch $longname1 || error "create of '$longname1' failed"
15949         echo "renaming very long named file"
15950         mv $longname1 $longname2
15951
15952         changelog_dump | grep RENME | tail -n 5
15953         rm -f $longname2
15954 }
15955 run_test 160b "Verify that very long rename doesn't crash in changelog"
15956
15957 test_160c() {
15958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15959         remote_mds_nodsh && skip "remote MDS with nodsh"
15960
15961         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15962                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15963                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15964                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15965
15966         local rc=0
15967
15968         # Registration step
15969         changelog_register || error "changelog_register failed"
15970
15971         rm -rf $DIR/$tdir
15972         mkdir -p $DIR/$tdir
15973         $MCREATE $DIR/$tdir/foo_160c
15974         changelog_chmask "-TRUNC"
15975         $TRUNCATE $DIR/$tdir/foo_160c 200
15976         changelog_chmask "+TRUNC"
15977         $TRUNCATE $DIR/$tdir/foo_160c 199
15978         changelog_dump | tail -n 5
15979         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15980         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15981 }
15982 run_test 160c "verify that changelog log catch the truncate event"
15983
15984 test_160d() {
15985         remote_mds_nodsh && skip "remote MDS with nodsh"
15986         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15988         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15989                 skip "Need MDS version at least 2.7.60"
15990
15991         # Registration step
15992         changelog_register || error "changelog_register failed"
15993
15994         mkdir -p $DIR/$tdir/migrate_dir
15995         changelog_clear 0 || error "changelog_clear failed"
15996
15997         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15998         changelog_dump | tail -n 5
15999         local migrates=$(changelog_dump | grep -c "MIGRT")
16000         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16001 }
16002 run_test 160d "verify that changelog log catch the migrate event"
16003
16004 test_160e() {
16005         remote_mds_nodsh && skip "remote MDS with nodsh"
16006
16007         # Create a user
16008         changelog_register || error "changelog_register failed"
16009
16010         local MDT0=$(facet_svc $SINGLEMDS)
16011         local rc
16012
16013         # No user (expect fail)
16014         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16015         rc=$?
16016         if [ $rc -eq 0 ]; then
16017                 error "Should fail without user"
16018         elif [ $rc -ne 4 ]; then
16019                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16020         fi
16021
16022         # Delete a future user (expect fail)
16023         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16024         rc=$?
16025         if [ $rc -eq 0 ]; then
16026                 error "Deleted non-existant user cl77"
16027         elif [ $rc -ne 2 ]; then
16028                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16029         fi
16030
16031         # Clear to a bad index (1 billion should be safe)
16032         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16033         rc=$?
16034
16035         if [ $rc -eq 0 ]; then
16036                 error "Successfully cleared to invalid CL index"
16037         elif [ $rc -ne 22 ]; then
16038                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16039         fi
16040 }
16041 run_test 160e "changelog negative testing (should return errors)"
16042
16043 test_160f() {
16044         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16045         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16046                 skip "Need MDS version at least 2.10.56"
16047
16048         local mdts=$(comma_list $(mdts_nodes))
16049
16050         # Create a user
16051         changelog_register || error "first changelog_register failed"
16052         changelog_register || error "second changelog_register failed"
16053         local cl_users
16054         declare -A cl_user1
16055         declare -A cl_user2
16056         local user_rec1
16057         local user_rec2
16058         local i
16059
16060         # generate some changelog records to accumulate on each MDT
16061         # use all_char because created files should be evenly distributed
16062         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16063                 error "test_mkdir $tdir failed"
16064         log "$(date +%s): creating first files"
16065         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16066                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16067                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16068         done
16069
16070         # check changelogs have been generated
16071         local start=$SECONDS
16072         local idle_time=$((MDSCOUNT * 5 + 5))
16073         local nbcl=$(changelog_dump | wc -l)
16074         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16075
16076         for param in "changelog_max_idle_time=$idle_time" \
16077                      "changelog_gc=1" \
16078                      "changelog_min_gc_interval=2" \
16079                      "changelog_min_free_cat_entries=3"; do
16080                 local MDT0=$(facet_svc $SINGLEMDS)
16081                 local var="${param%=*}"
16082                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16083
16084                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16085                 do_nodes $mdts $LCTL set_param mdd.*.$param
16086         done
16087
16088         # force cl_user2 to be idle (1st part), but also cancel the
16089         # cl_user1 records so that it is not evicted later in the test.
16090         local sleep1=$((idle_time / 2))
16091         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16092         sleep $sleep1
16093
16094         # simulate changelog catalog almost full
16095         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16096         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16097
16098         for i in $(seq $MDSCOUNT); do
16099                 cl_users=(${CL_USERS[mds$i]})
16100                 cl_user1[mds$i]="${cl_users[0]}"
16101                 cl_user2[mds$i]="${cl_users[1]}"
16102
16103                 [ -n "${cl_user1[mds$i]}" ] ||
16104                         error "mds$i: no user registered"
16105                 [ -n "${cl_user2[mds$i]}" ] ||
16106                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16107
16108                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16109                 [ -n "$user_rec1" ] ||
16110                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16111                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16112                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16113                 [ -n "$user_rec2" ] ||
16114                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16115                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16116                      "$user_rec1 + 2 == $user_rec2"
16117                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16118                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16119                               "$user_rec1 + 2, but is $user_rec2"
16120                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16121                 [ -n "$user_rec2" ] ||
16122                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16123                 [ $user_rec1 == $user_rec2 ] ||
16124                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16125                               "$user_rec1, but is $user_rec2"
16126         done
16127
16128         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16129         local sleep2=$((idle_time - (SECONDS - start) + 1))
16130         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16131         sleep $sleep2
16132
16133         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16134         # cl_user1 should be OK because it recently processed records.
16135         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16136         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16137                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16138                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16139         done
16140
16141         # ensure gc thread is done
16142         for i in $(mdts_nodes); do
16143                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16144                         error "$i: GC-thread not done"
16145         done
16146
16147         local first_rec
16148         for (( i = 1; i <= MDSCOUNT; i++ )); do
16149                 # check cl_user1 still registered
16150                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16151                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16152                 # check cl_user2 unregistered
16153                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16154                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16155
16156                 # check changelogs are present and starting at $user_rec1 + 1
16157                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16158                 [ -n "$user_rec1" ] ||
16159                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16160                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16161                             awk '{ print $1; exit; }')
16162
16163                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16164                 [ $((user_rec1 + 1)) == $first_rec ] ||
16165                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16166         done
16167 }
16168 run_test 160f "changelog garbage collect (timestamped users)"
16169
16170 test_160g() {
16171         remote_mds_nodsh && skip "remote MDS with nodsh"
16172         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16173                 skip "Need MDS version at least 2.14.55"
16174
16175         local mdts=$(comma_list $(mdts_nodes))
16176
16177         # Create a user
16178         changelog_register || error "first changelog_register failed"
16179         changelog_register || error "second changelog_register failed"
16180         local cl_users
16181         declare -A cl_user1
16182         declare -A cl_user2
16183         local user_rec1
16184         local user_rec2
16185         local i
16186
16187         # generate some changelog records to accumulate on each MDT
16188         # use all_char because created files should be evenly distributed
16189         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16190                 error "test_mkdir $tdir failed"
16191         for ((i = 0; i < MDSCOUNT; i++)); do
16192                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16193                         error "create $DIR/$tdir/d$i.1 failed"
16194         done
16195
16196         # check changelogs have been generated
16197         local nbcl=$(changelog_dump | wc -l)
16198         (( $nbcl > 0 )) || error "no changelogs found"
16199
16200         # reduce the max_idle_indexes value to make sure we exceed it
16201         for param in "changelog_max_idle_indexes=2" \
16202                      "changelog_gc=1" \
16203                      "changelog_min_gc_interval=2"; do
16204                 local MDT0=$(facet_svc $SINGLEMDS)
16205                 local var="${param%=*}"
16206                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16207
16208                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16209                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16210                         error "unable to set mdd.*.$param"
16211         done
16212
16213         local start=$SECONDS
16214         for i in $(seq $MDSCOUNT); do
16215                 cl_users=(${CL_USERS[mds$i]})
16216                 cl_user1[mds$i]="${cl_users[0]}"
16217                 cl_user2[mds$i]="${cl_users[1]}"
16218
16219                 [ -n "${cl_user1[mds$i]}" ] ||
16220                         error "mds$i: user1 is not registered"
16221                 [ -n "${cl_user2[mds$i]}" ] ||
16222                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16223
16224                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16225                 [ -n "$user_rec1" ] ||
16226                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16227                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16228                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16229                 [ -n "$user_rec2" ] ||
16230                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16231                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16232                      "$user_rec1 + 2 == $user_rec2"
16233                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16234                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16235                               "expected $user_rec1 + 2, but is $user_rec2"
16236                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16237                 [ -n "$user_rec2" ] ||
16238                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16239                 [ $user_rec1 == $user_rec2 ] ||
16240                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16241                               "expected $user_rec1, but is $user_rec2"
16242         done
16243
16244         # ensure we are past the previous changelog_min_gc_interval set above
16245         local sleep2=$((start + 2 - SECONDS))
16246         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16247         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16248         # cl_user1 should be OK because it recently processed records.
16249         for ((i = 0; i < MDSCOUNT; i++)); do
16250                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16251                         error "create $DIR/$tdir/d$i.3 failed"
16252         done
16253
16254         # ensure gc thread is done
16255         for i in $(mdts_nodes); do
16256                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16257                         error "$i: GC-thread not done"
16258         done
16259
16260         local first_rec
16261         for (( i = 1; i <= MDSCOUNT; i++ )); do
16262                 # check cl_user1 still registered
16263                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16264                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16265                 # check cl_user2 unregistered
16266                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16267                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16268
16269                 # check changelogs are present and starting at $user_rec1 + 1
16270                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16271                 [ -n "$user_rec1" ] ||
16272                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16273                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16274                             awk '{ print $1; exit; }')
16275
16276                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16277                 [ $((user_rec1 + 1)) == $first_rec ] ||
16278                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16279         done
16280 }
16281 run_test 160g "changelog garbage collect on idle records"
16282
16283 test_160h() {
16284         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16285         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16286                 skip "Need MDS version at least 2.10.56"
16287
16288         local mdts=$(comma_list $(mdts_nodes))
16289
16290         # Create a user
16291         changelog_register || error "first changelog_register failed"
16292         changelog_register || error "second changelog_register failed"
16293         local cl_users
16294         declare -A cl_user1
16295         declare -A cl_user2
16296         local user_rec1
16297         local user_rec2
16298         local i
16299
16300         # generate some changelog records to accumulate on each MDT
16301         # use all_char because created files should be evenly distributed
16302         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16303                 error "test_mkdir $tdir failed"
16304         for ((i = 0; i < MDSCOUNT; i++)); do
16305                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16306                         error "create $DIR/$tdir/d$i.1 failed"
16307         done
16308
16309         # check changelogs have been generated
16310         local nbcl=$(changelog_dump | wc -l)
16311         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16312
16313         for param in "changelog_max_idle_time=10" \
16314                      "changelog_gc=1" \
16315                      "changelog_min_gc_interval=2"; do
16316                 local MDT0=$(facet_svc $SINGLEMDS)
16317                 local var="${param%=*}"
16318                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16319
16320                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16321                 do_nodes $mdts $LCTL set_param mdd.*.$param
16322         done
16323
16324         # force cl_user2 to be idle (1st part)
16325         sleep 9
16326
16327         for i in $(seq $MDSCOUNT); do
16328                 cl_users=(${CL_USERS[mds$i]})
16329                 cl_user1[mds$i]="${cl_users[0]}"
16330                 cl_user2[mds$i]="${cl_users[1]}"
16331
16332                 [ -n "${cl_user1[mds$i]}" ] ||
16333                         error "mds$i: no user registered"
16334                 [ -n "${cl_user2[mds$i]}" ] ||
16335                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16336
16337                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16338                 [ -n "$user_rec1" ] ||
16339                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16340                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16341                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16342                 [ -n "$user_rec2" ] ||
16343                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16344                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16345                      "$user_rec1 + 2 == $user_rec2"
16346                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16347                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16348                               "$user_rec1 + 2, but is $user_rec2"
16349                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16350                 [ -n "$user_rec2" ] ||
16351                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16352                 [ $user_rec1 == $user_rec2 ] ||
16353                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16354                               "$user_rec1, but is $user_rec2"
16355         done
16356
16357         # force cl_user2 to be idle (2nd part) and to reach
16358         # changelog_max_idle_time
16359         sleep 2
16360
16361         # force each GC-thread start and block then
16362         # one per MDT/MDD, set fail_val accordingly
16363         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16364         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16365
16366         # generate more changelogs to trigger fail_loc
16367         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16368                 error "create $DIR/$tdir/${tfile}bis failed"
16369
16370         # stop MDT to stop GC-thread, should be done in back-ground as it will
16371         # block waiting for the thread to be released and exit
16372         declare -A stop_pids
16373         for i in $(seq $MDSCOUNT); do
16374                 stop mds$i &
16375                 stop_pids[mds$i]=$!
16376         done
16377
16378         for i in $(mdts_nodes); do
16379                 local facet
16380                 local nb=0
16381                 local facets=$(facets_up_on_host $i)
16382
16383                 for facet in ${facets//,/ }; do
16384                         if [[ $facet == mds* ]]; then
16385                                 nb=$((nb + 1))
16386                         fi
16387                 done
16388                 # ensure each MDS's gc threads are still present and all in "R"
16389                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16390                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16391                         error "$i: expected $nb GC-thread"
16392                 wait_update $i \
16393                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16394                         "R" 20 ||
16395                         error "$i: GC-thread not found in R-state"
16396                 # check umounts of each MDT on MDS have reached kthread_stop()
16397                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16398                         error "$i: expected $nb umount"
16399                 wait_update $i \
16400                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16401                         error "$i: umount not found in D-state"
16402         done
16403
16404         # release all GC-threads
16405         do_nodes $mdts $LCTL set_param fail_loc=0
16406
16407         # wait for MDT stop to complete
16408         for i in $(seq $MDSCOUNT); do
16409                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16410         done
16411
16412         # XXX
16413         # may try to check if any orphan changelog records are present
16414         # via ldiskfs/zfs and llog_reader...
16415
16416         # re-start/mount MDTs
16417         for i in $(seq $MDSCOUNT); do
16418                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16419                         error "Fail to start mds$i"
16420         done
16421
16422         local first_rec
16423         for i in $(seq $MDSCOUNT); do
16424                 # check cl_user1 still registered
16425                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16426                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16427                 # check cl_user2 unregistered
16428                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16429                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16430
16431                 # check changelogs are present and starting at $user_rec1 + 1
16432                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16433                 [ -n "$user_rec1" ] ||
16434                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16435                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16436                             awk '{ print $1; exit; }')
16437
16438                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16439                 [ $((user_rec1 + 1)) == $first_rec ] ||
16440                         error "mds$i: first index should be $user_rec1 + 1, " \
16441                               "but is $first_rec"
16442         done
16443 }
16444 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16445               "during mount"
16446
16447 test_160i() {
16448
16449         local mdts=$(comma_list $(mdts_nodes))
16450
16451         changelog_register || error "first changelog_register failed"
16452
16453         # generate some changelog records to accumulate on each MDT
16454         # use all_char because created files should be evenly distributed
16455         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16456                 error "test_mkdir $tdir failed"
16457         for ((i = 0; i < MDSCOUNT; i++)); do
16458                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16459                         error "create $DIR/$tdir/d$i.1 failed"
16460         done
16461
16462         # check changelogs have been generated
16463         local nbcl=$(changelog_dump | wc -l)
16464         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16465
16466         # simulate race between register and unregister
16467         # XXX as fail_loc is set per-MDS, with DNE configs the race
16468         # simulation will only occur for one MDT per MDS and for the
16469         # others the normal race scenario will take place
16470         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16471         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16472         do_nodes $mdts $LCTL set_param fail_val=1
16473
16474         # unregister 1st user
16475         changelog_deregister &
16476         local pid1=$!
16477         # wait some time for deregister work to reach race rdv
16478         sleep 2
16479         # register 2nd user
16480         changelog_register || error "2nd user register failed"
16481
16482         wait $pid1 || error "1st user deregister failed"
16483
16484         local i
16485         local last_rec
16486         declare -A LAST_REC
16487         for i in $(seq $MDSCOUNT); do
16488                 if changelog_users mds$i | grep "^cl"; then
16489                         # make sure new records are added with one user present
16490                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16491                                           awk '/^current.index:/ { print $NF }')
16492                 else
16493                         error "mds$i has no user registered"
16494                 fi
16495         done
16496
16497         # generate more changelog records to accumulate on each MDT
16498         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16499                 error "create $DIR/$tdir/${tfile}bis failed"
16500
16501         for i in $(seq $MDSCOUNT); do
16502                 last_rec=$(changelog_users $SINGLEMDS |
16503                            awk '/^current.index:/ { print $NF }')
16504                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16505                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16506                         error "changelogs are off on mds$i"
16507         done
16508 }
16509 run_test 160i "changelog user register/unregister race"
16510
16511 test_160j() {
16512         remote_mds_nodsh && skip "remote MDS with nodsh"
16513         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16514                 skip "Need MDS version at least 2.12.56"
16515
16516         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16517         stack_trap "umount $MOUNT2" EXIT
16518
16519         changelog_register || error "first changelog_register failed"
16520         stack_trap "changelog_deregister" EXIT
16521
16522         # generate some changelog
16523         # use all_char because created files should be evenly distributed
16524         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16525                 error "mkdir $tdir failed"
16526         for ((i = 0; i < MDSCOUNT; i++)); do
16527                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16528                         error "create $DIR/$tdir/d$i.1 failed"
16529         done
16530
16531         # open the changelog device
16532         exec 3>/dev/changelog-$FSNAME-MDT0000
16533         stack_trap "exec 3>&-" EXIT
16534         exec 4</dev/changelog-$FSNAME-MDT0000
16535         stack_trap "exec 4<&-" EXIT
16536
16537         # umount the first lustre mount
16538         umount $MOUNT
16539         stack_trap "mount_client $MOUNT" EXIT
16540
16541         # read changelog, which may or may not fail, but should not crash
16542         cat <&4 >/dev/null
16543
16544         # clear changelog
16545         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16546         changelog_users $SINGLEMDS | grep -q $cl_user ||
16547                 error "User $cl_user not found in changelog_users"
16548
16549         printf 'clear:'$cl_user':0' >&3
16550 }
16551 run_test 160j "client can be umounted while its chanangelog is being used"
16552
16553 test_160k() {
16554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16555         remote_mds_nodsh && skip "remote MDS with nodsh"
16556
16557         mkdir -p $DIR/$tdir/1/1
16558
16559         changelog_register || error "changelog_register failed"
16560         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16561
16562         changelog_users $SINGLEMDS | grep -q $cl_user ||
16563                 error "User '$cl_user' not found in changelog_users"
16564 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16565         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16566         rmdir $DIR/$tdir/1/1 & sleep 1
16567         mkdir $DIR/$tdir/2
16568         touch $DIR/$tdir/2/2
16569         rm -rf $DIR/$tdir/2
16570
16571         wait
16572         sleep 4
16573
16574         changelog_dump | grep rmdir || error "rmdir not recorded"
16575 }
16576 run_test 160k "Verify that changelog records are not lost"
16577
16578 # Verifies that a file passed as a parameter has recently had an operation
16579 # performed on it that has generated an MTIME changelog which contains the
16580 # correct parent FID. As files might reside on a different MDT from the
16581 # parent directory in DNE configurations, the FIDs are translated to paths
16582 # before being compared, which should be identical
16583 compare_mtime_changelog() {
16584         local file="${1}"
16585         local mdtidx
16586         local mtime
16587         local cl_fid
16588         local pdir
16589         local dir
16590
16591         mdtidx=$($LFS getstripe --mdt-index $file)
16592         mdtidx=$(printf "%04x" $mdtidx)
16593
16594         # Obtain the parent FID from the MTIME changelog
16595         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16596         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16597
16598         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16599         [ -z "$cl_fid" ] && error "parent FID not present"
16600
16601         # Verify that the path for the parent FID is the same as the path for
16602         # the test directory
16603         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16604
16605         dir=$(dirname $1)
16606
16607         [[ "${pdir%/}" == "$dir" ]] ||
16608                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16609 }
16610
16611 test_160l() {
16612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16613
16614         remote_mds_nodsh && skip "remote MDS with nodsh"
16615         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16616                 skip "Need MDS version at least 2.13.55"
16617
16618         local cl_user
16619
16620         changelog_register || error "changelog_register failed"
16621         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16622
16623         changelog_users $SINGLEMDS | grep -q $cl_user ||
16624                 error "User '$cl_user' not found in changelog_users"
16625
16626         # Clear some types so that MTIME changelogs are generated
16627         changelog_chmask "-CREAT"
16628         changelog_chmask "-CLOSE"
16629
16630         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16631
16632         # Test CL_MTIME during setattr
16633         touch $DIR/$tdir/$tfile
16634         compare_mtime_changelog $DIR/$tdir/$tfile
16635
16636         # Test CL_MTIME during close
16637         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16638         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16639 }
16640 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16641
16642 test_160m() {
16643         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16644         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16645                 skip "Need MDS version at least 2.14.51"
16646         local cl_users
16647         local cl_user1
16648         local cl_user2
16649         local pid1
16650
16651         # Create a user
16652         changelog_register || error "first changelog_register failed"
16653         changelog_register || error "second changelog_register failed"
16654
16655         cl_users=(${CL_USERS[mds1]})
16656         cl_user1="${cl_users[0]}"
16657         cl_user2="${cl_users[1]}"
16658         # generate some changelog records to accumulate on MDT0
16659         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16660         createmany -m $DIR/$tdir/$tfile 50 ||
16661                 error "create $DIR/$tdir/$tfile failed"
16662         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16663         rm -f $DIR/$tdir
16664
16665         # check changelogs have been generated
16666         local nbcl=$(changelog_dump | wc -l)
16667         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16668
16669 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16670         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16671
16672         __changelog_clear mds1 $cl_user1 +10
16673         __changelog_clear mds1 $cl_user2 0 &
16674         pid1=$!
16675         sleep 2
16676         __changelog_clear mds1 $cl_user1 0 ||
16677                 error "fail to cancel record for $cl_user1"
16678         wait $pid1
16679         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16680 }
16681 run_test 160m "Changelog clear race"
16682
16683 test_160n() {
16684         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16685         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16686                 skip "Need MDS version at least 2.14.51"
16687         local cl_users
16688         local cl_user1
16689         local cl_user2
16690         local pid1
16691         local first_rec
16692         local last_rec=0
16693
16694         # Create a user
16695         changelog_register || error "first changelog_register failed"
16696
16697         cl_users=(${CL_USERS[mds1]})
16698         cl_user1="${cl_users[0]}"
16699
16700         # generate some changelog records to accumulate on MDT0
16701         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16702         first_rec=$(changelog_users $SINGLEMDS |
16703                         awk '/^current.index:/ { print $NF }')
16704         while (( last_rec < (( first_rec + 65000)) )); do
16705                 createmany -m $DIR/$tdir/$tfile 10000 ||
16706                         error "create $DIR/$tdir/$tfile failed"
16707
16708                 for i in $(seq 0 10000); do
16709                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16710                                 > /dev/null
16711                 done
16712
16713                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16714                         error "unlinkmany failed unlink"
16715                 last_rec=$(changelog_users $SINGLEMDS |
16716                         awk '/^current.index:/ { print $NF }')
16717                 echo last record $last_rec
16718                 (( last_rec == 0 )) && error "no changelog found"
16719         done
16720
16721 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16722         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16723
16724         __changelog_clear mds1 $cl_user1 0 &
16725         pid1=$!
16726         sleep 2
16727         __changelog_clear mds1 $cl_user1 0 ||
16728                 error "fail to cancel record for $cl_user1"
16729         wait $pid1
16730         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16731 }
16732 run_test 160n "Changelog destroy race"
16733
16734 test_160o() {
16735         local mdt="$(facet_svc $SINGLEMDS)"
16736
16737         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16738         remote_mds_nodsh && skip "remote MDS with nodsh"
16739         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16740                 skip "Need MDS version at least 2.14.52"
16741
16742         changelog_register --user test_160o -m unlnk+close+open ||
16743                 error "changelog_register failed"
16744
16745         do_facet $SINGLEMDS $LCTL --device $mdt \
16746                                 changelog_register -u "Tt3_-#" &&
16747                 error "bad symbols in name should fail"
16748
16749         do_facet $SINGLEMDS $LCTL --device $mdt \
16750                                 changelog_register -u test_160o &&
16751                 error "the same name registration should fail"
16752
16753         do_facet $SINGLEMDS $LCTL --device $mdt \
16754                         changelog_register -u test_160toolongname &&
16755                 error "too long name registration should fail"
16756
16757         changelog_chmask "MARK+HSM"
16758         lctl get_param mdd.*.changelog*mask
16759         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16760         changelog_users $SINGLEMDS | grep -q $cl_user ||
16761                 error "User $cl_user not found in changelog_users"
16762         #verify username
16763         echo $cl_user | grep -q test_160o ||
16764                 error "User $cl_user has no specific name 'test160o'"
16765
16766         # change something
16767         changelog_clear 0 || error "changelog_clear failed"
16768         # generate some changelog records to accumulate on MDT0
16769         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16770         touch $DIR/$tdir/$tfile                 # open 1
16771
16772         OPENS=$(changelog_dump | grep -c "OPEN")
16773         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16774
16775         # must be no MKDIR it wasn't set as user mask
16776         MKDIR=$(changelog_dump | grep -c "MKDIR")
16777         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16778
16779         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16780                                 mdd.$mdt.changelog_current_mask -n)
16781         # register maskless user
16782         changelog_register || error "changelog_register failed"
16783         # effective mask should be not changed because it is not minimal
16784         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16785                                 mdd.$mdt.changelog_current_mask -n)
16786         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16787         # set server mask to minimal value
16788         changelog_chmask "MARK"
16789         # check effective mask again, should be treated as DEFMASK now
16790         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16791                                 mdd.$mdt.changelog_current_mask -n)
16792         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16793
16794         do_facet $SINGLEMDS $LCTL --device $mdt \
16795                                 changelog_deregister -u test_160o ||
16796                 error "cannot deregister by name"
16797 }
16798 run_test 160o "changelog user name and mask"
16799
16800 test_160p() {
16801         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16802         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16803                 skip "Need MDS version at least 2.14.51"
16804         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16805         local cl_users
16806         local cl_user1
16807         local entry_count
16808
16809         # Create a user
16810         changelog_register || error "first changelog_register failed"
16811
16812         cl_users=(${CL_USERS[mds1]})
16813         cl_user1="${cl_users[0]}"
16814
16815         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16816         createmany -m $DIR/$tdir/$tfile 50 ||
16817                 error "create $DIR/$tdir/$tfile failed"
16818         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16819         rm -rf $DIR/$tdir
16820
16821         # check changelogs have been generated
16822         entry_count=$(changelog_dump | wc -l)
16823         ((entry_count != 0)) || error "no changelog entries found"
16824
16825         # remove changelog_users and check that orphan entries are removed
16826         stop mds1
16827         local dev=$(mdsdevname 1)
16828         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16829         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16830         entry_count=$(changelog_dump | wc -l)
16831         ((entry_count == 0)) ||
16832                 error "found $entry_count changelog entries, expected none"
16833 }
16834 run_test 160p "Changelog orphan cleanup with no users"
16835
16836 test_160q() {
16837         local mdt="$(facet_svc $SINGLEMDS)"
16838         local clu
16839
16840         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16841         remote_mds_nodsh && skip "remote MDS with nodsh"
16842         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16843                 skip "Need MDS version at least 2.14.54"
16844
16845         # set server mask to minimal value like server init does
16846         changelog_chmask "MARK"
16847         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16848                 error "changelog_register failed"
16849         # check effective mask again, should be treated as DEFMASK now
16850         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16851                                 mdd.$mdt.changelog_current_mask -n)
16852         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16853                 error "changelog_deregister failed"
16854         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16855 }
16856 run_test 160q "changelog effective mask is DEFMASK if not set"
16857
16858 test_160s() {
16859         remote_mds_nodsh && skip "remote MDS with nodsh"
16860         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16861                 skip "Need MDS version at least 2.14.55"
16862
16863         local mdts=$(comma_list $(mdts_nodes))
16864
16865         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16866         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16867                                        fail_val=$((24 * 3600 * 10))
16868
16869         # Create a user which is 10 days old
16870         changelog_register || error "first changelog_register failed"
16871         local cl_users
16872         declare -A cl_user1
16873         local i
16874
16875         # generate some changelog records to accumulate on each MDT
16876         # use all_char because created files should be evenly distributed
16877         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16878                 error "test_mkdir $tdir failed"
16879         for ((i = 0; i < MDSCOUNT; i++)); do
16880                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16881                         error "create $DIR/$tdir/d$i.1 failed"
16882         done
16883
16884         # check changelogs have been generated
16885         local nbcl=$(changelog_dump | wc -l)
16886         (( nbcl > 0 )) || error "no changelogs found"
16887
16888         # reduce the max_idle_indexes value to make sure we exceed it
16889         for param in "changelog_max_idle_indexes=2097446912" \
16890                      "changelog_max_idle_time=2592000" \
16891                      "changelog_gc=1" \
16892                      "changelog_min_gc_interval=2"; do
16893                 local MDT0=$(facet_svc $SINGLEMDS)
16894                 local var="${param%=*}"
16895                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16896
16897                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16898                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16899                         error "unable to set mdd.*.$param"
16900         done
16901
16902         local start=$SECONDS
16903         for i in $(seq $MDSCOUNT); do
16904                 cl_users=(${CL_USERS[mds$i]})
16905                 cl_user1[mds$i]="${cl_users[0]}"
16906
16907                 [[ -n "${cl_user1[mds$i]}" ]] ||
16908                         error "mds$i: no user registered"
16909         done
16910
16911         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16912         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16913
16914         # ensure we are past the previous changelog_min_gc_interval set above
16915         local sleep2=$((start + 2 - SECONDS))
16916         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16917
16918         # Generate one more changelog to trigger GC
16919         for ((i = 0; i < MDSCOUNT; i++)); do
16920                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16921                         error "create $DIR/$tdir/d$i.3 failed"
16922         done
16923
16924         # ensure gc thread is done
16925         for node in $(mdts_nodes); do
16926                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16927                         error "$node: GC-thread not done"
16928         done
16929
16930         do_nodes $mdts $LCTL set_param fail_loc=0
16931
16932         for (( i = 1; i <= MDSCOUNT; i++ )); do
16933                 # check cl_user1 is purged
16934                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16935                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16936         done
16937         return 0
16938 }
16939 run_test 160s "changelog garbage collect on idle records * time"
16940
16941 test_161a() {
16942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16943
16944         test_mkdir -c1 $DIR/$tdir
16945         cp /etc/hosts $DIR/$tdir/$tfile
16946         test_mkdir -c1 $DIR/$tdir/foo1
16947         test_mkdir -c1 $DIR/$tdir/foo2
16948         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16949         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16950         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16951         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16952         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16953         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16954                 $LFS fid2path $DIR $FID
16955                 error "bad link ea"
16956         fi
16957         # middle
16958         rm $DIR/$tdir/foo2/zachary
16959         # last
16960         rm $DIR/$tdir/foo2/thor
16961         # first
16962         rm $DIR/$tdir/$tfile
16963         # rename
16964         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16965         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16966                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16967         rm $DIR/$tdir/foo2/maggie
16968
16969         # overflow the EA
16970         local longname=$tfile.avg_len_is_thirty_two_
16971         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16972                 error_noexit 'failed to unlink many hardlinks'" EXIT
16973         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16974                 error "failed to hardlink many files"
16975         links=$($LFS fid2path $DIR $FID | wc -l)
16976         echo -n "${links}/1000 links in link EA"
16977         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16978 }
16979 run_test 161a "link ea sanity"
16980
16981 test_161b() {
16982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16983         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16984
16985         local MDTIDX=1
16986         local remote_dir=$DIR/$tdir/remote_dir
16987
16988         mkdir -p $DIR/$tdir
16989         $LFS mkdir -i $MDTIDX $remote_dir ||
16990                 error "create remote directory failed"
16991
16992         cp /etc/hosts $remote_dir/$tfile
16993         mkdir -p $remote_dir/foo1
16994         mkdir -p $remote_dir/foo2
16995         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16996         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16997         ln $remote_dir/$tfile $remote_dir/foo1/luna
16998         ln $remote_dir/$tfile $remote_dir/foo2/thor
16999
17000         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17001                      tr -d ']')
17002         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17003                 $LFS fid2path $DIR $FID
17004                 error "bad link ea"
17005         fi
17006         # middle
17007         rm $remote_dir/foo2/zachary
17008         # last
17009         rm $remote_dir/foo2/thor
17010         # first
17011         rm $remote_dir/$tfile
17012         # rename
17013         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17014         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17015         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17016                 $LFS fid2path $DIR $FID
17017                 error "bad link rename"
17018         fi
17019         rm $remote_dir/foo2/maggie
17020
17021         # overflow the EA
17022         local longname=filename_avg_len_is_thirty_two_
17023         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17024                 error "failed to hardlink many files"
17025         links=$($LFS fid2path $DIR $FID | wc -l)
17026         echo -n "${links}/1000 links in link EA"
17027         [[ ${links} -gt 60 ]] ||
17028                 error "expected at least 60 links in link EA"
17029         unlinkmany $remote_dir/foo2/$longname 1000 ||
17030         error "failed to unlink many hardlinks"
17031 }
17032 run_test 161b "link ea sanity under remote directory"
17033
17034 test_161c() {
17035         remote_mds_nodsh && skip "remote MDS with nodsh"
17036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17037         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17038                 skip "Need MDS version at least 2.1.5"
17039
17040         # define CLF_RENAME_LAST 0x0001
17041         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17042         changelog_register || error "changelog_register failed"
17043
17044         rm -rf $DIR/$tdir
17045         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17046         touch $DIR/$tdir/foo_161c
17047         touch $DIR/$tdir/bar_161c
17048         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17049         changelog_dump | grep RENME | tail -n 5
17050         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17051         changelog_clear 0 || error "changelog_clear failed"
17052         if [ x$flags != "x0x1" ]; then
17053                 error "flag $flags is not 0x1"
17054         fi
17055
17056         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17057         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17058         touch $DIR/$tdir/foo_161c
17059         touch $DIR/$tdir/bar_161c
17060         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17061         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17062         changelog_dump | grep RENME | tail -n 5
17063         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17064         changelog_clear 0 || error "changelog_clear failed"
17065         if [ x$flags != "x0x0" ]; then
17066                 error "flag $flags is not 0x0"
17067         fi
17068         echo "rename overwrite a target having nlink > 1," \
17069                 "changelog record has flags of $flags"
17070
17071         # rename doesn't overwrite a target (changelog flag 0x0)
17072         touch $DIR/$tdir/foo_161c
17073         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17074         changelog_dump | grep RENME | tail -n 5
17075         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17076         changelog_clear 0 || error "changelog_clear failed"
17077         if [ x$flags != "x0x0" ]; then
17078                 error "flag $flags is not 0x0"
17079         fi
17080         echo "rename doesn't overwrite a target," \
17081                 "changelog record has flags of $flags"
17082
17083         # define CLF_UNLINK_LAST 0x0001
17084         # unlink a file having nlink = 1 (changelog flag 0x1)
17085         rm -f $DIR/$tdir/foo2_161c
17086         changelog_dump | grep UNLNK | tail -n 5
17087         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17088         changelog_clear 0 || error "changelog_clear failed"
17089         if [ x$flags != "x0x1" ]; then
17090                 error "flag $flags is not 0x1"
17091         fi
17092         echo "unlink a file having nlink = 1," \
17093                 "changelog record has flags of $flags"
17094
17095         # unlink a file having nlink > 1 (changelog flag 0x0)
17096         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17097         rm -f $DIR/$tdir/foobar_161c
17098         changelog_dump | grep UNLNK | tail -n 5
17099         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17100         changelog_clear 0 || error "changelog_clear failed"
17101         if [ x$flags != "x0x0" ]; then
17102                 error "flag $flags is not 0x0"
17103         fi
17104         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17105 }
17106 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17107
17108 test_161d() {
17109         remote_mds_nodsh && skip "remote MDS with nodsh"
17110         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17111
17112         local pid
17113         local fid
17114
17115         changelog_register || error "changelog_register failed"
17116
17117         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17118         # interfer with $MOUNT/.lustre/fid/ access
17119         mkdir $DIR/$tdir
17120         [[ $? -eq 0 ]] || error "mkdir failed"
17121
17122         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17123         $LCTL set_param fail_loc=0x8000140c
17124         # 5s pause
17125         $LCTL set_param fail_val=5
17126
17127         # create file
17128         echo foofoo > $DIR/$tdir/$tfile &
17129         pid=$!
17130
17131         # wait for create to be delayed
17132         sleep 2
17133
17134         ps -p $pid
17135         [[ $? -eq 0 ]] || error "create should be blocked"
17136
17137         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17138         stack_trap "rm -f $tempfile"
17139         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17140         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17141         # some delay may occur during ChangeLog publishing and file read just
17142         # above, that could allow file write to happen finally
17143         [[ -s $tempfile ]] && echo "file should be empty"
17144
17145         $LCTL set_param fail_loc=0
17146
17147         wait $pid
17148         [[ $? -eq 0 ]] || error "create failed"
17149 }
17150 run_test 161d "create with concurrent .lustre/fid access"
17151
17152 check_path() {
17153         local expected="$1"
17154         shift
17155         local fid="$2"
17156
17157         local path
17158         path=$($LFS fid2path "$@")
17159         local rc=$?
17160
17161         if [ $rc -ne 0 ]; then
17162                 error "path looked up of '$expected' failed: rc=$rc"
17163         elif [ "$path" != "$expected" ]; then
17164                 error "path looked up '$path' instead of '$expected'"
17165         else
17166                 echo "FID '$fid' resolves to path '$path' as expected"
17167         fi
17168 }
17169
17170 test_162a() { # was test_162
17171         test_mkdir -p -c1 $DIR/$tdir/d2
17172         touch $DIR/$tdir/d2/$tfile
17173         touch $DIR/$tdir/d2/x1
17174         touch $DIR/$tdir/d2/x2
17175         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17176         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17177         # regular file
17178         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17179         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17180
17181         # softlink
17182         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17183         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17184         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17185
17186         # softlink to wrong file
17187         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17188         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17189         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17190
17191         # hardlink
17192         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17193         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17194         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17195         # fid2path dir/fsname should both work
17196         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17197         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17198
17199         # hardlink count: check that there are 2 links
17200         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17201         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17202
17203         # hardlink indexing: remove the first link
17204         rm $DIR/$tdir/d2/p/q/r/hlink
17205         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17206 }
17207 run_test 162a "path lookup sanity"
17208
17209 test_162b() {
17210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17211         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17212
17213         mkdir $DIR/$tdir
17214         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17215                                 error "create striped dir failed"
17216
17217         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17218                                         tail -n 1 | awk '{print $2}')
17219         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17220
17221         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17222         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17223
17224         # regular file
17225         for ((i=0;i<5;i++)); do
17226                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17227                         error "get fid for f$i failed"
17228                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17229
17230                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17231                         error "get fid for d$i failed"
17232                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17233         done
17234
17235         return 0
17236 }
17237 run_test 162b "striped directory path lookup sanity"
17238
17239 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17240 test_162c() {
17241         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17242                 skip "Need MDS version at least 2.7.51"
17243
17244         local lpath=$tdir.local
17245         local rpath=$tdir.remote
17246
17247         test_mkdir $DIR/$lpath
17248         test_mkdir $DIR/$rpath
17249
17250         for ((i = 0; i <= 101; i++)); do
17251                 lpath="$lpath/$i"
17252                 mkdir $DIR/$lpath
17253                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17254                         error "get fid for local directory $DIR/$lpath failed"
17255                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17256
17257                 rpath="$rpath/$i"
17258                 test_mkdir $DIR/$rpath
17259                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17260                         error "get fid for remote directory $DIR/$rpath failed"
17261                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17262         done
17263
17264         return 0
17265 }
17266 run_test 162c "fid2path works with paths 100 or more directories deep"
17267
17268 oalr_event_count() {
17269         local event="${1}"
17270         local trace="${2}"
17271
17272         awk -v name="${FSNAME}-OST0000" \
17273             -v event="${event}" \
17274             '$1 == "TRACE" && $2 == event && $3 == name' \
17275             "${trace}" |
17276         wc -l
17277 }
17278
17279 oalr_expect_event_count() {
17280         local event="${1}"
17281         local trace="${2}"
17282         local expect="${3}"
17283         local count
17284
17285         count=$(oalr_event_count "${event}" "${trace}")
17286         if ((count == expect)); then
17287                 return 0
17288         fi
17289
17290         error_noexit "${event} event count was '${count}', expected ${expect}"
17291         cat "${trace}" >&2
17292         exit 1
17293 }
17294
17295 cleanup_165() {
17296         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17297         stop ost1
17298         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17299 }
17300
17301 setup_165() {
17302         sync # Flush previous IOs so we can count log entries.
17303         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17304         stack_trap cleanup_165 EXIT
17305 }
17306
17307 test_165a() {
17308         local trace="/tmp/${tfile}.trace"
17309         local rc
17310         local count
17311
17312         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17313                 skip "OFD access log unsupported"
17314
17315         setup_165
17316         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17317         sleep 5
17318
17319         do_facet ost1 ofd_access_log_reader --list
17320         stop ost1
17321
17322         do_facet ost1 killall -TERM ofd_access_log_reader
17323         wait
17324         rc=$?
17325
17326         if ((rc != 0)); then
17327                 error "ofd_access_log_reader exited with rc = '${rc}'"
17328         fi
17329
17330         # Parse trace file for discovery events:
17331         oalr_expect_event_count alr_log_add "${trace}" 1
17332         oalr_expect_event_count alr_log_eof "${trace}" 1
17333         oalr_expect_event_count alr_log_free "${trace}" 1
17334 }
17335 run_test 165a "ofd access log discovery"
17336
17337 test_165b() {
17338         local trace="/tmp/${tfile}.trace"
17339         local file="${DIR}/${tfile}"
17340         local pfid1
17341         local pfid2
17342         local -a entry
17343         local rc
17344         local count
17345         local size
17346         local flags
17347
17348         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17349                 skip "OFD access log unsupported"
17350
17351         setup_165
17352         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17353         sleep 5
17354
17355         do_facet ost1 ofd_access_log_reader --list
17356
17357         lfs setstripe -c 1 -i 0 "${file}"
17358         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17359                 error "cannot create '${file}'"
17360
17361         sleep 5
17362         do_facet ost1 killall -TERM ofd_access_log_reader
17363         wait
17364         rc=$?
17365
17366         if ((rc != 0)); then
17367                 error "ofd_access_log_reader exited with rc = '${rc}'"
17368         fi
17369
17370         oalr_expect_event_count alr_log_entry "${trace}" 1
17371
17372         pfid1=$($LFS path2fid "${file}")
17373
17374         # 1     2             3   4    5     6   7    8    9     10
17375         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17376         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17377
17378         echo "entry = '${entry[*]}'" >&2
17379
17380         pfid2=${entry[4]}
17381         if [[ "${pfid1}" != "${pfid2}" ]]; then
17382                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17383         fi
17384
17385         size=${entry[8]}
17386         if ((size != 1048576)); then
17387                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17388         fi
17389
17390         flags=${entry[10]}
17391         if [[ "${flags}" != "w" ]]; then
17392                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17393         fi
17394
17395         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17396         sleep 5
17397
17398         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17399                 error "cannot read '${file}'"
17400         sleep 5
17401
17402         do_facet ost1 killall -TERM ofd_access_log_reader
17403         wait
17404         rc=$?
17405
17406         if ((rc != 0)); then
17407                 error "ofd_access_log_reader exited with rc = '${rc}'"
17408         fi
17409
17410         oalr_expect_event_count alr_log_entry "${trace}" 1
17411
17412         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17413         echo "entry = '${entry[*]}'" >&2
17414
17415         pfid2=${entry[4]}
17416         if [[ "${pfid1}" != "${pfid2}" ]]; then
17417                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17418         fi
17419
17420         size=${entry[8]}
17421         if ((size != 524288)); then
17422                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17423         fi
17424
17425         flags=${entry[10]}
17426         if [[ "${flags}" != "r" ]]; then
17427                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17428         fi
17429 }
17430 run_test 165b "ofd access log entries are produced and consumed"
17431
17432 test_165c() {
17433         local trace="/tmp/${tfile}.trace"
17434         local file="${DIR}/${tdir}/${tfile}"
17435
17436         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17437                 skip "OFD access log unsupported"
17438
17439         test_mkdir "${DIR}/${tdir}"
17440
17441         setup_165
17442         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17443         sleep 5
17444
17445         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17446
17447         # 4096 / 64 = 64. Create twice as many entries.
17448         for ((i = 0; i < 128; i++)); do
17449                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17450                         error "cannot create file"
17451         done
17452
17453         sync
17454
17455         do_facet ost1 killall -TERM ofd_access_log_reader
17456         wait
17457         rc=$?
17458         if ((rc != 0)); then
17459                 error "ofd_access_log_reader exited with rc = '${rc}'"
17460         fi
17461
17462         unlinkmany  "${file}-%d" 128
17463 }
17464 run_test 165c "full ofd access logs do not block IOs"
17465
17466 oal_get_read_count() {
17467         local stats="$1"
17468
17469         # STATS lustre-OST0001 alr_read_count 1
17470
17471         do_facet ost1 cat "${stats}" |
17472         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17473              END { print count; }'
17474 }
17475
17476 oal_expect_read_count() {
17477         local stats="$1"
17478         local count
17479         local expect="$2"
17480
17481         # Ask ofd_access_log_reader to write stats.
17482         do_facet ost1 killall -USR1 ofd_access_log_reader
17483
17484         # Allow some time for things to happen.
17485         sleep 1
17486
17487         count=$(oal_get_read_count "${stats}")
17488         if ((count == expect)); then
17489                 return 0
17490         fi
17491
17492         error_noexit "bad read count, got ${count}, expected ${expect}"
17493         do_facet ost1 cat "${stats}" >&2
17494         exit 1
17495 }
17496
17497 test_165d() {
17498         local stats="/tmp/${tfile}.stats"
17499         local file="${DIR}/${tdir}/${tfile}"
17500         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17501
17502         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17503                 skip "OFD access log unsupported"
17504
17505         test_mkdir "${DIR}/${tdir}"
17506
17507         setup_165
17508         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17509         sleep 5
17510
17511         lfs setstripe -c 1 -i 0 "${file}"
17512
17513         do_facet ost1 lctl set_param "${param}=rw"
17514         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17515                 error "cannot create '${file}'"
17516         oal_expect_read_count "${stats}" 1
17517
17518         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17519                 error "cannot read '${file}'"
17520         oal_expect_read_count "${stats}" 2
17521
17522         do_facet ost1 lctl set_param "${param}=r"
17523         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17524                 error "cannot create '${file}'"
17525         oal_expect_read_count "${stats}" 2
17526
17527         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17528                 error "cannot read '${file}'"
17529         oal_expect_read_count "${stats}" 3
17530
17531         do_facet ost1 lctl set_param "${param}=w"
17532         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17533                 error "cannot create '${file}'"
17534         oal_expect_read_count "${stats}" 4
17535
17536         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17537                 error "cannot read '${file}'"
17538         oal_expect_read_count "${stats}" 4
17539
17540         do_facet ost1 lctl set_param "${param}=0"
17541         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17542                 error "cannot create '${file}'"
17543         oal_expect_read_count "${stats}" 4
17544
17545         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17546                 error "cannot read '${file}'"
17547         oal_expect_read_count "${stats}" 4
17548
17549         do_facet ost1 killall -TERM ofd_access_log_reader
17550         wait
17551         rc=$?
17552         if ((rc != 0)); then
17553                 error "ofd_access_log_reader exited with rc = '${rc}'"
17554         fi
17555 }
17556 run_test 165d "ofd_access_log mask works"
17557
17558 test_165e() {
17559         local stats="/tmp/${tfile}.stats"
17560         local file0="${DIR}/${tdir}-0/${tfile}"
17561         local file1="${DIR}/${tdir}-1/${tfile}"
17562
17563         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17564                 skip "OFD access log unsupported"
17565
17566         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17567
17568         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17569         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17570
17571         lfs setstripe -c 1 -i 0 "${file0}"
17572         lfs setstripe -c 1 -i 0 "${file1}"
17573
17574         setup_165
17575         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17576         sleep 5
17577
17578         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17579                 error "cannot create '${file0}'"
17580         sync
17581         oal_expect_read_count "${stats}" 0
17582
17583         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17584                 error "cannot create '${file1}'"
17585         sync
17586         oal_expect_read_count "${stats}" 1
17587
17588         do_facet ost1 killall -TERM ofd_access_log_reader
17589         wait
17590         rc=$?
17591         if ((rc != 0)); then
17592                 error "ofd_access_log_reader exited with rc = '${rc}'"
17593         fi
17594 }
17595 run_test 165e "ofd_access_log MDT index filter works"
17596
17597 test_165f() {
17598         local trace="/tmp/${tfile}.trace"
17599         local rc
17600         local count
17601
17602         setup_165
17603         do_facet ost1 timeout 60 ofd_access_log_reader \
17604                 --exit-on-close --debug=- --trace=- > "${trace}" &
17605         sleep 5
17606         stop ost1
17607
17608         wait
17609         rc=$?
17610
17611         if ((rc != 0)); then
17612                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17613                 cat "${trace}"
17614                 exit 1
17615         fi
17616 }
17617 run_test 165f "ofd_access_log_reader --exit-on-close works"
17618
17619 test_169() {
17620         # do directio so as not to populate the page cache
17621         log "creating a 10 Mb file"
17622         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17623                 error "multiop failed while creating a file"
17624         log "starting reads"
17625         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17626         log "truncating the file"
17627         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17628                 error "multiop failed while truncating the file"
17629         log "killing dd"
17630         kill %+ || true # reads might have finished
17631         echo "wait until dd is finished"
17632         wait
17633         log "removing the temporary file"
17634         rm -rf $DIR/$tfile || error "tmp file removal failed"
17635 }
17636 run_test 169 "parallel read and truncate should not deadlock"
17637
17638 test_170() {
17639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17640
17641         $LCTL clear     # bug 18514
17642         $LCTL debug_daemon start $TMP/${tfile}_log_good
17643         touch $DIR/$tfile
17644         $LCTL debug_daemon stop
17645         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17646                 error "sed failed to read log_good"
17647
17648         $LCTL debug_daemon start $TMP/${tfile}_log_good
17649         rm -rf $DIR/$tfile
17650         $LCTL debug_daemon stop
17651
17652         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17653                error "lctl df log_bad failed"
17654
17655         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17656         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17657
17658         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17659         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17660
17661         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17662                 error "bad_line good_line1 good_line2 are empty"
17663
17664         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17665         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17666         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17667
17668         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17669         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17670         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17671
17672         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17673                 error "bad_line_new good_line_new are empty"
17674
17675         local expected_good=$((good_line1 + good_line2*2))
17676
17677         rm -f $TMP/${tfile}*
17678         # LU-231, short malformed line may not be counted into bad lines
17679         if [ $bad_line -ne $bad_line_new ] &&
17680                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17681                 error "expected $bad_line bad lines, but got $bad_line_new"
17682                 return 1
17683         fi
17684
17685         if [ $expected_good -ne $good_line_new ]; then
17686                 error "expected $expected_good good lines, but got $good_line_new"
17687                 return 2
17688         fi
17689         true
17690 }
17691 run_test 170 "test lctl df to handle corrupted log ====================="
17692
17693 test_171() { # bug20592
17694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17695
17696         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17697         $LCTL set_param fail_loc=0x50e
17698         $LCTL set_param fail_val=3000
17699         multiop_bg_pause $DIR/$tfile O_s || true
17700         local MULTIPID=$!
17701         kill -USR1 $MULTIPID
17702         # cause log dump
17703         sleep 3
17704         wait $MULTIPID
17705         if dmesg | grep "recursive fault"; then
17706                 error "caught a recursive fault"
17707         fi
17708         $LCTL set_param fail_loc=0
17709         true
17710 }
17711 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17712
17713 # it would be good to share it with obdfilter-survey/iokit-libecho code
17714 setup_obdecho_osc () {
17715         local rc=0
17716         local ost_nid=$1
17717         local obdfilter_name=$2
17718         echo "Creating new osc for $obdfilter_name on $ost_nid"
17719         # make sure we can find loopback nid
17720         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17721
17722         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17723                            ${obdfilter_name}_osc_UUID || rc=2; }
17724         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17725                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17726         return $rc
17727 }
17728
17729 cleanup_obdecho_osc () {
17730         local obdfilter_name=$1
17731         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17732         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17733         return 0
17734 }
17735
17736 obdecho_test() {
17737         local OBD=$1
17738         local node=$2
17739         local pages=${3:-64}
17740         local rc=0
17741         local id
17742
17743         local count=10
17744         local obd_size=$(get_obd_size $node $OBD)
17745         local page_size=$(get_page_size $node)
17746         if [[ -n "$obd_size" ]]; then
17747                 local new_count=$((obd_size / (pages * page_size / 1024)))
17748                 [[ $new_count -ge $count ]] || count=$new_count
17749         fi
17750
17751         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17752         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17753                            rc=2; }
17754         if [ $rc -eq 0 ]; then
17755             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17756             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17757         fi
17758         echo "New object id is $id"
17759         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17760                            rc=4; }
17761         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17762                            "test_brw $count w v $pages $id" || rc=4; }
17763         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17764                            rc=4; }
17765         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17766                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17767         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17768                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17769         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17770         return $rc
17771 }
17772
17773 test_180a() {
17774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17775
17776         if ! [ -d /sys/fs/lustre/echo_client ] &&
17777            ! module_loaded obdecho; then
17778                 load_module obdecho/obdecho &&
17779                         stack_trap "rmmod obdecho" EXIT ||
17780                         error "unable to load obdecho on client"
17781         fi
17782
17783         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17784         local host=$($LCTL get_param -n osc.$osc.import |
17785                      awk '/current_connection:/ { print $2 }' )
17786         local target=$($LCTL get_param -n osc.$osc.import |
17787                        awk '/target:/ { print $2 }' )
17788         target=${target%_UUID}
17789
17790         if [ -n "$target" ]; then
17791                 setup_obdecho_osc $host $target &&
17792                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17793                         { error "obdecho setup failed with $?"; return; }
17794
17795                 obdecho_test ${target}_osc client ||
17796                         error "obdecho_test failed on ${target}_osc"
17797         else
17798                 $LCTL get_param osc.$osc.import
17799                 error "there is no osc.$osc.import target"
17800         fi
17801 }
17802 run_test 180a "test obdecho on osc"
17803
17804 test_180b() {
17805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17806         remote_ost_nodsh && skip "remote OST with nodsh"
17807
17808         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17809                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17810                 error "failed to load module obdecho"
17811
17812         local target=$(do_facet ost1 $LCTL dl |
17813                        awk '/obdfilter/ { print $4; exit; }')
17814
17815         if [ -n "$target" ]; then
17816                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17817         else
17818                 do_facet ost1 $LCTL dl
17819                 error "there is no obdfilter target on ost1"
17820         fi
17821 }
17822 run_test 180b "test obdecho directly on obdfilter"
17823
17824 test_180c() { # LU-2598
17825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17826         remote_ost_nodsh && skip "remote OST with nodsh"
17827         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17828                 skip "Need MDS version at least 2.4.0"
17829
17830         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17831                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17832                 error "failed to load module obdecho"
17833
17834         local target=$(do_facet ost1 $LCTL dl |
17835                        awk '/obdfilter/ { print $4; exit; }')
17836
17837         if [ -n "$target" ]; then
17838                 local pages=16384 # 64MB bulk I/O RPC size
17839
17840                 obdecho_test "$target" ost1 "$pages" ||
17841                         error "obdecho_test with pages=$pages failed with $?"
17842         else
17843                 do_facet ost1 $LCTL dl
17844                 error "there is no obdfilter target on ost1"
17845         fi
17846 }
17847 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17848
17849 test_181() { # bug 22177
17850         test_mkdir $DIR/$tdir
17851         # create enough files to index the directory
17852         createmany -o $DIR/$tdir/foobar 4000
17853         # print attributes for debug purpose
17854         lsattr -d .
17855         # open dir
17856         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17857         MULTIPID=$!
17858         # remove the files & current working dir
17859         unlinkmany $DIR/$tdir/foobar 4000
17860         rmdir $DIR/$tdir
17861         kill -USR1 $MULTIPID
17862         wait $MULTIPID
17863         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17864         return 0
17865 }
17866 run_test 181 "Test open-unlinked dir ========================"
17867
17868 test_182() {
17869         local fcount=1000
17870         local tcount=10
17871
17872         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17873
17874         $LCTL set_param mdc.*.rpc_stats=clear
17875
17876         for (( i = 0; i < $tcount; i++ )) ; do
17877                 mkdir $DIR/$tdir/$i
17878         done
17879
17880         for (( i = 0; i < $tcount; i++ )) ; do
17881                 createmany -o $DIR/$tdir/$i/f- $fcount &
17882         done
17883         wait
17884
17885         for (( i = 0; i < $tcount; i++ )) ; do
17886                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17887         done
17888         wait
17889
17890         $LCTL get_param mdc.*.rpc_stats
17891
17892         rm -rf $DIR/$tdir
17893 }
17894 run_test 182 "Test parallel modify metadata operations ================"
17895
17896 test_183() { # LU-2275
17897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17898         remote_mds_nodsh && skip "remote MDS with nodsh"
17899         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17900                 skip "Need MDS version at least 2.3.56"
17901
17902         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17903         echo aaa > $DIR/$tdir/$tfile
17904
17905 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17906         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17907
17908         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17909         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17910
17911         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17912
17913         # Flush negative dentry cache
17914         touch $DIR/$tdir/$tfile
17915
17916         # We are not checking for any leaked references here, they'll
17917         # become evident next time we do cleanup with module unload.
17918         rm -rf $DIR/$tdir
17919 }
17920 run_test 183 "No crash or request leak in case of strange dispositions ========"
17921
17922 # test suite 184 is for LU-2016, LU-2017
17923 test_184a() {
17924         check_swap_layouts_support
17925
17926         dir0=$DIR/$tdir/$testnum
17927         test_mkdir -p -c1 $dir0
17928         ref1=/etc/passwd
17929         ref2=/etc/group
17930         file1=$dir0/f1
17931         file2=$dir0/f2
17932         $LFS setstripe -c1 $file1
17933         cp $ref1 $file1
17934         $LFS setstripe -c2 $file2
17935         cp $ref2 $file2
17936         gen1=$($LFS getstripe -g $file1)
17937         gen2=$($LFS getstripe -g $file2)
17938
17939         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17940         gen=$($LFS getstripe -g $file1)
17941         [[ $gen1 != $gen ]] ||
17942                 error "Layout generation on $file1 does not change"
17943         gen=$($LFS getstripe -g $file2)
17944         [[ $gen2 != $gen ]] ||
17945                 error "Layout generation on $file2 does not change"
17946
17947         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17948         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17949
17950         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17951 }
17952 run_test 184a "Basic layout swap"
17953
17954 test_184b() {
17955         check_swap_layouts_support
17956
17957         dir0=$DIR/$tdir/$testnum
17958         mkdir -p $dir0 || error "creating dir $dir0"
17959         file1=$dir0/f1
17960         file2=$dir0/f2
17961         file3=$dir0/f3
17962         dir1=$dir0/d1
17963         dir2=$dir0/d2
17964         mkdir $dir1 $dir2
17965         $LFS setstripe -c1 $file1
17966         $LFS setstripe -c2 $file2
17967         $LFS setstripe -c1 $file3
17968         chown $RUNAS_ID $file3
17969         gen1=$($LFS getstripe -g $file1)
17970         gen2=$($LFS getstripe -g $file2)
17971
17972         $LFS swap_layouts $dir1 $dir2 &&
17973                 error "swap of directories layouts should fail"
17974         $LFS swap_layouts $dir1 $file1 &&
17975                 error "swap of directory and file layouts should fail"
17976         $RUNAS $LFS swap_layouts $file1 $file2 &&
17977                 error "swap of file we cannot write should fail"
17978         $LFS swap_layouts $file1 $file3 &&
17979                 error "swap of file with different owner should fail"
17980         /bin/true # to clear error code
17981 }
17982 run_test 184b "Forbidden layout swap (will generate errors)"
17983
17984 test_184c() {
17985         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17986         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17987         check_swap_layouts_support
17988         check_swap_layout_no_dom $DIR
17989
17990         local dir0=$DIR/$tdir/$testnum
17991         mkdir -p $dir0 || error "creating dir $dir0"
17992
17993         local ref1=$dir0/ref1
17994         local ref2=$dir0/ref2
17995         local file1=$dir0/file1
17996         local file2=$dir0/file2
17997         # create a file large enough for the concurrent test
17998         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17999         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18000         echo "ref file size: ref1($(stat -c %s $ref1))," \
18001              "ref2($(stat -c %s $ref2))"
18002
18003         cp $ref2 $file2
18004         dd if=$ref1 of=$file1 bs=16k &
18005         local DD_PID=$!
18006
18007         # Make sure dd starts to copy file, but wait at most 5 seconds
18008         local loops=0
18009         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18010
18011         $LFS swap_layouts $file1 $file2
18012         local rc=$?
18013         wait $DD_PID
18014         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18015         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18016
18017         # how many bytes copied before swapping layout
18018         local copied=$(stat -c %s $file2)
18019         local remaining=$(stat -c %s $ref1)
18020         remaining=$((remaining - copied))
18021         echo "Copied $copied bytes before swapping layout..."
18022
18023         cmp -n $copied $file1 $ref2 | grep differ &&
18024                 error "Content mismatch [0, $copied) of ref2 and file1"
18025         cmp -n $copied $file2 $ref1 ||
18026                 error "Content mismatch [0, $copied) of ref1 and file2"
18027         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18028                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18029
18030         # clean up
18031         rm -f $ref1 $ref2 $file1 $file2
18032 }
18033 run_test 184c "Concurrent write and layout swap"
18034
18035 test_184d() {
18036         check_swap_layouts_support
18037         check_swap_layout_no_dom $DIR
18038         [ -z "$(which getfattr 2>/dev/null)" ] &&
18039                 skip_env "no getfattr command"
18040
18041         local file1=$DIR/$tdir/$tfile-1
18042         local file2=$DIR/$tdir/$tfile-2
18043         local file3=$DIR/$tdir/$tfile-3
18044         local lovea1
18045         local lovea2
18046
18047         mkdir -p $DIR/$tdir
18048         touch $file1 || error "create $file1 failed"
18049         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18050                 error "create $file2 failed"
18051         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18052                 error "create $file3 failed"
18053         lovea1=$(get_layout_param $file1)
18054
18055         $LFS swap_layouts $file2 $file3 ||
18056                 error "swap $file2 $file3 layouts failed"
18057         $LFS swap_layouts $file1 $file2 ||
18058                 error "swap $file1 $file2 layouts failed"
18059
18060         lovea2=$(get_layout_param $file2)
18061         echo "$lovea1"
18062         echo "$lovea2"
18063         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18064
18065         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18066         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18067 }
18068 run_test 184d "allow stripeless layouts swap"
18069
18070 test_184e() {
18071         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18072                 skip "Need MDS version at least 2.6.94"
18073         check_swap_layouts_support
18074         check_swap_layout_no_dom $DIR
18075         [ -z "$(which getfattr 2>/dev/null)" ] &&
18076                 skip_env "no getfattr command"
18077
18078         local file1=$DIR/$tdir/$tfile-1
18079         local file2=$DIR/$tdir/$tfile-2
18080         local file3=$DIR/$tdir/$tfile-3
18081         local lovea
18082
18083         mkdir -p $DIR/$tdir
18084         touch $file1 || error "create $file1 failed"
18085         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18086                 error "create $file2 failed"
18087         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18088                 error "create $file3 failed"
18089
18090         $LFS swap_layouts $file1 $file2 ||
18091                 error "swap $file1 $file2 layouts failed"
18092
18093         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18094         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18095
18096         echo 123 > $file1 || error "Should be able to write into $file1"
18097
18098         $LFS swap_layouts $file1 $file3 ||
18099                 error "swap $file1 $file3 layouts failed"
18100
18101         echo 123 > $file1 || error "Should be able to write into $file1"
18102
18103         rm -rf $file1 $file2 $file3
18104 }
18105 run_test 184e "Recreate layout after stripeless layout swaps"
18106
18107 test_184f() {
18108         # Create a file with name longer than sizeof(struct stat) ==
18109         # 144 to see if we can get chars from the file name to appear
18110         # in the returned striping. Note that 'f' == 0x66.
18111         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18112
18113         mkdir -p $DIR/$tdir
18114         mcreate $DIR/$tdir/$file
18115         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18116                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18117         fi
18118 }
18119 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18120
18121 test_185() { # LU-2441
18122         # LU-3553 - no volatile file support in old servers
18123         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18124                 skip "Need MDS version at least 2.3.60"
18125
18126         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18127         touch $DIR/$tdir/spoo
18128         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18129         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18130                 error "cannot create/write a volatile file"
18131         [ "$FILESET" == "" ] &&
18132         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18133                 error "FID is still valid after close"
18134
18135         multiop_bg_pause $DIR/$tdir vVw4096_c
18136         local multi_pid=$!
18137
18138         local OLD_IFS=$IFS
18139         IFS=":"
18140         local fidv=($fid)
18141         IFS=$OLD_IFS
18142         # assume that the next FID for this client is sequential, since stdout
18143         # is unfortunately eaten by multiop_bg_pause
18144         local n=$((${fidv[1]} + 1))
18145         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18146         if [ "$FILESET" == "" ]; then
18147                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18148                         error "FID is missing before close"
18149         fi
18150         kill -USR1 $multi_pid
18151         # 1 second delay, so if mtime change we will see it
18152         sleep 1
18153         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18154         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18155 }
18156 run_test 185 "Volatile file support"
18157
18158 function create_check_volatile() {
18159         local idx=$1
18160         local tgt
18161
18162         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18163         local PID=$!
18164         sleep 1
18165         local FID=$(cat /tmp/${tfile}.fid)
18166         [ "$FID" == "" ] && error "can't get FID for volatile"
18167         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18168         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18169         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18170         kill -USR1 $PID
18171         wait
18172         sleep 1
18173         cancel_lru_locks mdc # flush opencache
18174         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18175         return 0
18176 }
18177
18178 test_185a(){
18179         # LU-12516 - volatile creation via .lustre
18180         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18181                 skip "Need MDS version at least 2.3.55"
18182
18183         create_check_volatile 0
18184         [ $MDSCOUNT -lt 2 ] && return 0
18185
18186         # DNE case
18187         create_check_volatile 1
18188
18189         return 0
18190 }
18191 run_test 185a "Volatile file creation in .lustre/fid/"
18192
18193 test_187a() {
18194         remote_mds_nodsh && skip "remote MDS with nodsh"
18195         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18196                 skip "Need MDS version at least 2.3.0"
18197
18198         local dir0=$DIR/$tdir/$testnum
18199         mkdir -p $dir0 || error "creating dir $dir0"
18200
18201         local file=$dir0/file1
18202         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18203         local dv1=$($LFS data_version $file)
18204         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18205         local dv2=$($LFS data_version $file)
18206         [[ $dv1 != $dv2 ]] ||
18207                 error "data version did not change on write $dv1 == $dv2"
18208
18209         # clean up
18210         rm -f $file1
18211 }
18212 run_test 187a "Test data version change"
18213
18214 test_187b() {
18215         remote_mds_nodsh && skip "remote MDS with nodsh"
18216         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18217                 skip "Need MDS version at least 2.3.0"
18218
18219         local dir0=$DIR/$tdir/$testnum
18220         mkdir -p $dir0 || error "creating dir $dir0"
18221
18222         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18223         [[ ${DV[0]} != ${DV[1]} ]] ||
18224                 error "data version did not change on write"\
18225                       " ${DV[0]} == ${DV[1]}"
18226
18227         # clean up
18228         rm -f $file1
18229 }
18230 run_test 187b "Test data version change on volatile file"
18231
18232 test_200() {
18233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18234         remote_mgs_nodsh && skip "remote MGS with nodsh"
18235         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18236
18237         local POOL=${POOL:-cea1}
18238         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18239         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18240         # Pool OST targets
18241         local first_ost=0
18242         local last_ost=$(($OSTCOUNT - 1))
18243         local ost_step=2
18244         local ost_list=$(seq $first_ost $ost_step $last_ost)
18245         local ost_range="$first_ost $last_ost $ost_step"
18246         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18247         local file_dir=$POOL_ROOT/file_tst
18248         local subdir=$test_path/subdir
18249         local rc=0
18250
18251         while : ; do
18252                 # former test_200a test_200b
18253                 pool_add $POOL                          || { rc=$? ; break; }
18254                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18255                 # former test_200c test_200d
18256                 mkdir -p $test_path
18257                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18258                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18259                 mkdir -p $subdir
18260                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18261                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18262                                                         || { rc=$? ; break; }
18263                 # former test_200e test_200f
18264                 local files=$((OSTCOUNT*3))
18265                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18266                                                         || { rc=$? ; break; }
18267                 pool_create_files $POOL $file_dir $files "$ost_list" \
18268                                                         || { rc=$? ; break; }
18269                 # former test_200g test_200h
18270                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18271                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18272
18273                 # former test_201a test_201b test_201c
18274                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18275
18276                 local f=$test_path/$tfile
18277                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18278                 pool_remove $POOL $f                    || { rc=$? ; break; }
18279                 break
18280         done
18281
18282         destroy_test_pools
18283
18284         return $rc
18285 }
18286 run_test 200 "OST pools"
18287
18288 # usage: default_attr <count | size | offset>
18289 default_attr() {
18290         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18291 }
18292
18293 # usage: check_default_stripe_attr
18294 check_default_stripe_attr() {
18295         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18296         case $1 in
18297         --stripe-count|-c)
18298                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18299         --stripe-size|-S)
18300                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18301         --stripe-index|-i)
18302                 EXPECTED=-1;;
18303         *)
18304                 error "unknown getstripe attr '$1'"
18305         esac
18306
18307         [ $ACTUAL == $EXPECTED ] ||
18308                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18309 }
18310
18311 test_204a() {
18312         test_mkdir $DIR/$tdir
18313         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18314
18315         check_default_stripe_attr --stripe-count
18316         check_default_stripe_attr --stripe-size
18317         check_default_stripe_attr --stripe-index
18318 }
18319 run_test 204a "Print default stripe attributes"
18320
18321 test_204b() {
18322         test_mkdir $DIR/$tdir
18323         $LFS setstripe --stripe-count 1 $DIR/$tdir
18324
18325         check_default_stripe_attr --stripe-size
18326         check_default_stripe_attr --stripe-index
18327 }
18328 run_test 204b "Print default stripe size and offset"
18329
18330 test_204c() {
18331         test_mkdir $DIR/$tdir
18332         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18333
18334         check_default_stripe_attr --stripe-count
18335         check_default_stripe_attr --stripe-index
18336 }
18337 run_test 204c "Print default stripe count and offset"
18338
18339 test_204d() {
18340         test_mkdir $DIR/$tdir
18341         $LFS setstripe --stripe-index 0 $DIR/$tdir
18342
18343         check_default_stripe_attr --stripe-count
18344         check_default_stripe_attr --stripe-size
18345 }
18346 run_test 204d "Print default stripe count and size"
18347
18348 test_204e() {
18349         test_mkdir $DIR/$tdir
18350         $LFS setstripe -d $DIR/$tdir
18351
18352         check_default_stripe_attr --stripe-count --raw
18353         check_default_stripe_attr --stripe-size --raw
18354         check_default_stripe_attr --stripe-index --raw
18355 }
18356 run_test 204e "Print raw stripe attributes"
18357
18358 test_204f() {
18359         test_mkdir $DIR/$tdir
18360         $LFS setstripe --stripe-count 1 $DIR/$tdir
18361
18362         check_default_stripe_attr --stripe-size --raw
18363         check_default_stripe_attr --stripe-index --raw
18364 }
18365 run_test 204f "Print raw stripe size and offset"
18366
18367 test_204g() {
18368         test_mkdir $DIR/$tdir
18369         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18370
18371         check_default_stripe_attr --stripe-count --raw
18372         check_default_stripe_attr --stripe-index --raw
18373 }
18374 run_test 204g "Print raw stripe count and offset"
18375
18376 test_204h() {
18377         test_mkdir $DIR/$tdir
18378         $LFS setstripe --stripe-index 0 $DIR/$tdir
18379
18380         check_default_stripe_attr --stripe-count --raw
18381         check_default_stripe_attr --stripe-size --raw
18382 }
18383 run_test 204h "Print raw stripe count and size"
18384
18385 # Figure out which job scheduler is being used, if any,
18386 # or use a fake one
18387 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18388         JOBENV=SLURM_JOB_ID
18389 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18390         JOBENV=LSB_JOBID
18391 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18392         JOBENV=PBS_JOBID
18393 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18394         JOBENV=LOADL_STEP_ID
18395 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18396         JOBENV=JOB_ID
18397 else
18398         $LCTL list_param jobid_name > /dev/null 2>&1
18399         if [ $? -eq 0 ]; then
18400                 JOBENV=nodelocal
18401         else
18402                 JOBENV=FAKE_JOBID
18403         fi
18404 fi
18405 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18406
18407 verify_jobstats() {
18408         local cmd=($1)
18409         shift
18410         local facets="$@"
18411
18412 # we don't really need to clear the stats for this test to work, since each
18413 # command has a unique jobid, but it makes debugging easier if needed.
18414 #       for facet in $facets; do
18415 #               local dev=$(convert_facet2label $facet)
18416 #               # clear old jobstats
18417 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18418 #       done
18419
18420         # use a new JobID for each test, or we might see an old one
18421         [ "$JOBENV" = "FAKE_JOBID" ] &&
18422                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18423
18424         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18425
18426         [ "$JOBENV" = "nodelocal" ] && {
18427                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18428                 $LCTL set_param jobid_name=$FAKE_JOBID
18429                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18430         }
18431
18432         log "Test: ${cmd[*]}"
18433         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18434
18435         if [ $JOBENV = "FAKE_JOBID" ]; then
18436                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18437         else
18438                 ${cmd[*]}
18439         fi
18440
18441         # all files are created on OST0000
18442         for facet in $facets; do
18443                 local stats="*.$(convert_facet2label $facet).job_stats"
18444
18445                 # strip out libtool wrappers for in-tree executables
18446                 if (( $(do_facet $facet lctl get_param $stats |
18447                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18448                         do_facet $facet lctl get_param $stats
18449                         error "No jobstats for $JOBVAL found on $facet::$stats"
18450                 fi
18451         done
18452 }
18453
18454 jobstats_set() {
18455         local new_jobenv=$1
18456
18457         set_persistent_param_and_check client "jobid_var" \
18458                 "$FSNAME.sys.jobid_var" $new_jobenv
18459 }
18460
18461 test_205a() { # Job stats
18462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18463         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18464                 skip "Need MDS version with at least 2.7.1"
18465         remote_mgs_nodsh && skip "remote MGS with nodsh"
18466         remote_mds_nodsh && skip "remote MDS with nodsh"
18467         remote_ost_nodsh && skip "remote OST with nodsh"
18468         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18469                 skip "Server doesn't support jobstats"
18470         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18471
18472         local old_jobenv=$($LCTL get_param -n jobid_var)
18473         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18474
18475         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18476                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18477         else
18478                 stack_trap "do_facet mgs $PERM_CMD \
18479                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18480         fi
18481         changelog_register
18482
18483         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18484                                 mdt.*.job_cleanup_interval | head -n 1)
18485         local new_interval=5
18486         do_facet $SINGLEMDS \
18487                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18488         stack_trap "do_facet $SINGLEMDS \
18489                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18490         local start=$SECONDS
18491
18492         local cmd
18493         # mkdir
18494         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18495         verify_jobstats "$cmd" "$SINGLEMDS"
18496         # rmdir
18497         cmd="rmdir $DIR/$tdir"
18498         verify_jobstats "$cmd" "$SINGLEMDS"
18499         # mkdir on secondary MDT
18500         if [ $MDSCOUNT -gt 1 ]; then
18501                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18502                 verify_jobstats "$cmd" "mds2"
18503         fi
18504         # mknod
18505         cmd="mknod $DIR/$tfile c 1 3"
18506         verify_jobstats "$cmd" "$SINGLEMDS"
18507         # unlink
18508         cmd="rm -f $DIR/$tfile"
18509         verify_jobstats "$cmd" "$SINGLEMDS"
18510         # create all files on OST0000 so verify_jobstats can find OST stats
18511         # open & close
18512         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18513         verify_jobstats "$cmd" "$SINGLEMDS"
18514         # setattr
18515         cmd="touch $DIR/$tfile"
18516         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18517         # write
18518         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18519         verify_jobstats "$cmd" "ost1"
18520         # read
18521         cancel_lru_locks osc
18522         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18523         verify_jobstats "$cmd" "ost1"
18524         # truncate
18525         cmd="$TRUNCATE $DIR/$tfile 0"
18526         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18527         # rename
18528         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18529         verify_jobstats "$cmd" "$SINGLEMDS"
18530         # jobstats expiry - sleep until old stats should be expired
18531         local left=$((new_interval + 5 - (SECONDS - start)))
18532         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18533                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18534                         "0" $left
18535         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18536         verify_jobstats "$cmd" "$SINGLEMDS"
18537         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18538             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18539
18540         # Ensure that jobid are present in changelog (if supported by MDS)
18541         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18542                 changelog_dump | tail -10
18543                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18544                 [ $jobids -eq 9 ] ||
18545                         error "Wrong changelog jobid count $jobids != 9"
18546
18547                 # LU-5862
18548                 JOBENV="disable"
18549                 jobstats_set $JOBENV
18550                 touch $DIR/$tfile
18551                 changelog_dump | grep $tfile
18552                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18553                 [ $jobids -eq 0 ] ||
18554                         error "Unexpected jobids when jobid_var=$JOBENV"
18555         fi
18556
18557         # test '%j' access to environment variable - if supported
18558         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18559                 JOBENV="JOBCOMPLEX"
18560                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18561
18562                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18563         fi
18564
18565         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18566                 JOBENV="JOBCOMPLEX"
18567                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18568
18569                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18570         fi
18571
18572         # test '%j' access to per-session jobid - if supported
18573         if lctl list_param jobid_this_session > /dev/null 2>&1
18574         then
18575                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18576                 lctl set_param jobid_this_session=$USER
18577
18578                 JOBENV="JOBCOMPLEX"
18579                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18580
18581                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18582         fi
18583 }
18584 run_test 205a "Verify job stats"
18585
18586 # LU-13117, LU-13597
18587 test_205b() {
18588         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18589                 skip "Need MDS version at least 2.13.54.91"
18590
18591         job_stats="mdt.*.job_stats"
18592         $LCTL set_param $job_stats=clear
18593         # Setting jobid_var to USER might not be supported
18594         $LCTL set_param jobid_var=USER || true
18595         $LCTL set_param jobid_name="%e.%u"
18596         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18597         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18598                 grep "job_id:.*foolish" &&
18599                         error "Unexpected jobid found"
18600         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18601                 grep "open:.*min.*max.*sum" ||
18602                         error "wrong job_stats format found"
18603 }
18604 run_test 205b "Verify job stats jobid and output format"
18605
18606 # LU-13733
18607 test_205c() {
18608         $LCTL set_param llite.*.stats=0
18609         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18610         $LCTL get_param llite.*.stats
18611         $LCTL get_param llite.*.stats | grep \
18612                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18613                         error "wrong client stats format found"
18614 }
18615 run_test 205c "Verify client stats format"
18616
18617 # LU-1480, LU-1773 and LU-1657
18618 test_206() {
18619         mkdir -p $DIR/$tdir
18620         $LFS setstripe -c -1 $DIR/$tdir
18621 #define OBD_FAIL_LOV_INIT 0x1403
18622         $LCTL set_param fail_loc=0xa0001403
18623         $LCTL set_param fail_val=1
18624         touch $DIR/$tdir/$tfile || true
18625 }
18626 run_test 206 "fail lov_init_raid0() doesn't lbug"
18627
18628 test_207a() {
18629         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18630         local fsz=`stat -c %s $DIR/$tfile`
18631         cancel_lru_locks mdc
18632
18633         # do not return layout in getattr intent
18634 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18635         $LCTL set_param fail_loc=0x170
18636         local sz=`stat -c %s $DIR/$tfile`
18637
18638         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18639
18640         rm -rf $DIR/$tfile
18641 }
18642 run_test 207a "can refresh layout at glimpse"
18643
18644 test_207b() {
18645         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18646         local cksum=`md5sum $DIR/$tfile`
18647         local fsz=`stat -c %s $DIR/$tfile`
18648         cancel_lru_locks mdc
18649         cancel_lru_locks osc
18650
18651         # do not return layout in getattr intent
18652 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18653         $LCTL set_param fail_loc=0x171
18654
18655         # it will refresh layout after the file is opened but before read issues
18656         echo checksum is "$cksum"
18657         echo "$cksum" |md5sum -c --quiet || error "file differs"
18658
18659         rm -rf $DIR/$tfile
18660 }
18661 run_test 207b "can refresh layout at open"
18662
18663 test_208() {
18664         # FIXME: in this test suite, only RD lease is used. This is okay
18665         # for now as only exclusive open is supported. After generic lease
18666         # is done, this test suite should be revised. - Jinshan
18667
18668         remote_mds_nodsh && skip "remote MDS with nodsh"
18669         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18670                 skip "Need MDS version at least 2.4.52"
18671
18672         echo "==== test 1: verify get lease work"
18673         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18674
18675         echo "==== test 2: verify lease can be broken by upcoming open"
18676         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18677         local PID=$!
18678         sleep 2
18679
18680         $MULTIOP $DIR/$tfile oO_RDWR:c
18681         kill -USR1 $PID && wait $PID || error "break lease error"
18682
18683         echo "==== test 3: verify lease can't be granted if an open already exists"
18684         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18685         local PID=$!
18686         sleep 2
18687
18688         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18689         kill -USR1 $PID && wait $PID || error "open file error"
18690
18691         echo "==== test 4: lease can sustain over recovery"
18692         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18693         PID=$!
18694         sleep 2
18695
18696         fail mds1
18697
18698         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18699
18700         echo "==== test 5: lease broken can't be regained by replay"
18701         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18702         PID=$!
18703         sleep 2
18704
18705         # open file to break lease and then recovery
18706         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18707         fail mds1
18708
18709         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18710
18711         rm -f $DIR/$tfile
18712 }
18713 run_test 208 "Exclusive open"
18714
18715 test_209() {
18716         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18717                 skip_env "must have disp_stripe"
18718
18719         touch $DIR/$tfile
18720         sync; sleep 5; sync;
18721
18722         echo 3 > /proc/sys/vm/drop_caches
18723         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18724                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18725         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18726
18727         # open/close 500 times
18728         for i in $(seq 500); do
18729                 cat $DIR/$tfile
18730         done
18731
18732         echo 3 > /proc/sys/vm/drop_caches
18733         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18734                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18735         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18736
18737         echo "before: $req_before, after: $req_after"
18738         [ $((req_after - req_before)) -ge 300 ] &&
18739                 error "open/close requests are not freed"
18740         return 0
18741 }
18742 run_test 209 "read-only open/close requests should be freed promptly"
18743
18744 test_210() {
18745         local pid
18746
18747         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18748         pid=$!
18749         sleep 1
18750
18751         $LFS getstripe $DIR/$tfile
18752         kill -USR1 $pid
18753         wait $pid || error "multiop failed"
18754
18755         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18756         pid=$!
18757         sleep 1
18758
18759         $LFS getstripe $DIR/$tfile
18760         kill -USR1 $pid
18761         wait $pid || error "multiop failed"
18762 }
18763 run_test 210 "lfs getstripe does not break leases"
18764
18765 test_212() {
18766         size=`date +%s`
18767         size=$((size % 8192 + 1))
18768         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18769         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18770         rm -f $DIR/f212 $DIR/f212.xyz
18771 }
18772 run_test 212 "Sendfile test ============================================"
18773
18774 test_213() {
18775         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18776         cancel_lru_locks osc
18777         lctl set_param fail_loc=0x8000040f
18778         # generate a read lock
18779         cat $DIR/$tfile > /dev/null
18780         # write to the file, it will try to cancel the above read lock.
18781         cat /etc/hosts >> $DIR/$tfile
18782 }
18783 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18784
18785 test_214() { # for bug 20133
18786         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18787         for (( i=0; i < 340; i++ )) ; do
18788                 touch $DIR/$tdir/d214c/a$i
18789         done
18790
18791         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18792         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18793         ls $DIR/d214c || error "ls $DIR/d214c failed"
18794         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18795         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18796 }
18797 run_test 214 "hash-indexed directory test - bug 20133"
18798
18799 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18800 create_lnet_proc_files() {
18801         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18802 }
18803
18804 # counterpart of create_lnet_proc_files
18805 remove_lnet_proc_files() {
18806         rm -f $TMP/lnet_$1.sys
18807 }
18808
18809 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18810 # 3rd arg as regexp for body
18811 check_lnet_proc_stats() {
18812         local l=$(cat "$TMP/lnet_$1" |wc -l)
18813         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18814
18815         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18816 }
18817
18818 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18819 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18820 # optional and can be regexp for 2nd line (lnet.routes case)
18821 check_lnet_proc_entry() {
18822         local blp=2          # blp stands for 'position of 1st line of body'
18823         [ -z "$5" ] || blp=3 # lnet.routes case
18824
18825         local l=$(cat "$TMP/lnet_$1" |wc -l)
18826         # subtracting one from $blp because the body can be empty
18827         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18828
18829         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18830                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18831
18832         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18833                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18834
18835         # bail out if any unexpected line happened
18836         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18837         [ "$?" != 0 ] || error "$2 misformatted"
18838 }
18839
18840 test_215() { # for bugs 18102, 21079, 21517
18841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18842
18843         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18844         local P='[1-9][0-9]*'           # positive numeric
18845         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18846         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18847         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18848         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18849
18850         local L1 # regexp for 1st line
18851         local L2 # regexp for 2nd line (optional)
18852         local BR # regexp for the rest (body)
18853
18854         # lnet.stats should look as 11 space-separated non-negative numerics
18855         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18856         create_lnet_proc_files "stats"
18857         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18858         remove_lnet_proc_files "stats"
18859
18860         # lnet.routes should look like this:
18861         # Routing disabled/enabled
18862         # net hops priority state router
18863         # where net is a string like tcp0, hops > 0, priority >= 0,
18864         # state is up/down,
18865         # router is a string like 192.168.1.1@tcp2
18866         L1="^Routing (disabled|enabled)$"
18867         L2="^net +hops +priority +state +router$"
18868         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18869         create_lnet_proc_files "routes"
18870         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18871         remove_lnet_proc_files "routes"
18872
18873         # lnet.routers should look like this:
18874         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18875         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18876         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18877         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18878         L1="^ref +rtr_ref +alive +router$"
18879         BR="^$P +$P +(up|down) +$NID$"
18880         create_lnet_proc_files "routers"
18881         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18882         remove_lnet_proc_files "routers"
18883
18884         # lnet.peers should look like this:
18885         # nid refs state last max rtr min tx min queue
18886         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18887         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18888         # numeric (0 or >0 or <0), queue >= 0.
18889         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18890         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18891         create_lnet_proc_files "peers"
18892         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18893         remove_lnet_proc_files "peers"
18894
18895         # lnet.buffers  should look like this:
18896         # pages count credits min
18897         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18898         L1="^pages +count +credits +min$"
18899         BR="^ +$N +$N +$I +$I$"
18900         create_lnet_proc_files "buffers"
18901         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18902         remove_lnet_proc_files "buffers"
18903
18904         # lnet.nis should look like this:
18905         # nid status alive refs peer rtr max tx min
18906         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18907         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18908         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18909         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18910         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18911         create_lnet_proc_files "nis"
18912         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18913         remove_lnet_proc_files "nis"
18914
18915         # can we successfully write to lnet.stats?
18916         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18917 }
18918 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18919
18920 test_216() { # bug 20317
18921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18922         remote_ost_nodsh && skip "remote OST with nodsh"
18923
18924         local node
18925         local facets=$(get_facets OST)
18926         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18927
18928         save_lustre_params client "osc.*.contention_seconds" > $p
18929         save_lustre_params $facets \
18930                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18931         save_lustre_params $facets \
18932                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18933         save_lustre_params $facets \
18934                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18935         clear_stats osc.*.osc_stats
18936
18937         # agressive lockless i/o settings
18938         do_nodes $(comma_list $(osts_nodes)) \
18939                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18940                         ldlm.namespaces.filter-*.contended_locks=0 \
18941                         ldlm.namespaces.filter-*.contention_seconds=60"
18942         lctl set_param -n osc.*.contention_seconds=60
18943
18944         $DIRECTIO write $DIR/$tfile 0 10 4096
18945         $CHECKSTAT -s 40960 $DIR/$tfile
18946
18947         # disable lockless i/o
18948         do_nodes $(comma_list $(osts_nodes)) \
18949                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18950                         ldlm.namespaces.filter-*.contended_locks=32 \
18951                         ldlm.namespaces.filter-*.contention_seconds=0"
18952         lctl set_param -n osc.*.contention_seconds=0
18953         clear_stats osc.*.osc_stats
18954
18955         dd if=/dev/zero of=$DIR/$tfile count=0
18956         $CHECKSTAT -s 0 $DIR/$tfile
18957
18958         restore_lustre_params <$p
18959         rm -f $p
18960         rm $DIR/$tfile
18961 }
18962 run_test 216 "check lockless direct write updates file size and kms correctly"
18963
18964 test_217() { # bug 22430
18965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18966
18967         local node
18968         local nid
18969
18970         for node in $(nodes_list); do
18971                 nid=$(host_nids_address $node $NETTYPE)
18972                 if [[ $nid = *-* ]] ; then
18973                         echo "lctl ping $(h2nettype $nid)"
18974                         lctl ping $(h2nettype $nid)
18975                 else
18976                         echo "skipping $node (no hyphen detected)"
18977                 fi
18978         done
18979 }
18980 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18981
18982 test_218() {
18983        # do directio so as not to populate the page cache
18984        log "creating a 10 Mb file"
18985        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18986        log "starting reads"
18987        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18988        log "truncating the file"
18989        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18990        log "killing dd"
18991        kill %+ || true # reads might have finished
18992        echo "wait until dd is finished"
18993        wait
18994        log "removing the temporary file"
18995        rm -rf $DIR/$tfile || error "tmp file removal failed"
18996 }
18997 run_test 218 "parallel read and truncate should not deadlock"
18998
18999 test_219() {
19000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19001
19002         # write one partial page
19003         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19004         # set no grant so vvp_io_commit_write will do sync write
19005         $LCTL set_param fail_loc=0x411
19006         # write a full page at the end of file
19007         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19008
19009         $LCTL set_param fail_loc=0
19010         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19011         $LCTL set_param fail_loc=0x411
19012         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19013
19014         # LU-4201
19015         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19016         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19017 }
19018 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19019
19020 test_220() { #LU-325
19021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19022         remote_ost_nodsh && skip "remote OST with nodsh"
19023         remote_mds_nodsh && skip "remote MDS with nodsh"
19024         remote_mgs_nodsh && skip "remote MGS with nodsh"
19025
19026         local OSTIDX=0
19027
19028         # create on MDT0000 so the last_id and next_id are correct
19029         mkdir_on_mdt0 $DIR/$tdir
19030         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19031         OST=${OST%_UUID}
19032
19033         # on the mdt's osc
19034         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19035         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19036                         osp.$mdtosc_proc1.prealloc_last_id)
19037         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19038                         osp.$mdtosc_proc1.prealloc_next_id)
19039
19040         $LFS df -i
19041
19042         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19043         #define OBD_FAIL_OST_ENOINO              0x229
19044         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19045         create_pool $FSNAME.$TESTNAME || return 1
19046         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19047
19048         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19049
19050         MDSOBJS=$((last_id - next_id))
19051         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19052
19053         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19054         echo "OST still has $count kbytes free"
19055
19056         echo "create $MDSOBJS files @next_id..."
19057         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19058
19059         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19060                         osp.$mdtosc_proc1.prealloc_last_id)
19061         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19062                         osp.$mdtosc_proc1.prealloc_next_id)
19063
19064         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19065         $LFS df -i
19066
19067         echo "cleanup..."
19068
19069         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19070         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19071
19072         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19073                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19074         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19075                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19076         echo "unlink $MDSOBJS files @$next_id..."
19077         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19078 }
19079 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19080
19081 test_221() {
19082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19083
19084         dd if=`which date` of=$MOUNT/date oflag=sync
19085         chmod +x $MOUNT/date
19086
19087         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19088         $LCTL set_param fail_loc=0x80001401
19089
19090         $MOUNT/date > /dev/null
19091         rm -f $MOUNT/date
19092 }
19093 run_test 221 "make sure fault and truncate race to not cause OOM"
19094
19095 test_222a () {
19096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19097
19098         rm -rf $DIR/$tdir
19099         test_mkdir $DIR/$tdir
19100         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19101         createmany -o $DIR/$tdir/$tfile 10
19102         cancel_lru_locks mdc
19103         cancel_lru_locks osc
19104         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19105         $LCTL set_param fail_loc=0x31a
19106         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19107         $LCTL set_param fail_loc=0
19108         rm -r $DIR/$tdir
19109 }
19110 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19111
19112 test_222b () {
19113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19114
19115         rm -rf $DIR/$tdir
19116         test_mkdir $DIR/$tdir
19117         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19118         createmany -o $DIR/$tdir/$tfile 10
19119         cancel_lru_locks mdc
19120         cancel_lru_locks osc
19121         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19122         $LCTL set_param fail_loc=0x31a
19123         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19124         $LCTL set_param fail_loc=0
19125 }
19126 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19127
19128 test_223 () {
19129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19130
19131         rm -rf $DIR/$tdir
19132         test_mkdir $DIR/$tdir
19133         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19134         createmany -o $DIR/$tdir/$tfile 10
19135         cancel_lru_locks mdc
19136         cancel_lru_locks osc
19137         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19138         $LCTL set_param fail_loc=0x31b
19139         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19140         $LCTL set_param fail_loc=0
19141         rm -r $DIR/$tdir
19142 }
19143 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19144
19145 test_224a() { # LU-1039, MRP-303
19146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19147         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19148         $LCTL set_param fail_loc=0x508
19149         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19150         $LCTL set_param fail_loc=0
19151         df $DIR
19152 }
19153 run_test 224a "Don't panic on bulk IO failure"
19154
19155 test_224bd_sub() { # LU-1039, MRP-303
19156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19157         local timeout=$1
19158
19159         shift
19160         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19161
19162         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19163
19164         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19165         cancel_lru_locks osc
19166         set_checksums 0
19167         stack_trap "set_checksums $ORIG_CSUM" EXIT
19168         local at_max_saved=0
19169
19170         # adaptive timeouts may prevent seeing the issue
19171         if at_is_enabled; then
19172                 at_max_saved=$(at_max_get mds)
19173                 at_max_set 0 mds client
19174                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19175         fi
19176
19177         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19178         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19179         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19180
19181         do_facet ost1 $LCTL set_param fail_loc=0
19182         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19183         df $DIR
19184 }
19185
19186 test_224b() {
19187         test_224bd_sub 3 error "dd failed"
19188 }
19189 run_test 224b "Don't panic on bulk IO failure"
19190
19191 test_224c() { # LU-6441
19192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19193         remote_mds_nodsh && skip "remote MDS with nodsh"
19194
19195         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19196         save_writethrough $p
19197         set_cache writethrough on
19198
19199         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19200         local at_max=$($LCTL get_param -n at_max)
19201         local timeout=$($LCTL get_param -n timeout)
19202         local test_at="at_max"
19203         local param_at="$FSNAME.sys.at_max"
19204         local test_timeout="timeout"
19205         local param_timeout="$FSNAME.sys.timeout"
19206
19207         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19208
19209         set_persistent_param_and_check client "$test_at" "$param_at" 0
19210         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19211
19212         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19213         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19214         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19215         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19216         sync
19217         do_facet ost1 "$LCTL set_param fail_loc=0"
19218
19219         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19220         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19221                 $timeout
19222
19223         $LCTL set_param -n $pages_per_rpc
19224         restore_lustre_params < $p
19225         rm -f $p
19226 }
19227 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19228
19229 test_224d() { # LU-11169
19230         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19231 }
19232 run_test 224d "Don't corrupt data on bulk IO timeout"
19233
19234 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19235 test_225a () {
19236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19237         if [ -z ${MDSSURVEY} ]; then
19238                 skip_env "mds-survey not found"
19239         fi
19240         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19241                 skip "Need MDS version at least 2.2.51"
19242
19243         local mds=$(facet_host $SINGLEMDS)
19244         local target=$(do_nodes $mds 'lctl dl' |
19245                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19246
19247         local cmd1="file_count=1000 thrhi=4"
19248         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19249         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19250         local cmd="$cmd1 $cmd2 $cmd3"
19251
19252         rm -f ${TMP}/mds_survey*
19253         echo + $cmd
19254         eval $cmd || error "mds-survey with zero-stripe failed"
19255         cat ${TMP}/mds_survey*
19256         rm -f ${TMP}/mds_survey*
19257 }
19258 run_test 225a "Metadata survey sanity with zero-stripe"
19259
19260 test_225b () {
19261         if [ -z ${MDSSURVEY} ]; then
19262                 skip_env "mds-survey not found"
19263         fi
19264         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19265                 skip "Need MDS version at least 2.2.51"
19266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19267         remote_mds_nodsh && skip "remote MDS with nodsh"
19268         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19269                 skip_env "Need to mount OST to test"
19270         fi
19271
19272         local mds=$(facet_host $SINGLEMDS)
19273         local target=$(do_nodes $mds 'lctl dl' |
19274                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19275
19276         local cmd1="file_count=1000 thrhi=4"
19277         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19278         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19279         local cmd="$cmd1 $cmd2 $cmd3"
19280
19281         rm -f ${TMP}/mds_survey*
19282         echo + $cmd
19283         eval $cmd || error "mds-survey with stripe_count failed"
19284         cat ${TMP}/mds_survey*
19285         rm -f ${TMP}/mds_survey*
19286 }
19287 run_test 225b "Metadata survey sanity with stripe_count = 1"
19288
19289 mcreate_path2fid () {
19290         local mode=$1
19291         local major=$2
19292         local minor=$3
19293         local name=$4
19294         local desc=$5
19295         local path=$DIR/$tdir/$name
19296         local fid
19297         local rc
19298         local fid_path
19299
19300         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19301                 error "cannot create $desc"
19302
19303         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19304         rc=$?
19305         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19306
19307         fid_path=$($LFS fid2path $MOUNT $fid)
19308         rc=$?
19309         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19310
19311         [ "$path" == "$fid_path" ] ||
19312                 error "fid2path returned $fid_path, expected $path"
19313
19314         echo "pass with $path and $fid"
19315 }
19316
19317 test_226a () {
19318         rm -rf $DIR/$tdir
19319         mkdir -p $DIR/$tdir
19320
19321         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19322         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19323         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19324         mcreate_path2fid 0040666 0 0 dir "directory"
19325         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19326         mcreate_path2fid 0100666 0 0 file "regular file"
19327         mcreate_path2fid 0120666 0 0 link "symbolic link"
19328         mcreate_path2fid 0140666 0 0 sock "socket"
19329 }
19330 run_test 226a "call path2fid and fid2path on files of all type"
19331
19332 test_226b () {
19333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19334
19335         local MDTIDX=1
19336
19337         rm -rf $DIR/$tdir
19338         mkdir -p $DIR/$tdir
19339         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19340                 error "create remote directory failed"
19341         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19342         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19343                                 "character special file (null)"
19344         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19345                                 "character special file (no device)"
19346         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19347         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19348                                 "block special file (loop)"
19349         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19350         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19351         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19352 }
19353 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19354
19355 test_226c () {
19356         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19357         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19358                 skip "Need MDS version at least 2.13.55"
19359
19360         local submnt=/mnt/submnt
19361         local srcfile=/etc/passwd
19362         local dstfile=$submnt/passwd
19363         local path
19364         local fid
19365
19366         rm -rf $DIR/$tdir
19367         rm -rf $submnt
19368         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19369                 error "create remote directory failed"
19370         mkdir -p $submnt || error "create $submnt failed"
19371         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19372                 error "mount $submnt failed"
19373         stack_trap "umount $submnt" EXIT
19374
19375         cp $srcfile $dstfile
19376         fid=$($LFS path2fid $dstfile)
19377         path=$($LFS fid2path $submnt "$fid")
19378         [ "$path" = "$dstfile" ] ||
19379                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19380 }
19381 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19382
19383 # LU-1299 Executing or running ldd on a truncated executable does not
19384 # cause an out-of-memory condition.
19385 test_227() {
19386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19387         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19388
19389         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19390         chmod +x $MOUNT/date
19391
19392         $MOUNT/date > /dev/null
19393         ldd $MOUNT/date > /dev/null
19394         rm -f $MOUNT/date
19395 }
19396 run_test 227 "running truncated executable does not cause OOM"
19397
19398 # LU-1512 try to reuse idle OI blocks
19399 test_228a() {
19400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19401         remote_mds_nodsh && skip "remote MDS with nodsh"
19402         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19403
19404         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19405         local myDIR=$DIR/$tdir
19406
19407         mkdir -p $myDIR
19408         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19409         $LCTL set_param fail_loc=0x80001002
19410         createmany -o $myDIR/t- 10000
19411         $LCTL set_param fail_loc=0
19412         # The guard is current the largest FID holder
19413         touch $myDIR/guard
19414         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19415                     tr -d '[')
19416         local IDX=$(($SEQ % 64))
19417
19418         do_facet $SINGLEMDS sync
19419         # Make sure journal flushed.
19420         sleep 6
19421         local blk1=$(do_facet $SINGLEMDS \
19422                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19423                      grep Blockcount | awk '{print $4}')
19424
19425         # Remove old files, some OI blocks will become idle.
19426         unlinkmany $myDIR/t- 10000
19427         # Create new files, idle OI blocks should be reused.
19428         createmany -o $myDIR/t- 2000
19429         do_facet $SINGLEMDS sync
19430         # Make sure journal flushed.
19431         sleep 6
19432         local blk2=$(do_facet $SINGLEMDS \
19433                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19434                      grep Blockcount | awk '{print $4}')
19435
19436         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19437 }
19438 run_test 228a "try to reuse idle OI blocks"
19439
19440 test_228b() {
19441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19442         remote_mds_nodsh && skip "remote MDS with nodsh"
19443         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19444
19445         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19446         local myDIR=$DIR/$tdir
19447
19448         mkdir -p $myDIR
19449         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19450         $LCTL set_param fail_loc=0x80001002
19451         createmany -o $myDIR/t- 10000
19452         $LCTL set_param fail_loc=0
19453         # The guard is current the largest FID holder
19454         touch $myDIR/guard
19455         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19456                     tr -d '[')
19457         local IDX=$(($SEQ % 64))
19458
19459         do_facet $SINGLEMDS sync
19460         # Make sure journal flushed.
19461         sleep 6
19462         local blk1=$(do_facet $SINGLEMDS \
19463                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19464                      grep Blockcount | awk '{print $4}')
19465
19466         # Remove old files, some OI blocks will become idle.
19467         unlinkmany $myDIR/t- 10000
19468
19469         # stop the MDT
19470         stop $SINGLEMDS || error "Fail to stop MDT."
19471         # remount the MDT
19472         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19473                 error "Fail to start MDT."
19474
19475         df $MOUNT || error "Fail to df."
19476         # Create new files, idle OI blocks should be reused.
19477         createmany -o $myDIR/t- 2000
19478         do_facet $SINGLEMDS sync
19479         # Make sure journal flushed.
19480         sleep 6
19481         local blk2=$(do_facet $SINGLEMDS \
19482                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19483                      grep Blockcount | awk '{print $4}')
19484
19485         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19486 }
19487 run_test 228b "idle OI blocks can be reused after MDT restart"
19488
19489 #LU-1881
19490 test_228c() {
19491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19492         remote_mds_nodsh && skip "remote MDS with nodsh"
19493         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19494
19495         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19496         local myDIR=$DIR/$tdir
19497
19498         mkdir -p $myDIR
19499         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19500         $LCTL set_param fail_loc=0x80001002
19501         # 20000 files can guarantee there are index nodes in the OI file
19502         createmany -o $myDIR/t- 20000
19503         $LCTL set_param fail_loc=0
19504         # The guard is current the largest FID holder
19505         touch $myDIR/guard
19506         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19507                     tr -d '[')
19508         local IDX=$(($SEQ % 64))
19509
19510         do_facet $SINGLEMDS sync
19511         # Make sure journal flushed.
19512         sleep 6
19513         local blk1=$(do_facet $SINGLEMDS \
19514                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19515                      grep Blockcount | awk '{print $4}')
19516
19517         # Remove old files, some OI blocks will become idle.
19518         unlinkmany $myDIR/t- 20000
19519         rm -f $myDIR/guard
19520         # The OI file should become empty now
19521
19522         # Create new files, idle OI blocks should be reused.
19523         createmany -o $myDIR/t- 2000
19524         do_facet $SINGLEMDS sync
19525         # Make sure journal flushed.
19526         sleep 6
19527         local blk2=$(do_facet $SINGLEMDS \
19528                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19529                      grep Blockcount | awk '{print $4}')
19530
19531         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19532 }
19533 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19534
19535 test_229() { # LU-2482, LU-3448
19536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19537         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19538         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19539                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19540
19541         rm -f $DIR/$tfile
19542
19543         # Create a file with a released layout and stripe count 2.
19544         $MULTIOP $DIR/$tfile H2c ||
19545                 error "failed to create file with released layout"
19546
19547         $LFS getstripe -v $DIR/$tfile
19548
19549         local pattern=$($LFS getstripe -L $DIR/$tfile)
19550         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19551
19552         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19553                 error "getstripe"
19554         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19555         stat $DIR/$tfile || error "failed to stat released file"
19556
19557         chown $RUNAS_ID $DIR/$tfile ||
19558                 error "chown $RUNAS_ID $DIR/$tfile failed"
19559
19560         chgrp $RUNAS_ID $DIR/$tfile ||
19561                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19562
19563         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19564         rm $DIR/$tfile || error "failed to remove released file"
19565 }
19566 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19567
19568 test_230a() {
19569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19570         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19571         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19572                 skip "Need MDS version at least 2.11.52"
19573
19574         local MDTIDX=1
19575
19576         test_mkdir $DIR/$tdir
19577         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19578         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19579         [ $mdt_idx -ne 0 ] &&
19580                 error "create local directory on wrong MDT $mdt_idx"
19581
19582         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19583                         error "create remote directory failed"
19584         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19585         [ $mdt_idx -ne $MDTIDX ] &&
19586                 error "create remote directory on wrong MDT $mdt_idx"
19587
19588         createmany -o $DIR/$tdir/test_230/t- 10 ||
19589                 error "create files on remote directory failed"
19590         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19591         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19592         rm -r $DIR/$tdir || error "unlink remote directory failed"
19593 }
19594 run_test 230a "Create remote directory and files under the remote directory"
19595
19596 test_230b() {
19597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19598         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19599         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19600                 skip "Need MDS version at least 2.11.52"
19601
19602         local MDTIDX=1
19603         local mdt_index
19604         local i
19605         local file
19606         local pid
19607         local stripe_count
19608         local migrate_dir=$DIR/$tdir/migrate_dir
19609         local other_dir=$DIR/$tdir/other_dir
19610
19611         test_mkdir $DIR/$tdir
19612         test_mkdir -i0 -c1 $migrate_dir
19613         test_mkdir -i0 -c1 $other_dir
19614         for ((i=0; i<10; i++)); do
19615                 mkdir -p $migrate_dir/dir_${i}
19616                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19617                         error "create files under remote dir failed $i"
19618         done
19619
19620         cp /etc/passwd $migrate_dir/$tfile
19621         cp /etc/passwd $other_dir/$tfile
19622         chattr +SAD $migrate_dir
19623         chattr +SAD $migrate_dir/$tfile
19624
19625         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19626         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19627         local old_dir_mode=$(stat -c%f $migrate_dir)
19628         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19629
19630         mkdir -p $migrate_dir/dir_default_stripe2
19631         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19632         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19633
19634         mkdir -p $other_dir
19635         ln $migrate_dir/$tfile $other_dir/luna
19636         ln $migrate_dir/$tfile $migrate_dir/sofia
19637         ln $other_dir/$tfile $migrate_dir/david
19638         ln -s $migrate_dir/$tfile $other_dir/zachary
19639         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19640         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19641
19642         local len
19643         local lnktgt
19644
19645         # inline symlink
19646         for len in 58 59 60; do
19647                 lnktgt=$(str_repeat 'l' $len)
19648                 touch $migrate_dir/$lnktgt
19649                 ln -s $lnktgt $migrate_dir/${len}char_ln
19650         done
19651
19652         # PATH_MAX
19653         for len in 4094 4095; do
19654                 lnktgt=$(str_repeat 'l' $len)
19655                 ln -s $lnktgt $migrate_dir/${len}char_ln
19656         done
19657
19658         # NAME_MAX
19659         for len in 254 255; do
19660                 touch $migrate_dir/$(str_repeat 'l' $len)
19661         done
19662
19663         $LFS migrate -m $MDTIDX $migrate_dir ||
19664                 error "fails on migrating remote dir to MDT1"
19665
19666         echo "migratate to MDT1, then checking.."
19667         for ((i = 0; i < 10; i++)); do
19668                 for file in $(find $migrate_dir/dir_${i}); do
19669                         mdt_index=$($LFS getstripe -m $file)
19670                         # broken symlink getstripe will fail
19671                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19672                                 error "$file is not on MDT${MDTIDX}"
19673                 done
19674         done
19675
19676         # the multiple link file should still in MDT0
19677         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19678         [ $mdt_index == 0 ] ||
19679                 error "$file is not on MDT${MDTIDX}"
19680
19681         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19682         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19683                 error " expect $old_dir_flag get $new_dir_flag"
19684
19685         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19686         [ "$old_file_flag" = "$new_file_flag" ] ||
19687                 error " expect $old_file_flag get $new_file_flag"
19688
19689         local new_dir_mode=$(stat -c%f $migrate_dir)
19690         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19691                 error "expect mode $old_dir_mode get $new_dir_mode"
19692
19693         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19694         [ "$old_file_mode" = "$new_file_mode" ] ||
19695                 error "expect mode $old_file_mode get $new_file_mode"
19696
19697         diff /etc/passwd $migrate_dir/$tfile ||
19698                 error "$tfile different after migration"
19699
19700         diff /etc/passwd $other_dir/luna ||
19701                 error "luna different after migration"
19702
19703         diff /etc/passwd $migrate_dir/sofia ||
19704                 error "sofia different after migration"
19705
19706         diff /etc/passwd $migrate_dir/david ||
19707                 error "david different after migration"
19708
19709         diff /etc/passwd $other_dir/zachary ||
19710                 error "zachary different after migration"
19711
19712         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19713                 error "${tfile}_ln different after migration"
19714
19715         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19716                 error "${tfile}_ln_other different after migration"
19717
19718         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19719         [ $stripe_count = 2 ] ||
19720                 error "dir strpe_count $d != 2 after migration."
19721
19722         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19723         [ $stripe_count = 2 ] ||
19724                 error "file strpe_count $d != 2 after migration."
19725
19726         #migrate back to MDT0
19727         MDTIDX=0
19728
19729         $LFS migrate -m $MDTIDX $migrate_dir ||
19730                 error "fails on migrating remote dir to MDT0"
19731
19732         echo "migrate back to MDT0, checking.."
19733         for file in $(find $migrate_dir); do
19734                 mdt_index=$($LFS getstripe -m $file)
19735                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19736                         error "$file is not on MDT${MDTIDX}"
19737         done
19738
19739         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19740         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19741                 error " expect $old_dir_flag get $new_dir_flag"
19742
19743         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19744         [ "$old_file_flag" = "$new_file_flag" ] ||
19745                 error " expect $old_file_flag get $new_file_flag"
19746
19747         local new_dir_mode=$(stat -c%f $migrate_dir)
19748         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19749                 error "expect mode $old_dir_mode get $new_dir_mode"
19750
19751         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19752         [ "$old_file_mode" = "$new_file_mode" ] ||
19753                 error "expect mode $old_file_mode get $new_file_mode"
19754
19755         diff /etc/passwd ${migrate_dir}/$tfile ||
19756                 error "$tfile different after migration"
19757
19758         diff /etc/passwd ${other_dir}/luna ||
19759                 error "luna different after migration"
19760
19761         diff /etc/passwd ${migrate_dir}/sofia ||
19762                 error "sofia different after migration"
19763
19764         diff /etc/passwd ${other_dir}/zachary ||
19765                 error "zachary different after migration"
19766
19767         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19768                 error "${tfile}_ln different after migration"
19769
19770         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19771                 error "${tfile}_ln_other different after migration"
19772
19773         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19774         [ $stripe_count = 2 ] ||
19775                 error "dir strpe_count $d != 2 after migration."
19776
19777         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19778         [ $stripe_count = 2 ] ||
19779                 error "file strpe_count $d != 2 after migration."
19780
19781         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19782 }
19783 run_test 230b "migrate directory"
19784
19785 test_230c() {
19786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19787         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19788         remote_mds_nodsh && skip "remote MDS with nodsh"
19789         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19790                 skip "Need MDS version at least 2.11.52"
19791
19792         local MDTIDX=1
19793         local total=3
19794         local mdt_index
19795         local file
19796         local migrate_dir=$DIR/$tdir/migrate_dir
19797
19798         #If migrating directory fails in the middle, all entries of
19799         #the directory is still accessiable.
19800         test_mkdir $DIR/$tdir
19801         test_mkdir -i0 -c1 $migrate_dir
19802         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19803         stat $migrate_dir
19804         createmany -o $migrate_dir/f $total ||
19805                 error "create files under ${migrate_dir} failed"
19806
19807         # fail after migrating top dir, and this will fail only once, so the
19808         # first sub file migration will fail (currently f3), others succeed.
19809         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19810         do_facet mds1 lctl set_param fail_loc=0x1801
19811         local t=$(ls $migrate_dir | wc -l)
19812         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19813                 error "migrate should fail"
19814         local u=$(ls $migrate_dir | wc -l)
19815         [ "$u" == "$t" ] || error "$u != $t during migration"
19816
19817         # add new dir/file should succeed
19818         mkdir $migrate_dir/dir ||
19819                 error "mkdir failed under migrating directory"
19820         touch $migrate_dir/file ||
19821                 error "create file failed under migrating directory"
19822
19823         # add file with existing name should fail
19824         for file in $migrate_dir/f*; do
19825                 stat $file > /dev/null || error "stat $file failed"
19826                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19827                         error "open(O_CREAT|O_EXCL) $file should fail"
19828                 $MULTIOP $file m && error "create $file should fail"
19829                 touch $DIR/$tdir/remote_dir/$tfile ||
19830                         error "touch $tfile failed"
19831                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19832                         error "link $file should fail"
19833                 mdt_index=$($LFS getstripe -m $file)
19834                 if [ $mdt_index == 0 ]; then
19835                         # file failed to migrate is not allowed to rename to
19836                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19837                                 error "rename to $file should fail"
19838                 else
19839                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19840                                 error "rename to $file failed"
19841                 fi
19842                 echo hello >> $file || error "write $file failed"
19843         done
19844
19845         # resume migration with different options should fail
19846         $LFS migrate -m 0 $migrate_dir &&
19847                 error "migrate -m 0 $migrate_dir should fail"
19848
19849         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19850                 error "migrate -c 2 $migrate_dir should fail"
19851
19852         # resume migration should succeed
19853         $LFS migrate -m $MDTIDX $migrate_dir ||
19854                 error "migrate $migrate_dir failed"
19855
19856         echo "Finish migration, then checking.."
19857         for file in $(find $migrate_dir); do
19858                 mdt_index=$($LFS getstripe -m $file)
19859                 [ $mdt_index == $MDTIDX ] ||
19860                         error "$file is not on MDT${MDTIDX}"
19861         done
19862
19863         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19864 }
19865 run_test 230c "check directory accessiblity if migration failed"
19866
19867 test_230d() {
19868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19869         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19870         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19871                 skip "Need MDS version at least 2.11.52"
19872         # LU-11235
19873         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19874
19875         local migrate_dir=$DIR/$tdir/migrate_dir
19876         local old_index
19877         local new_index
19878         local old_count
19879         local new_count
19880         local new_hash
19881         local mdt_index
19882         local i
19883         local j
19884
19885         old_index=$((RANDOM % MDSCOUNT))
19886         old_count=$((MDSCOUNT - old_index))
19887         new_index=$((RANDOM % MDSCOUNT))
19888         new_count=$((MDSCOUNT - new_index))
19889         new_hash=1 # for all_char
19890
19891         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19892         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19893
19894         test_mkdir $DIR/$tdir
19895         test_mkdir -i $old_index -c $old_count $migrate_dir
19896
19897         for ((i=0; i<100; i++)); do
19898                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19899                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19900                         error "create files under remote dir failed $i"
19901         done
19902
19903         echo -n "Migrate from MDT$old_index "
19904         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19905         echo -n "to MDT$new_index"
19906         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19907         echo
19908
19909         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19910         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19911                 error "migrate remote dir error"
19912
19913         echo "Finish migration, then checking.."
19914         for file in $(find $migrate_dir -maxdepth 1); do
19915                 mdt_index=$($LFS getstripe -m $file)
19916                 if [ $mdt_index -lt $new_index ] ||
19917                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19918                         error "$file is on MDT$mdt_index"
19919                 fi
19920         done
19921
19922         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19923 }
19924 run_test 230d "check migrate big directory"
19925
19926 test_230e() {
19927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19928         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19929         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19930                 skip "Need MDS version at least 2.11.52"
19931
19932         local i
19933         local j
19934         local a_fid
19935         local b_fid
19936
19937         mkdir_on_mdt0 $DIR/$tdir
19938         mkdir $DIR/$tdir/migrate_dir
19939         mkdir $DIR/$tdir/other_dir
19940         touch $DIR/$tdir/migrate_dir/a
19941         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19942         ls $DIR/$tdir/other_dir
19943
19944         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19945                 error "migrate dir fails"
19946
19947         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19948         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19949
19950         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19951         [ $mdt_index == 0 ] || error "a is not on MDT0"
19952
19953         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19954                 error "migrate dir fails"
19955
19956         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19957         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19958
19959         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19960         [ $mdt_index == 1 ] || error "a is not on MDT1"
19961
19962         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19963         [ $mdt_index == 1 ] || error "b is not on MDT1"
19964
19965         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19966         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19967
19968         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19969
19970         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19971 }
19972 run_test 230e "migrate mulitple local link files"
19973
19974 test_230f() {
19975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19976         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19977         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19978                 skip "Need MDS version at least 2.11.52"
19979
19980         local a_fid
19981         local ln_fid
19982
19983         mkdir -p $DIR/$tdir
19984         mkdir $DIR/$tdir/migrate_dir
19985         $LFS mkdir -i1 $DIR/$tdir/other_dir
19986         touch $DIR/$tdir/migrate_dir/a
19987         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19988         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19989         ls $DIR/$tdir/other_dir
19990
19991         # a should be migrated to MDT1, since no other links on MDT0
19992         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19993                 error "#1 migrate dir fails"
19994         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19995         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19996         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19997         [ $mdt_index == 1 ] || error "a is not on MDT1"
19998
19999         # a should stay on MDT1, because it is a mulitple link file
20000         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20001                 error "#2 migrate dir fails"
20002         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20003         [ $mdt_index == 1 ] || error "a is not on MDT1"
20004
20005         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20006                 error "#3 migrate dir fails"
20007
20008         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20009         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20010         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20011
20012         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20013         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20014
20015         # a should be migrated to MDT0, since no other links on MDT1
20016         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20017                 error "#4 migrate dir fails"
20018         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20019         [ $mdt_index == 0 ] || error "a is not on MDT0"
20020
20021         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20022 }
20023 run_test 230f "migrate mulitple remote link files"
20024
20025 test_230g() {
20026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20027         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20028         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20029                 skip "Need MDS version at least 2.11.52"
20030
20031         mkdir -p $DIR/$tdir/migrate_dir
20032
20033         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20034                 error "migrating dir to non-exist MDT succeeds"
20035         true
20036 }
20037 run_test 230g "migrate dir to non-exist MDT"
20038
20039 test_230h() {
20040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20041         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20042         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20043                 skip "Need MDS version at least 2.11.52"
20044
20045         local mdt_index
20046
20047         mkdir -p $DIR/$tdir/migrate_dir
20048
20049         $LFS migrate -m1 $DIR &&
20050                 error "migrating mountpoint1 should fail"
20051
20052         $LFS migrate -m1 $DIR/$tdir/.. &&
20053                 error "migrating mountpoint2 should fail"
20054
20055         # same as mv
20056         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20057                 error "migrating $tdir/migrate_dir/.. should fail"
20058
20059         true
20060 }
20061 run_test 230h "migrate .. and root"
20062
20063 test_230i() {
20064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20065         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20066         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20067                 skip "Need MDS version at least 2.11.52"
20068
20069         mkdir -p $DIR/$tdir/migrate_dir
20070
20071         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20072                 error "migration fails with a tailing slash"
20073
20074         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20075                 error "migration fails with two tailing slashes"
20076 }
20077 run_test 230i "lfs migrate -m tolerates trailing slashes"
20078
20079 test_230j() {
20080         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20081         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20082                 skip "Need MDS version at least 2.11.52"
20083
20084         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20085         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20086                 error "create $tfile failed"
20087         cat /etc/passwd > $DIR/$tdir/$tfile
20088
20089         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20090
20091         cmp /etc/passwd $DIR/$tdir/$tfile ||
20092                 error "DoM file mismatch after migration"
20093 }
20094 run_test 230j "DoM file data not changed after dir migration"
20095
20096 test_230k() {
20097         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20098         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20099                 skip "Need MDS version at least 2.11.56"
20100
20101         local total=20
20102         local files_on_starting_mdt=0
20103
20104         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20105         $LFS getdirstripe $DIR/$tdir
20106         for i in $(seq $total); do
20107                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20108                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20109                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20110         done
20111
20112         echo "$files_on_starting_mdt files on MDT0"
20113
20114         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20115         $LFS getdirstripe $DIR/$tdir
20116
20117         files_on_starting_mdt=0
20118         for i in $(seq $total); do
20119                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20120                         error "file $tfile.$i mismatch after migration"
20121                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20122                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20123         done
20124
20125         echo "$files_on_starting_mdt files on MDT1 after migration"
20126         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20127
20128         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20129         $LFS getdirstripe $DIR/$tdir
20130
20131         files_on_starting_mdt=0
20132         for i in $(seq $total); do
20133                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20134                         error "file $tfile.$i mismatch after 2nd migration"
20135                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20136                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20137         done
20138
20139         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20140         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20141
20142         true
20143 }
20144 run_test 230k "file data not changed after dir migration"
20145
20146 test_230l() {
20147         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20148         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20149                 skip "Need MDS version at least 2.11.56"
20150
20151         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20152         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20153                 error "create files under remote dir failed $i"
20154         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20155 }
20156 run_test 230l "readdir between MDTs won't crash"
20157
20158 test_230m() {
20159         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20160         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20161                 skip "Need MDS version at least 2.11.56"
20162
20163         local MDTIDX=1
20164         local mig_dir=$DIR/$tdir/migrate_dir
20165         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20166         local shortstr="b"
20167         local val
20168
20169         echo "Creating files and dirs with xattrs"
20170         test_mkdir $DIR/$tdir
20171         test_mkdir -i0 -c1 $mig_dir
20172         mkdir $mig_dir/dir
20173         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20174                 error "cannot set xattr attr1 on dir"
20175         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20176                 error "cannot set xattr attr2 on dir"
20177         touch $mig_dir/dir/f0
20178         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20179                 error "cannot set xattr attr1 on file"
20180         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20181                 error "cannot set xattr attr2 on file"
20182         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20183         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20184         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20185         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20186         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20187         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20188         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20189         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20190         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20191
20192         echo "Migrating to MDT1"
20193         $LFS migrate -m $MDTIDX $mig_dir ||
20194                 error "fails on migrating dir to MDT1"
20195
20196         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20197         echo "Checking xattrs"
20198         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20199         [ "$val" = $longstr ] ||
20200                 error "expecting xattr1 $longstr on dir, found $val"
20201         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20202         [ "$val" = $shortstr ] ||
20203                 error "expecting xattr2 $shortstr on dir, found $val"
20204         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20205         [ "$val" = $longstr ] ||
20206                 error "expecting xattr1 $longstr on file, found $val"
20207         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20208         [ "$val" = $shortstr ] ||
20209                 error "expecting xattr2 $shortstr on file, found $val"
20210 }
20211 run_test 230m "xattrs not changed after dir migration"
20212
20213 test_230n() {
20214         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20215         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20216                 skip "Need MDS version at least 2.13.53"
20217
20218         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20219         cat /etc/hosts > $DIR/$tdir/$tfile
20220         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20221         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20222
20223         cmp /etc/hosts $DIR/$tdir/$tfile ||
20224                 error "File data mismatch after migration"
20225 }
20226 run_test 230n "Dir migration with mirrored file"
20227
20228 test_230o() {
20229         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20230         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20231                 skip "Need MDS version at least 2.13.52"
20232
20233         local mdts=$(comma_list $(mdts_nodes))
20234         local timeout=100
20235         local restripe_status
20236         local delta
20237         local i
20238
20239         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20240
20241         # in case "crush" hash type is not set
20242         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20243
20244         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20245                            mdt.*MDT0000.enable_dir_restripe)
20246         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20247         stack_trap "do_nodes $mdts $LCTL set_param \
20248                     mdt.*.enable_dir_restripe=$restripe_status"
20249
20250         mkdir $DIR/$tdir
20251         createmany -m $DIR/$tdir/f 100 ||
20252                 error "create files under remote dir failed $i"
20253         createmany -d $DIR/$tdir/d 100 ||
20254                 error "create dirs under remote dir failed $i"
20255
20256         for i in $(seq 2 $MDSCOUNT); do
20257                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20258                 $LFS setdirstripe -c $i $DIR/$tdir ||
20259                         error "split -c $i $tdir failed"
20260                 wait_update $HOSTNAME \
20261                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20262                         error "dir split not finished"
20263                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20264                         awk '/migrate/ {sum += $2} END { print sum }')
20265                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20266                 # delta is around total_files/stripe_count
20267                 (( $delta < 200 / (i - 1) + 4 )) ||
20268                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20269         done
20270 }
20271 run_test 230o "dir split"
20272
20273 test_230p() {
20274         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20275         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20276                 skip "Need MDS version at least 2.13.52"
20277
20278         local mdts=$(comma_list $(mdts_nodes))
20279         local timeout=100
20280         local restripe_status
20281         local delta
20282         local c
20283
20284         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20285
20286         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20287
20288         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20289                            mdt.*MDT0000.enable_dir_restripe)
20290         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20291         stack_trap "do_nodes $mdts $LCTL set_param \
20292                     mdt.*.enable_dir_restripe=$restripe_status"
20293
20294         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20295         createmany -m $DIR/$tdir/f 100 ||
20296                 error "create files under remote dir failed"
20297         createmany -d $DIR/$tdir/d 100 ||
20298                 error "create dirs under remote dir failed"
20299
20300         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20301                 local mdt_hash="crush"
20302
20303                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20304                 $LFS setdirstripe -c $c $DIR/$tdir ||
20305                         error "split -c $c $tdir failed"
20306                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20307                         mdt_hash="$mdt_hash,fixed"
20308                 elif [ $c -eq 1 ]; then
20309                         mdt_hash="none"
20310                 fi
20311                 wait_update $HOSTNAME \
20312                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20313                         error "dir merge not finished"
20314                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20315                         awk '/migrate/ {sum += $2} END { print sum }')
20316                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20317                 # delta is around total_files/stripe_count
20318                 (( delta < 200 / c + 4 )) ||
20319                         error "$delta files migrated >= $((200 / c + 4))"
20320         done
20321 }
20322 run_test 230p "dir merge"
20323
20324 test_230q() {
20325         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20326         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20327                 skip "Need MDS version at least 2.13.52"
20328
20329         local mdts=$(comma_list $(mdts_nodes))
20330         local saved_threshold=$(do_facet mds1 \
20331                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20332         local saved_delta=$(do_facet mds1 \
20333                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20334         local threshold=100
20335         local delta=2
20336         local total=0
20337         local stripe_count=0
20338         local stripe_index
20339         local nr_files
20340         local create
20341
20342         # test with fewer files on ZFS
20343         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20344
20345         stack_trap "do_nodes $mdts $LCTL set_param \
20346                     mdt.*.dir_split_count=$saved_threshold"
20347         stack_trap "do_nodes $mdts $LCTL set_param \
20348                     mdt.*.dir_split_delta=$saved_delta"
20349         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20350         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20351         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20352         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20353         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20354         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20355
20356         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20357         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20358
20359         create=$((threshold * 3 / 2))
20360         while [ $stripe_count -lt $MDSCOUNT ]; do
20361                 createmany -m $DIR/$tdir/f $total $create ||
20362                         error "create sub files failed"
20363                 stat $DIR/$tdir > /dev/null
20364                 total=$((total + create))
20365                 stripe_count=$((stripe_count + delta))
20366                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20367
20368                 wait_update $HOSTNAME \
20369                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20370                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20371
20372                 wait_update $HOSTNAME \
20373                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20374                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20375
20376                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20377                 echo "$nr_files/$total files on MDT$stripe_index after split"
20378                 # allow 10% margin of imbalance with crush hash
20379                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20380                         error "$nr_files files on MDT$stripe_index after split"
20381
20382                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20383                 [ $nr_files -eq $total ] ||
20384                         error "total sub files $nr_files != $total"
20385         done
20386
20387         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20388
20389         echo "fixed layout directory won't auto split"
20390         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20391         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20392                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20393         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20394                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20395 }
20396 run_test 230q "dir auto split"
20397
20398 test_230r() {
20399         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20400         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20401         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20402                 skip "Need MDS version at least 2.13.54"
20403
20404         # maximum amount of local locks:
20405         # parent striped dir - 2 locks
20406         # new stripe in parent to migrate to - 1 lock
20407         # source and target - 2 locks
20408         # Total 5 locks for regular file
20409         mkdir -p $DIR/$tdir
20410         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20411         touch $DIR/$tdir/dir1/eee
20412
20413         # create 4 hardlink for 4 more locks
20414         # Total: 9 locks > RS_MAX_LOCKS (8)
20415         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20416         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20417         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20418         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20419         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20420         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20421         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20422         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20423
20424         cancel_lru_locks mdc
20425
20426         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20427                 error "migrate dir fails"
20428
20429         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20430 }
20431 run_test 230r "migrate with too many local locks"
20432
20433 test_230s() {
20434         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
20435                 skip "Need MDS version at least 2.13.57"
20436
20437         local mdts=$(comma_list $(mdts_nodes))
20438         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20439                                 mdt.*MDT0000.enable_dir_restripe)
20440
20441         stack_trap "do_nodes $mdts $LCTL set_param \
20442                     mdt.*.enable_dir_restripe=$restripe_status"
20443
20444         local st
20445         for st in 0 1; do
20446                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20447                 test_mkdir $DIR/$tdir
20448                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20449                         error "$LFS mkdir doesn't return -EEXIST if target exists"
20450                 rmdir $DIR/$tdir
20451         done
20452 }
20453 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20454
20455 test_230t()
20456 {
20457         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20458         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20459                 skip "Need MDS version at least 2.14.50"
20460
20461         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20462         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20463         $LFS project -p 1 -s $DIR/$tdir ||
20464                 error "set $tdir project id failed"
20465         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20466                 error "set subdir project id failed"
20467         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20468 }
20469 run_test 230t "migrate directory with project ID set"
20470
20471 test_230u()
20472 {
20473         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20474         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20475                 skip "Need MDS version at least 2.14.53"
20476
20477         local count
20478
20479         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20480         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20481         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20482         for i in $(seq 0 $((MDSCOUNT - 1))); do
20483                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20484                 echo "$count dirs migrated to MDT$i"
20485         done
20486         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20487         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20488 }
20489 run_test 230u "migrate directory by QOS"
20490
20491 test_230v()
20492 {
20493         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20494         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20495                 skip "Need MDS version at least 2.14.53"
20496
20497         local count
20498
20499         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20500         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20501         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20502         for i in $(seq 0 $((MDSCOUNT - 1))); do
20503                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20504                 echo "$count subdirs migrated to MDT$i"
20505                 (( i == 3 )) && (( count > 0 )) &&
20506                         error "subdir shouldn't be migrated to MDT3"
20507         done
20508         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20509         (( count == 3 )) || error "dirs migrated to $count MDTs"
20510 }
20511 run_test 230v "subdir migrated to the MDT where its parent is located"
20512
20513 test_230w() {
20514         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20515         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20516                 skip "Need MDS version at least 2.14.53"
20517
20518         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20519
20520         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20521                 error "migrate failed"
20522
20523         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20524                 error "$tdir stripe count mismatch"
20525
20526         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20527                 error "$tdir/sub is striped"
20528 }
20529 run_test 230w "non-recursive mode dir migration"
20530
20531 test_231a()
20532 {
20533         # For simplicity this test assumes that max_pages_per_rpc
20534         # is the same across all OSCs
20535         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20536         local bulk_size=$((max_pages * PAGE_SIZE))
20537         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20538                                        head -n 1)
20539
20540         mkdir -p $DIR/$tdir
20541         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20542                 error "failed to set stripe with -S ${brw_size}M option"
20543
20544         # clear the OSC stats
20545         $LCTL set_param osc.*.stats=0 &>/dev/null
20546         stop_writeback
20547
20548         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20549         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20550                 oflag=direct &>/dev/null || error "dd failed"
20551
20552         sync; sleep 1; sync # just to be safe
20553         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20554         if [ x$nrpcs != "x1" ]; then
20555                 $LCTL get_param osc.*.stats
20556                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20557         fi
20558
20559         start_writeback
20560         # Drop the OSC cache, otherwise we will read from it
20561         cancel_lru_locks osc
20562
20563         # clear the OSC stats
20564         $LCTL set_param osc.*.stats=0 &>/dev/null
20565
20566         # Client reads $bulk_size.
20567         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20568                 iflag=direct &>/dev/null || error "dd failed"
20569
20570         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20571         if [ x$nrpcs != "x1" ]; then
20572                 $LCTL get_param osc.*.stats
20573                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20574         fi
20575 }
20576 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20577
20578 test_231b() {
20579         mkdir -p $DIR/$tdir
20580         local i
20581         for i in {0..1023}; do
20582                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20583                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20584                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20585         done
20586         sync
20587 }
20588 run_test 231b "must not assert on fully utilized OST request buffer"
20589
20590 test_232a() {
20591         mkdir -p $DIR/$tdir
20592         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20593
20594         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20595         do_facet ost1 $LCTL set_param fail_loc=0x31c
20596
20597         # ignore dd failure
20598         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20599
20600         do_facet ost1 $LCTL set_param fail_loc=0
20601         umount_client $MOUNT || error "umount failed"
20602         mount_client $MOUNT || error "mount failed"
20603         stop ost1 || error "cannot stop ost1"
20604         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20605 }
20606 run_test 232a "failed lock should not block umount"
20607
20608 test_232b() {
20609         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20610                 skip "Need MDS version at least 2.10.58"
20611
20612         mkdir -p $DIR/$tdir
20613         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20615         sync
20616         cancel_lru_locks osc
20617
20618         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20619         do_facet ost1 $LCTL set_param fail_loc=0x31c
20620
20621         # ignore failure
20622         $LFS data_version $DIR/$tdir/$tfile || true
20623
20624         do_facet ost1 $LCTL set_param fail_loc=0
20625         umount_client $MOUNT || error "umount failed"
20626         mount_client $MOUNT || error "mount failed"
20627         stop ost1 || error "cannot stop ost1"
20628         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20629 }
20630 run_test 232b "failed data version lock should not block umount"
20631
20632 test_233a() {
20633         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20634                 skip "Need MDS version at least 2.3.64"
20635         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20636
20637         local fid=$($LFS path2fid $MOUNT)
20638
20639         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20640                 error "cannot access $MOUNT using its FID '$fid'"
20641 }
20642 run_test 233a "checking that OBF of the FS root succeeds"
20643
20644 test_233b() {
20645         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20646                 skip "Need MDS version at least 2.5.90"
20647         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20648
20649         local fid=$($LFS path2fid $MOUNT/.lustre)
20650
20651         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20652                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20653
20654         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20655         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20656                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20657 }
20658 run_test 233b "checking that OBF of the FS .lustre succeeds"
20659
20660 test_234() {
20661         local p="$TMP/sanityN-$TESTNAME.parameters"
20662         save_lustre_params client "llite.*.xattr_cache" > $p
20663         lctl set_param llite.*.xattr_cache 1 ||
20664                 skip_env "xattr cache is not supported"
20665
20666         mkdir -p $DIR/$tdir || error "mkdir failed"
20667         touch $DIR/$tdir/$tfile || error "touch failed"
20668         # OBD_FAIL_LLITE_XATTR_ENOMEM
20669         $LCTL set_param fail_loc=0x1405
20670         getfattr -n user.attr $DIR/$tdir/$tfile &&
20671                 error "getfattr should have failed with ENOMEM"
20672         $LCTL set_param fail_loc=0x0
20673         rm -rf $DIR/$tdir
20674
20675         restore_lustre_params < $p
20676         rm -f $p
20677 }
20678 run_test 234 "xattr cache should not crash on ENOMEM"
20679
20680 test_235() {
20681         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20682                 skip "Need MDS version at least 2.4.52"
20683
20684         flock_deadlock $DIR/$tfile
20685         local RC=$?
20686         case $RC in
20687                 0)
20688                 ;;
20689                 124) error "process hangs on a deadlock"
20690                 ;;
20691                 *) error "error executing flock_deadlock $DIR/$tfile"
20692                 ;;
20693         esac
20694 }
20695 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20696
20697 #LU-2935
20698 test_236() {
20699         check_swap_layouts_support
20700
20701         local ref1=/etc/passwd
20702         local ref2=/etc/group
20703         local file1=$DIR/$tdir/f1
20704         local file2=$DIR/$tdir/f2
20705
20706         test_mkdir -c1 $DIR/$tdir
20707         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20708         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20709         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20710         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20711         local fd=$(free_fd)
20712         local cmd="exec $fd<>$file2"
20713         eval $cmd
20714         rm $file2
20715         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20716                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20717         cmd="exec $fd>&-"
20718         eval $cmd
20719         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20720
20721         #cleanup
20722         rm -rf $DIR/$tdir
20723 }
20724 run_test 236 "Layout swap on open unlinked file"
20725
20726 # LU-4659 linkea consistency
20727 test_238() {
20728         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20729                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20730                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20731                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20732
20733         touch $DIR/$tfile
20734         ln $DIR/$tfile $DIR/$tfile.lnk
20735         touch $DIR/$tfile.new
20736         mv $DIR/$tfile.new $DIR/$tfile
20737         local fid1=$($LFS path2fid $DIR/$tfile)
20738         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20739         local path1=$($LFS fid2path $FSNAME "$fid1")
20740         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20741         local path2=$($LFS fid2path $FSNAME "$fid2")
20742         [ $tfile.lnk == $path2 ] ||
20743                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20744         rm -f $DIR/$tfile*
20745 }
20746 run_test 238 "Verify linkea consistency"
20747
20748 test_239A() { # was test_239
20749         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20750                 skip "Need MDS version at least 2.5.60"
20751
20752         local list=$(comma_list $(mdts_nodes))
20753
20754         mkdir -p $DIR/$tdir
20755         createmany -o $DIR/$tdir/f- 5000
20756         unlinkmany $DIR/$tdir/f- 5000
20757         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20758                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20759         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20760                         osp.*MDT*.sync_in_flight" | calc_sum)
20761         [ "$changes" -eq 0 ] || error "$changes not synced"
20762 }
20763 run_test 239A "osp_sync test"
20764
20765 test_239a() { #LU-5297
20766         remote_mds_nodsh && skip "remote MDS with nodsh"
20767
20768         touch $DIR/$tfile
20769         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20770         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20771         chgrp $RUNAS_GID $DIR/$tfile
20772         wait_delete_completed
20773 }
20774 run_test 239a "process invalid osp sync record correctly"
20775
20776 test_239b() { #LU-5297
20777         remote_mds_nodsh && skip "remote MDS with nodsh"
20778
20779         touch $DIR/$tfile1
20780         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20781         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20782         chgrp $RUNAS_GID $DIR/$tfile1
20783         wait_delete_completed
20784         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20785         touch $DIR/$tfile2
20786         chgrp $RUNAS_GID $DIR/$tfile2
20787         wait_delete_completed
20788 }
20789 run_test 239b "process osp sync record with ENOMEM error correctly"
20790
20791 test_240() {
20792         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20793         remote_mds_nodsh && skip "remote MDS with nodsh"
20794
20795         mkdir -p $DIR/$tdir
20796
20797         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20798                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20799         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20800                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20801
20802         umount_client $MOUNT || error "umount failed"
20803         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20804         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20805         mount_client $MOUNT || error "failed to mount client"
20806
20807         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20808         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20809 }
20810 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20811
20812 test_241_bio() {
20813         local count=$1
20814         local bsize=$2
20815
20816         for LOOP in $(seq $count); do
20817                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20818                 cancel_lru_locks $OSC || true
20819         done
20820 }
20821
20822 test_241_dio() {
20823         local count=$1
20824         local bsize=$2
20825
20826         for LOOP in $(seq $1); do
20827                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20828                         2>/dev/null
20829         done
20830 }
20831
20832 test_241a() { # was test_241
20833         local bsize=$PAGE_SIZE
20834
20835         (( bsize < 40960 )) && bsize=40960
20836         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20837         ls -la $DIR/$tfile
20838         cancel_lru_locks $OSC
20839         test_241_bio 1000 $bsize &
20840         PID=$!
20841         test_241_dio 1000 $bsize
20842         wait $PID
20843 }
20844 run_test 241a "bio vs dio"
20845
20846 test_241b() {
20847         local bsize=$PAGE_SIZE
20848
20849         (( bsize < 40960 )) && bsize=40960
20850         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20851         ls -la $DIR/$tfile
20852         test_241_dio 1000 $bsize &
20853         PID=$!
20854         test_241_dio 1000 $bsize
20855         wait $PID
20856 }
20857 run_test 241b "dio vs dio"
20858
20859 test_242() {
20860         remote_mds_nodsh && skip "remote MDS with nodsh"
20861
20862         mkdir_on_mdt0 $DIR/$tdir
20863         touch $DIR/$tdir/$tfile
20864
20865         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20866         do_facet mds1 lctl set_param fail_loc=0x105
20867         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20868
20869         do_facet mds1 lctl set_param fail_loc=0
20870         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20871 }
20872 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20873
20874 test_243()
20875 {
20876         test_mkdir $DIR/$tdir
20877         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20878 }
20879 run_test 243 "various group lock tests"
20880
20881 test_244a()
20882 {
20883         test_mkdir $DIR/$tdir
20884         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20885         sendfile_grouplock $DIR/$tdir/$tfile || \
20886                 error "sendfile+grouplock failed"
20887         rm -rf $DIR/$tdir
20888 }
20889 run_test 244a "sendfile with group lock tests"
20890
20891 test_244b()
20892 {
20893         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20894
20895         local threads=50
20896         local size=$((1024*1024))
20897
20898         test_mkdir $DIR/$tdir
20899         for i in $(seq 1 $threads); do
20900                 local file=$DIR/$tdir/file_$((i / 10))
20901                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20902                 local pids[$i]=$!
20903         done
20904         for i in $(seq 1 $threads); do
20905                 wait ${pids[$i]}
20906         done
20907 }
20908 run_test 244b "multi-threaded write with group lock"
20909
20910 test_245() {
20911         local flagname="multi_mod_rpcs"
20912         local connect_data_name="max_mod_rpcs"
20913         local out
20914
20915         # check if multiple modify RPCs flag is set
20916         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20917                 grep "connect_flags:")
20918         echo "$out"
20919
20920         echo "$out" | grep -qw $flagname
20921         if [ $? -ne 0 ]; then
20922                 echo "connect flag $flagname is not set"
20923                 return
20924         fi
20925
20926         # check if multiple modify RPCs data is set
20927         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20928         echo "$out"
20929
20930         echo "$out" | grep -qw $connect_data_name ||
20931                 error "import should have connect data $connect_data_name"
20932 }
20933 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20934
20935 cleanup_247() {
20936         local submount=$1
20937
20938         trap 0
20939         umount_client $submount
20940         rmdir $submount
20941 }
20942
20943 test_247a() {
20944         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20945                 grep -q subtree ||
20946                 skip_env "Fileset feature is not supported"
20947
20948         local submount=${MOUNT}_$tdir
20949
20950         mkdir $MOUNT/$tdir
20951         mkdir -p $submount || error "mkdir $submount failed"
20952         FILESET="$FILESET/$tdir" mount_client $submount ||
20953                 error "mount $submount failed"
20954         trap "cleanup_247 $submount" EXIT
20955         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20956         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20957                 error "read $MOUNT/$tdir/$tfile failed"
20958         cleanup_247 $submount
20959 }
20960 run_test 247a "mount subdir as fileset"
20961
20962 test_247b() {
20963         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20964                 skip_env "Fileset feature is not supported"
20965
20966         local submount=${MOUNT}_$tdir
20967
20968         rm -rf $MOUNT/$tdir
20969         mkdir -p $submount || error "mkdir $submount failed"
20970         SKIP_FILESET=1
20971         FILESET="$FILESET/$tdir" mount_client $submount &&
20972                 error "mount $submount should fail"
20973         rmdir $submount
20974 }
20975 run_test 247b "mount subdir that dose not exist"
20976
20977 test_247c() {
20978         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20979                 skip_env "Fileset feature is not supported"
20980
20981         local submount=${MOUNT}_$tdir
20982
20983         mkdir -p $MOUNT/$tdir/dir1
20984         mkdir -p $submount || error "mkdir $submount failed"
20985         trap "cleanup_247 $submount" EXIT
20986         FILESET="$FILESET/$tdir" mount_client $submount ||
20987                 error "mount $submount failed"
20988         local fid=$($LFS path2fid $MOUNT/)
20989         $LFS fid2path $submount $fid && error "fid2path should fail"
20990         cleanup_247 $submount
20991 }
20992 run_test 247c "running fid2path outside subdirectory root"
20993
20994 test_247d() {
20995         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20996                 skip "Fileset feature is not supported"
20997
20998         local submount=${MOUNT}_$tdir
20999
21000         mkdir -p $MOUNT/$tdir/dir1
21001         mkdir -p $submount || error "mkdir $submount failed"
21002         FILESET="$FILESET/$tdir" mount_client $submount ||
21003                 error "mount $submount failed"
21004         trap "cleanup_247 $submount" EXIT
21005
21006         local td=$submount/dir1
21007         local fid=$($LFS path2fid $td)
21008         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21009
21010         # check that we get the same pathname back
21011         local rootpath
21012         local found
21013         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21014                 echo "$rootpath $fid"
21015                 found=$($LFS fid2path $rootpath "$fid")
21016                 [ -n "found" ] || error "fid2path should succeed"
21017                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21018         done
21019         # check wrong root path format
21020         rootpath=$submount"_wrong"
21021         found=$($LFS fid2path $rootpath "$fid")
21022         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21023
21024         cleanup_247 $submount
21025 }
21026 run_test 247d "running fid2path inside subdirectory root"
21027
21028 # LU-8037
21029 test_247e() {
21030         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21031                 grep -q subtree ||
21032                 skip "Fileset feature is not supported"
21033
21034         local submount=${MOUNT}_$tdir
21035
21036         mkdir $MOUNT/$tdir
21037         mkdir -p $submount || error "mkdir $submount failed"
21038         FILESET="$FILESET/.." mount_client $submount &&
21039                 error "mount $submount should fail"
21040         rmdir $submount
21041 }
21042 run_test 247e "mount .. as fileset"
21043
21044 test_247f() {
21045         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21046         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21047                 skip "Need at least version 2.13.52"
21048         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21049                 skip "Need at least version 2.14.50"
21050         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21051                 grep -q subtree ||
21052                 skip "Fileset feature is not supported"
21053
21054         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21055         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21056                 error "mkdir remote failed"
21057         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21058                 error "mkdir remote/subdir failed"
21059         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21060                 error "mkdir striped failed"
21061         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21062
21063         local submount=${MOUNT}_$tdir
21064
21065         mkdir -p $submount || error "mkdir $submount failed"
21066         stack_trap "rmdir $submount"
21067
21068         local dir
21069         local stat
21070         local fileset=$FILESET
21071         local mdts=$(comma_list $(mdts_nodes))
21072
21073         stat=$(do_facet mds1 $LCTL get_param -n \
21074                 mdt.*MDT0000.enable_remote_subdir_mount)
21075         stack_trap "do_nodes $mdts $LCTL set_param \
21076                 mdt.*.enable_remote_subdir_mount=$stat"
21077
21078         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21079         stack_trap "umount_client $submount"
21080         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21081                 error "mount remote dir $dir should fail"
21082
21083         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21084                 $tdir/striped/. ; do
21085                 FILESET="$fileset/$dir" mount_client $submount ||
21086                         error "mount $dir failed"
21087                 umount_client $submount
21088         done
21089
21090         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21091         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21092                 error "mount $tdir/remote failed"
21093 }
21094 run_test 247f "mount striped or remote directory as fileset"
21095
21096 test_247g() {
21097         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21098         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21099                 skip "Need at least version 2.14.50"
21100
21101         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21102                 error "mkdir $tdir failed"
21103         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21104
21105         local submount=${MOUNT}_$tdir
21106
21107         mkdir -p $submount || error "mkdir $submount failed"
21108         stack_trap "rmdir $submount"
21109
21110         FILESET="$fileset/$tdir" mount_client $submount ||
21111                 error "mount $dir failed"
21112         stack_trap "umount $submount"
21113
21114         local mdts=$(comma_list $(mdts_nodes))
21115
21116         local nrpcs
21117
21118         stat $submount > /dev/null
21119         cancel_lru_locks $MDC
21120         stat $submount > /dev/null
21121         stat $submount/$tfile > /dev/null
21122         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21123         stat $submount/$tfile > /dev/null
21124         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21125                 awk '/getattr/ {sum += $2} END {print sum}')
21126
21127         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21128 }
21129 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21130
21131 test_248a() {
21132         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21133         [ -z "$fast_read_sav" ] && skip "no fast read support"
21134
21135         # create a large file for fast read verification
21136         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21137
21138         # make sure the file is created correctly
21139         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21140                 { rm -f $DIR/$tfile; skip "file creation error"; }
21141
21142         echo "Test 1: verify that fast read is 4 times faster on cache read"
21143
21144         # small read with fast read enabled
21145         $LCTL set_param -n llite.*.fast_read=1
21146         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21147                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21148                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21149         # small read with fast read disabled
21150         $LCTL set_param -n llite.*.fast_read=0
21151         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21152                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21153                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21154
21155         # verify that fast read is 4 times faster for cache read
21156         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21157                 error_not_in_vm "fast read was not 4 times faster: " \
21158                            "$t_fast vs $t_slow"
21159
21160         echo "Test 2: verify the performance between big and small read"
21161         $LCTL set_param -n llite.*.fast_read=1
21162
21163         # 1k non-cache read
21164         cancel_lru_locks osc
21165         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21166                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21167                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21168
21169         # 1M non-cache read
21170         cancel_lru_locks osc
21171         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21172                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21173                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21174
21175         # verify that big IO is not 4 times faster than small IO
21176         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21177                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21178
21179         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21180         rm -f $DIR/$tfile
21181 }
21182 run_test 248a "fast read verification"
21183
21184 test_248b() {
21185         # Default short_io_bytes=16384, try both smaller and larger sizes.
21186         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21187         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21188         echo "bs=53248 count=113 normal buffered write"
21189         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21190                 error "dd of initial data file failed"
21191         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21192
21193         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21194         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21195                 error "dd with sync normal writes failed"
21196         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21197
21198         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21199         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21200                 error "dd with sync small writes failed"
21201         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21202
21203         cancel_lru_locks osc
21204
21205         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21206         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21207         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21208         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21209                 iflag=direct || error "dd with O_DIRECT small read failed"
21210         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21211         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21212                 error "compare $TMP/$tfile.1 failed"
21213
21214         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21215         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21216
21217         # just to see what the maximum tunable value is, and test parsing
21218         echo "test invalid parameter 2MB"
21219         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21220                 error "too-large short_io_bytes allowed"
21221         echo "test maximum parameter 512KB"
21222         # if we can set a larger short_io_bytes, run test regardless of version
21223         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21224                 # older clients may not allow setting it this large, that's OK
21225                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21226                         skip "Need at least client version 2.13.50"
21227                 error "medium short_io_bytes failed"
21228         fi
21229         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21230         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21231
21232         echo "test large parameter 64KB"
21233         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21234         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21235
21236         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21237         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21238                 error "dd with sync large writes failed"
21239         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21240
21241         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21242         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21243         num=$((113 * 4096 / PAGE_SIZE))
21244         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21245         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21246                 error "dd with O_DIRECT large writes failed"
21247         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21248                 error "compare $DIR/$tfile.3 failed"
21249
21250         cancel_lru_locks osc
21251
21252         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21253         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21254                 error "dd with O_DIRECT large read failed"
21255         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21256                 error "compare $TMP/$tfile.2 failed"
21257
21258         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21259         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21260                 error "dd with O_DIRECT large read failed"
21261         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21262                 error "compare $TMP/$tfile.3 failed"
21263 }
21264 run_test 248b "test short_io read and write for both small and large sizes"
21265
21266 test_249() { # LU-7890
21267         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21268                 skip "Need at least version 2.8.54"
21269
21270         rm -f $DIR/$tfile
21271         $LFS setstripe -c 1 $DIR/$tfile
21272         # Offset 2T == 4k * 512M
21273         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21274                 error "dd to 2T offset failed"
21275 }
21276 run_test 249 "Write above 2T file size"
21277
21278 test_250() {
21279         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21280          && skip "no 16TB file size limit on ZFS"
21281
21282         $LFS setstripe -c 1 $DIR/$tfile
21283         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21284         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21285         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21286         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21287                 conv=notrunc,fsync && error "append succeeded"
21288         return 0
21289 }
21290 run_test 250 "Write above 16T limit"
21291
21292 test_251() {
21293         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21294
21295         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21296         #Skip once - writing the first stripe will succeed
21297         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21298         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21299                 error "short write happened"
21300
21301         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21302         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21303                 error "short read happened"
21304
21305         rm -f $DIR/$tfile
21306 }
21307 run_test 251 "Handling short read and write correctly"
21308
21309 test_252() {
21310         remote_mds_nodsh && skip "remote MDS with nodsh"
21311         remote_ost_nodsh && skip "remote OST with nodsh"
21312         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21313                 skip_env "ldiskfs only test"
21314         fi
21315
21316         local tgt
21317         local dev
21318         local out
21319         local uuid
21320         local num
21321         local gen
21322
21323         # check lr_reader on OST0000
21324         tgt=ost1
21325         dev=$(facet_device $tgt)
21326         out=$(do_facet $tgt $LR_READER $dev)
21327         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21328         echo "$out"
21329         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21330         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21331                 error "Invalid uuid returned by $LR_READER on target $tgt"
21332         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21333
21334         # check lr_reader -c on MDT0000
21335         tgt=mds1
21336         dev=$(facet_device $tgt)
21337         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21338                 skip "$LR_READER does not support additional options"
21339         fi
21340         out=$(do_facet $tgt $LR_READER -c $dev)
21341         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21342         echo "$out"
21343         num=$(echo "$out" | grep -c "mdtlov")
21344         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21345                 error "Invalid number of mdtlov clients returned by $LR_READER"
21346         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21347
21348         # check lr_reader -cr on MDT0000
21349         out=$(do_facet $tgt $LR_READER -cr $dev)
21350         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21351         echo "$out"
21352         echo "$out" | grep -q "^reply_data:$" ||
21353                 error "$LR_READER should have returned 'reply_data' section"
21354         num=$(echo "$out" | grep -c "client_generation")
21355         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21356 }
21357 run_test 252 "check lr_reader tool"
21358
21359 test_253() {
21360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21361         remote_mds_nodsh && skip "remote MDS with nodsh"
21362         remote_mgs_nodsh && skip "remote MGS with nodsh"
21363
21364         local ostidx=0
21365         local rc=0
21366         local ost_name=$(ostname_from_index $ostidx)
21367
21368         # on the mdt's osc
21369         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21370         do_facet $SINGLEMDS $LCTL get_param -n \
21371                 osp.$mdtosc_proc1.reserved_mb_high ||
21372                 skip  "remote MDS does not support reserved_mb_high"
21373
21374         rm -rf $DIR/$tdir
21375         wait_mds_ost_sync
21376         wait_delete_completed
21377         mkdir $DIR/$tdir
21378
21379         pool_add $TESTNAME || error "Pool creation failed"
21380         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21381
21382         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21383                 error "Setstripe failed"
21384
21385         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21386
21387         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21388                     grep "watermarks")
21389         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21390
21391         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21392                         osp.$mdtosc_proc1.prealloc_status)
21393         echo "prealloc_status $oa_status"
21394
21395         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21396                 error "File creation should fail"
21397
21398         #object allocation was stopped, but we still able to append files
21399         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21400                 oflag=append || error "Append failed"
21401
21402         rm -f $DIR/$tdir/$tfile.0
21403
21404         # For this test, we want to delete the files we created to go out of
21405         # space but leave the watermark, so we remain nearly out of space
21406         ost_watermarks_enospc_delete_files $tfile $ostidx
21407
21408         wait_delete_completed
21409
21410         sleep_maxage
21411
21412         for i in $(seq 10 12); do
21413                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21414                         2>/dev/null || error "File creation failed after rm"
21415         done
21416
21417         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21418                         osp.$mdtosc_proc1.prealloc_status)
21419         echo "prealloc_status $oa_status"
21420
21421         if (( oa_status != 0 )); then
21422                 error "Object allocation still disable after rm"
21423         fi
21424 }
21425 run_test 253 "Check object allocation limit"
21426
21427 test_254() {
21428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21429         remote_mds_nodsh && skip "remote MDS with nodsh"
21430
21431         local mdt=$(facet_svc $SINGLEMDS)
21432
21433         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21434                 skip "MDS does not support changelog_size"
21435
21436         local cl_user
21437
21438         changelog_register || error "changelog_register failed"
21439
21440         changelog_clear 0 || error "changelog_clear failed"
21441
21442         local size1=$(do_facet $SINGLEMDS \
21443                       $LCTL get_param -n mdd.$mdt.changelog_size)
21444         echo "Changelog size $size1"
21445
21446         rm -rf $DIR/$tdir
21447         $LFS mkdir -i 0 $DIR/$tdir
21448         # change something
21449         mkdir -p $DIR/$tdir/pics/2008/zachy
21450         touch $DIR/$tdir/pics/2008/zachy/timestamp
21451         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21452         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21453         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21454         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21455         rm $DIR/$tdir/pics/desktop.jpg
21456
21457         local size2=$(do_facet $SINGLEMDS \
21458                       $LCTL get_param -n mdd.$mdt.changelog_size)
21459         echo "Changelog size after work $size2"
21460
21461         (( $size2 > $size1 )) ||
21462                 error "new Changelog size=$size2 less than old size=$size1"
21463 }
21464 run_test 254 "Check changelog size"
21465
21466 ladvise_no_type()
21467 {
21468         local type=$1
21469         local file=$2
21470
21471         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21472                 awk -F: '{print $2}' | grep $type > /dev/null
21473         if [ $? -ne 0 ]; then
21474                 return 0
21475         fi
21476         return 1
21477 }
21478
21479 ladvise_no_ioctl()
21480 {
21481         local file=$1
21482
21483         lfs ladvise -a willread $file > /dev/null 2>&1
21484         if [ $? -eq 0 ]; then
21485                 return 1
21486         fi
21487
21488         lfs ladvise -a willread $file 2>&1 |
21489                 grep "Inappropriate ioctl for device" > /dev/null
21490         if [ $? -eq 0 ]; then
21491                 return 0
21492         fi
21493         return 1
21494 }
21495
21496 percent() {
21497         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21498 }
21499
21500 # run a random read IO workload
21501 # usage: random_read_iops <filename> <filesize> <iosize>
21502 random_read_iops() {
21503         local file=$1
21504         local fsize=$2
21505         local iosize=${3:-4096}
21506
21507         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21508                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21509 }
21510
21511 drop_file_oss_cache() {
21512         local file="$1"
21513         local nodes="$2"
21514
21515         $LFS ladvise -a dontneed $file 2>/dev/null ||
21516                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21517 }
21518
21519 ladvise_willread_performance()
21520 {
21521         local repeat=10
21522         local average_origin=0
21523         local average_cache=0
21524         local average_ladvise=0
21525
21526         for ((i = 1; i <= $repeat; i++)); do
21527                 echo "Iter $i/$repeat: reading without willread hint"
21528                 cancel_lru_locks osc
21529                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21530                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21531                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21532                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21533
21534                 cancel_lru_locks osc
21535                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21536                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21537                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21538
21539                 cancel_lru_locks osc
21540                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21541                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21542                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21543                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21544                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21545         done
21546         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21547         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21548         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21549
21550         speedup_cache=$(percent $average_cache $average_origin)
21551         speedup_ladvise=$(percent $average_ladvise $average_origin)
21552
21553         echo "Average uncached read: $average_origin"
21554         echo "Average speedup with OSS cached read: " \
21555                 "$average_cache = +$speedup_cache%"
21556         echo "Average speedup with ladvise willread: " \
21557                 "$average_ladvise = +$speedup_ladvise%"
21558
21559         local lowest_speedup=20
21560         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
21561                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
21562                         "got $average_cache%. Skipping ladvise willread check."
21563                 return 0
21564         fi
21565
21566         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21567         # it is still good to run until then to exercise 'ladvise willread'
21568         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21569                 [ "$ost1_FSTYPE" = "zfs" ] &&
21570                 echo "osd-zfs does not support dontneed or drop_caches" &&
21571                 return 0
21572
21573         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21574         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
21575                 error_not_in_vm "Speedup with willread is less than " \
21576                         "$lowest_speedup%, got $average_ladvise%"
21577 }
21578
21579 test_255a() {
21580         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21581                 skip "lustre < 2.8.54 does not support ladvise "
21582         remote_ost_nodsh && skip "remote OST with nodsh"
21583
21584         stack_trap "rm -f $DIR/$tfile"
21585         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21586
21587         ladvise_no_type willread $DIR/$tfile &&
21588                 skip "willread ladvise is not supported"
21589
21590         ladvise_no_ioctl $DIR/$tfile &&
21591                 skip "ladvise ioctl is not supported"
21592
21593         local size_mb=100
21594         local size=$((size_mb * 1048576))
21595         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21596                 error "dd to $DIR/$tfile failed"
21597
21598         lfs ladvise -a willread $DIR/$tfile ||
21599                 error "Ladvise failed with no range argument"
21600
21601         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21602                 error "Ladvise failed with no -l or -e argument"
21603
21604         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21605                 error "Ladvise failed with only -e argument"
21606
21607         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21608                 error "Ladvise failed with only -l argument"
21609
21610         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21611                 error "End offset should not be smaller than start offset"
21612
21613         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21614                 error "End offset should not be equal to start offset"
21615
21616         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21617                 error "Ladvise failed with overflowing -s argument"
21618
21619         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21620                 error "Ladvise failed with overflowing -e argument"
21621
21622         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21623                 error "Ladvise failed with overflowing -l argument"
21624
21625         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21626                 error "Ladvise succeeded with conflicting -l and -e arguments"
21627
21628         echo "Synchronous ladvise should wait"
21629         local delay=4
21630 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21631         do_nodes $(comma_list $(osts_nodes)) \
21632                 $LCTL set_param fail_val=$delay fail_loc=0x237
21633
21634         local start_ts=$SECONDS
21635         lfs ladvise -a willread $DIR/$tfile ||
21636                 error "Ladvise failed with no range argument"
21637         local end_ts=$SECONDS
21638         local inteval_ts=$((end_ts - start_ts))
21639
21640         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21641                 error "Synchronous advice didn't wait reply"
21642         fi
21643
21644         echo "Asynchronous ladvise shouldn't wait"
21645         local start_ts=$SECONDS
21646         lfs ladvise -a willread -b $DIR/$tfile ||
21647                 error "Ladvise failed with no range argument"
21648         local end_ts=$SECONDS
21649         local inteval_ts=$((end_ts - start_ts))
21650
21651         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21652                 error "Asynchronous advice blocked"
21653         fi
21654
21655         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21656         ladvise_willread_performance
21657 }
21658 run_test 255a "check 'lfs ladvise -a willread'"
21659
21660 facet_meminfo() {
21661         local facet=$1
21662         local info=$2
21663
21664         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21665 }
21666
21667 test_255b() {
21668         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21669                 skip "lustre < 2.8.54 does not support ladvise "
21670         remote_ost_nodsh && skip "remote OST with nodsh"
21671
21672         stack_trap "rm -f $DIR/$tfile"
21673         lfs setstripe -c 1 -i 0 $DIR/$tfile
21674
21675         ladvise_no_type dontneed $DIR/$tfile &&
21676                 skip "dontneed ladvise is not supported"
21677
21678         ladvise_no_ioctl $DIR/$tfile &&
21679                 skip "ladvise ioctl is not supported"
21680
21681         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21682                 [ "$ost1_FSTYPE" = "zfs" ] &&
21683                 skip "zfs-osd does not support 'ladvise dontneed'"
21684
21685         local size_mb=100
21686         local size=$((size_mb * 1048576))
21687         # In order to prevent disturbance of other processes, only check 3/4
21688         # of the memory usage
21689         local kibibytes=$((size_mb * 1024 * 3 / 4))
21690
21691         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21692                 error "dd to $DIR/$tfile failed"
21693
21694         #force write to complete before dropping OST cache & checking memory
21695         sync
21696
21697         local total=$(facet_meminfo ost1 MemTotal)
21698         echo "Total memory: $total KiB"
21699
21700         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21701         local before_read=$(facet_meminfo ost1 Cached)
21702         echo "Cache used before read: $before_read KiB"
21703
21704         lfs ladvise -a willread $DIR/$tfile ||
21705                 error "Ladvise willread failed"
21706         local after_read=$(facet_meminfo ost1 Cached)
21707         echo "Cache used after read: $after_read KiB"
21708
21709         lfs ladvise -a dontneed $DIR/$tfile ||
21710                 error "Ladvise dontneed again failed"
21711         local no_read=$(facet_meminfo ost1 Cached)
21712         echo "Cache used after dontneed ladvise: $no_read KiB"
21713
21714         if [ $total -lt $((before_read + kibibytes)) ]; then
21715                 echo "Memory is too small, abort checking"
21716                 return 0
21717         fi
21718
21719         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21720                 error "Ladvise willread should use more memory" \
21721                         "than $kibibytes KiB"
21722         fi
21723
21724         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21725                 error "Ladvise dontneed should release more memory" \
21726                         "than $kibibytes KiB"
21727         fi
21728 }
21729 run_test 255b "check 'lfs ladvise -a dontneed'"
21730
21731 test_255c() {
21732         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21733                 skip "lustre < 2.10.50 does not support lockahead"
21734
21735         local ost1_imp=$(get_osc_import_name client ost1)
21736         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21737                          cut -d'.' -f2)
21738         local count
21739         local new_count
21740         local difference
21741         local i
21742         local rc
21743
21744         test_mkdir -p $DIR/$tdir
21745         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21746
21747         #test 10 returns only success/failure
21748         i=10
21749         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21750         rc=$?
21751         if [ $rc -eq 255 ]; then
21752                 error "Ladvise test${i} failed, ${rc}"
21753         fi
21754
21755         #test 11 counts lock enqueue requests, all others count new locks
21756         i=11
21757         count=$(do_facet ost1 \
21758                 $LCTL get_param -n ost.OSS.ost.stats)
21759         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21760
21761         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21762         rc=$?
21763         if [ $rc -eq 255 ]; then
21764                 error "Ladvise test${i} failed, ${rc}"
21765         fi
21766
21767         new_count=$(do_facet ost1 \
21768                 $LCTL get_param -n ost.OSS.ost.stats)
21769         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21770                    awk '{ print $2 }')
21771
21772         difference="$((new_count - count))"
21773         if [ $difference -ne $rc ]; then
21774                 error "Ladvise test${i}, bad enqueue count, returned " \
21775                       "${rc}, actual ${difference}"
21776         fi
21777
21778         for i in $(seq 12 21); do
21779                 # If we do not do this, we run the risk of having too many
21780                 # locks and starting lock cancellation while we are checking
21781                 # lock counts.
21782                 cancel_lru_locks osc
21783
21784                 count=$($LCTL get_param -n \
21785                        ldlm.namespaces.$imp_name.lock_unused_count)
21786
21787                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21788                 rc=$?
21789                 if [ $rc -eq 255 ]; then
21790                         error "Ladvise test ${i} failed, ${rc}"
21791                 fi
21792
21793                 new_count=$($LCTL get_param -n \
21794                        ldlm.namespaces.$imp_name.lock_unused_count)
21795                 difference="$((new_count - count))"
21796
21797                 # Test 15 output is divided by 100 to map down to valid return
21798                 if [ $i -eq 15 ]; then
21799                         rc="$((rc * 100))"
21800                 fi
21801
21802                 if [ $difference -ne $rc ]; then
21803                         error "Ladvise test ${i}, bad lock count, returned " \
21804                               "${rc}, actual ${difference}"
21805                 fi
21806         done
21807
21808         #test 22 returns only success/failure
21809         i=22
21810         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21811         rc=$?
21812         if [ $rc -eq 255 ]; then
21813                 error "Ladvise test${i} failed, ${rc}"
21814         fi
21815 }
21816 run_test 255c "suite of ladvise lockahead tests"
21817
21818 test_256() {
21819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21820         remote_mds_nodsh && skip "remote MDS with nodsh"
21821         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21822         changelog_users $SINGLEMDS | grep "^cl" &&
21823                 skip "active changelog user"
21824
21825         local cl_user
21826         local cat_sl
21827         local mdt_dev
21828
21829         mdt_dev=$(facet_device $SINGLEMDS)
21830         echo $mdt_dev
21831
21832         changelog_register || error "changelog_register failed"
21833
21834         rm -rf $DIR/$tdir
21835         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
21836
21837         changelog_clear 0 || error "changelog_clear failed"
21838
21839         # change something
21840         touch $DIR/$tdir/{1..10}
21841
21842         # stop the MDT
21843         stop $SINGLEMDS || error "Fail to stop MDT"
21844
21845         # remount the MDT
21846         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21847                 error "Fail to start MDT"
21848
21849         #after mount new plainllog is used
21850         touch $DIR/$tdir/{11..19}
21851         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21852         stack_trap "rm -f $tmpfile"
21853         cat_sl=$(do_facet $SINGLEMDS "sync; \
21854                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21855                  llog_reader $tmpfile | grep -c type=1064553b")
21856         do_facet $SINGLEMDS llog_reader $tmpfile
21857
21858         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21859
21860         changelog_clear 0 || error "changelog_clear failed"
21861
21862         cat_sl=$(do_facet $SINGLEMDS "sync; \
21863                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21864                  llog_reader $tmpfile | grep -c type=1064553b")
21865
21866         if (( cat_sl == 2 )); then
21867                 error "Empty plain llog was not deleted from changelog catalog"
21868         elif (( cat_sl != 1 )); then
21869                 error "Active plain llog shouldn't be deleted from catalog"
21870         fi
21871 }
21872 run_test 256 "Check llog delete for empty and not full state"
21873
21874 test_257() {
21875         remote_mds_nodsh && skip "remote MDS with nodsh"
21876         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21877                 skip "Need MDS version at least 2.8.55"
21878
21879         test_mkdir $DIR/$tdir
21880
21881         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21882                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21883         stat $DIR/$tdir
21884
21885 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21886         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21887         local facet=mds$((mdtidx + 1))
21888         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21889         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21890
21891         stop $facet || error "stop MDS failed"
21892         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21893                 error "start MDS fail"
21894         wait_recovery_complete $facet
21895 }
21896 run_test 257 "xattr locks are not lost"
21897
21898 # Verify we take the i_mutex when security requires it
21899 test_258a() {
21900 #define OBD_FAIL_IMUTEX_SEC 0x141c
21901         $LCTL set_param fail_loc=0x141c
21902         touch $DIR/$tfile
21903         chmod u+s $DIR/$tfile
21904         chmod a+rwx $DIR/$tfile
21905         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21906         RC=$?
21907         if [ $RC -ne 0 ]; then
21908                 error "error, failed to take i_mutex, rc=$?"
21909         fi
21910         rm -f $DIR/$tfile
21911 }
21912 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21913
21914 # Verify we do NOT take the i_mutex in the normal case
21915 test_258b() {
21916 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21917         $LCTL set_param fail_loc=0x141d
21918         touch $DIR/$tfile
21919         chmod a+rwx $DIR
21920         chmod a+rw $DIR/$tfile
21921         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21922         RC=$?
21923         if [ $RC -ne 0 ]; then
21924                 error "error, took i_mutex unnecessarily, rc=$?"
21925         fi
21926         rm -f $DIR/$tfile
21927
21928 }
21929 run_test 258b "verify i_mutex security behavior"
21930
21931 test_259() {
21932         local file=$DIR/$tfile
21933         local before
21934         local after
21935
21936         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21937
21938         stack_trap "rm -f $file" EXIT
21939
21940         wait_delete_completed
21941         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21942         echo "before: $before"
21943
21944         $LFS setstripe -i 0 -c 1 $file
21945         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21946         sync_all_data
21947         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21948         echo "after write: $after"
21949
21950 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21951         do_facet ost1 $LCTL set_param fail_loc=0x2301
21952         $TRUNCATE $file 0
21953         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21954         echo "after truncate: $after"
21955
21956         stop ost1
21957         do_facet ost1 $LCTL set_param fail_loc=0
21958         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21959         sleep 2
21960         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21961         echo "after restart: $after"
21962         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21963                 error "missing truncate?"
21964
21965         return 0
21966 }
21967 run_test 259 "crash at delayed truncate"
21968
21969 test_260() {
21970 #define OBD_FAIL_MDC_CLOSE               0x806
21971         $LCTL set_param fail_loc=0x80000806
21972         touch $DIR/$tfile
21973
21974 }
21975 run_test 260 "Check mdc_close fail"
21976
21977 ### Data-on-MDT sanity tests ###
21978 test_270a() {
21979         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21980                 skip "Need MDS version at least 2.10.55 for DoM"
21981
21982         # create DoM file
21983         local dom=$DIR/$tdir/dom_file
21984         local tmp=$DIR/$tdir/tmp_file
21985
21986         mkdir_on_mdt0 $DIR/$tdir
21987
21988         # basic checks for DoM component creation
21989         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21990                 error "Can set MDT layout to non-first entry"
21991
21992         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21993                 error "Can define multiple entries as MDT layout"
21994
21995         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21996
21997         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21998         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21999         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22000
22001         local mdtidx=$($LFS getstripe -m $dom)
22002         local mdtname=MDT$(printf %04x $mdtidx)
22003         local facet=mds$((mdtidx + 1))
22004         local space_check=1
22005
22006         # Skip free space checks with ZFS
22007         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22008
22009         # write
22010         sync
22011         local size_tmp=$((65536 * 3))
22012         local mdtfree1=$(do_facet $facet \
22013                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22014
22015         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22016         # check also direct IO along write
22017         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22018         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22019         sync
22020         cmp $tmp $dom || error "file data is different"
22021         [ $(stat -c%s $dom) == $size_tmp ] ||
22022                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22023         if [ $space_check == 1 ]; then
22024                 local mdtfree2=$(do_facet $facet \
22025                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22026
22027                 # increase in usage from by $size_tmp
22028                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22029                         error "MDT free space wrong after write: " \
22030                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22031         fi
22032
22033         # truncate
22034         local size_dom=10000
22035
22036         $TRUNCATE $dom $size_dom
22037         [ $(stat -c%s $dom) == $size_dom ] ||
22038                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22039         if [ $space_check == 1 ]; then
22040                 mdtfree1=$(do_facet $facet \
22041                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22042                 # decrease in usage from $size_tmp to new $size_dom
22043                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22044                   $(((size_tmp - size_dom) / 1024)) ] ||
22045                         error "MDT free space is wrong after truncate: " \
22046                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22047         fi
22048
22049         # append
22050         cat $tmp >> $dom
22051         sync
22052         size_dom=$((size_dom + size_tmp))
22053         [ $(stat -c%s $dom) == $size_dom ] ||
22054                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22055         if [ $space_check == 1 ]; then
22056                 mdtfree2=$(do_facet $facet \
22057                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22058                 # increase in usage by $size_tmp from previous
22059                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22060                         error "MDT free space is wrong after append: " \
22061                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22062         fi
22063
22064         # delete
22065         rm $dom
22066         if [ $space_check == 1 ]; then
22067                 mdtfree1=$(do_facet $facet \
22068                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22069                 # decrease in usage by $size_dom from previous
22070                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22071                         error "MDT free space is wrong after removal: " \
22072                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22073         fi
22074
22075         # combined striping
22076         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22077                 error "Can't create DoM + OST striping"
22078
22079         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22080         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22081         # check also direct IO along write
22082         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22083         sync
22084         cmp $tmp $dom || error "file data is different"
22085         [ $(stat -c%s $dom) == $size_tmp ] ||
22086                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22087         rm $dom $tmp
22088
22089         return 0
22090 }
22091 run_test 270a "DoM: basic functionality tests"
22092
22093 test_270b() {
22094         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22095                 skip "Need MDS version at least 2.10.55"
22096
22097         local dom=$DIR/$tdir/dom_file
22098         local max_size=1048576
22099
22100         mkdir -p $DIR/$tdir
22101         $LFS setstripe -E $max_size -L mdt $dom
22102
22103         # truncate over the limit
22104         $TRUNCATE $dom $(($max_size + 1)) &&
22105                 error "successful truncate over the maximum size"
22106         # write over the limit
22107         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22108                 error "successful write over the maximum size"
22109         # append over the limit
22110         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22111         echo "12345" >> $dom && error "successful append over the maximum size"
22112         rm $dom
22113
22114         return 0
22115 }
22116 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22117
22118 test_270c() {
22119         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22120                 skip "Need MDS version at least 2.10.55"
22121
22122         mkdir -p $DIR/$tdir
22123         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22124
22125         # check files inherit DoM EA
22126         touch $DIR/$tdir/first
22127         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22128                 error "bad pattern"
22129         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22130                 error "bad stripe count"
22131         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22132                 error "bad stripe size"
22133
22134         # check directory inherits DoM EA and uses it as default
22135         mkdir $DIR/$tdir/subdir
22136         touch $DIR/$tdir/subdir/second
22137         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22138                 error "bad pattern in sub-directory"
22139         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22140                 error "bad stripe count in sub-directory"
22141         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22142                 error "bad stripe size in sub-directory"
22143         return 0
22144 }
22145 run_test 270c "DoM: DoM EA inheritance tests"
22146
22147 test_270d() {
22148         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22149                 skip "Need MDS version at least 2.10.55"
22150
22151         mkdir -p $DIR/$tdir
22152         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22153
22154         # inherit default DoM striping
22155         mkdir $DIR/$tdir/subdir
22156         touch $DIR/$tdir/subdir/f1
22157
22158         # change default directory striping
22159         $LFS setstripe -c 1 $DIR/$tdir/subdir
22160         touch $DIR/$tdir/subdir/f2
22161         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22162                 error "wrong default striping in file 2"
22163         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22164                 error "bad pattern in file 2"
22165         return 0
22166 }
22167 run_test 270d "DoM: change striping from DoM to RAID0"
22168
22169 test_270e() {
22170         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22171                 skip "Need MDS version at least 2.10.55"
22172
22173         mkdir -p $DIR/$tdir/dom
22174         mkdir -p $DIR/$tdir/norm
22175         DOMFILES=20
22176         NORMFILES=10
22177         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22178         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22179
22180         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22181         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22182
22183         # find DoM files by layout
22184         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22185         [ $NUM -eq  $DOMFILES ] ||
22186                 error "lfs find -L: found $NUM, expected $DOMFILES"
22187         echo "Test 1: lfs find 20 DOM files by layout: OK"
22188
22189         # there should be 1 dir with default DOM striping
22190         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22191         [ $NUM -eq  1 ] ||
22192                 error "lfs find -L: found $NUM, expected 1 dir"
22193         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22194
22195         # find DoM files by stripe size
22196         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22197         [ $NUM -eq  $DOMFILES ] ||
22198                 error "lfs find -S: found $NUM, expected $DOMFILES"
22199         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22200
22201         # find files by stripe offset except DoM files
22202         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22203         [ $NUM -eq  $NORMFILES ] ||
22204                 error "lfs find -i: found $NUM, expected $NORMFILES"
22205         echo "Test 5: lfs find no DOM files by stripe index: OK"
22206         return 0
22207 }
22208 run_test 270e "DoM: lfs find with DoM files test"
22209
22210 test_270f() {
22211         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22212                 skip "Need MDS version at least 2.10.55"
22213
22214         local mdtname=${FSNAME}-MDT0000-mdtlov
22215         local dom=$DIR/$tdir/dom_file
22216         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22217                                                 lod.$mdtname.dom_stripesize)
22218         local dom_limit=131072
22219
22220         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22221         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22222                                                 lod.$mdtname.dom_stripesize)
22223         [ ${dom_limit} -eq ${dom_current} ] ||
22224                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22225
22226         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22227         $LFS setstripe -d $DIR/$tdir
22228         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22229                 error "Can't set directory default striping"
22230
22231         # exceed maximum stripe size
22232         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22233                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22234         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22235                 error "Able to create DoM component size more than LOD limit"
22236
22237         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22238         dom_current=$(do_facet mds1 $LCTL get_param -n \
22239                                                 lod.$mdtname.dom_stripesize)
22240         [ 0 -eq ${dom_current} ] ||
22241                 error "Can't set zero DoM stripe limit"
22242         rm $dom
22243
22244         # attempt to create DoM file on server with disabled DoM should
22245         # remove DoM entry from layout and be succeed
22246         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22247                 error "Can't create DoM file (DoM is disabled)"
22248         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22249                 error "File has DoM component while DoM is disabled"
22250         rm $dom
22251
22252         # attempt to create DoM file with only DoM stripe should return error
22253         $LFS setstripe -E $dom_limit -L mdt $dom &&
22254                 error "Able to create DoM-only file while DoM is disabled"
22255
22256         # too low values to be aligned with smallest stripe size 64K
22257         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22258         dom_current=$(do_facet mds1 $LCTL get_param -n \
22259                                                 lod.$mdtname.dom_stripesize)
22260         [ 30000 -eq ${dom_current} ] &&
22261                 error "Can set too small DoM stripe limit"
22262
22263         # 64K is a minimal stripe size in Lustre, expect limit of that size
22264         [ 65536 -eq ${dom_current} ] ||
22265                 error "Limit is not set to 64K but ${dom_current}"
22266
22267         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22268         dom_current=$(do_facet mds1 $LCTL get_param -n \
22269                                                 lod.$mdtname.dom_stripesize)
22270         echo $dom_current
22271         [ 2147483648 -eq ${dom_current} ] &&
22272                 error "Can set too large DoM stripe limit"
22273
22274         do_facet mds1 $LCTL set_param -n \
22275                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22276         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22277                 error "Can't create DoM component size after limit change"
22278         do_facet mds1 $LCTL set_param -n \
22279                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22280         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22281                 error "Can't create DoM file after limit decrease"
22282         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22283                 error "Can create big DoM component after limit decrease"
22284         touch ${dom}_def ||
22285                 error "Can't create file with old default layout"
22286
22287         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22288         return 0
22289 }
22290 run_test 270f "DoM: maximum DoM stripe size checks"
22291
22292 test_270g() {
22293         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22294                 skip "Need MDS version at least 2.13.52"
22295         local dom=$DIR/$tdir/$tfile
22296
22297         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22298         local lodname=${FSNAME}-MDT0000-mdtlov
22299
22300         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22301         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22302         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22303         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22304
22305         local dom_limit=1024
22306         local dom_threshold="50%"
22307
22308         $LFS setstripe -d $DIR/$tdir
22309         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22310                 error "Can't set directory default striping"
22311
22312         do_facet mds1 $LCTL set_param -n \
22313                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22314         # set 0 threshold and create DOM file to change tunable stripesize
22315         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22316         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22317                 error "Failed to create $dom file"
22318         # now tunable dom_cur_stripesize should reach maximum
22319         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22320                                         lod.${lodname}.dom_stripesize_cur_kb)
22321         [[ $dom_current == $dom_limit ]] ||
22322                 error "Current DOM stripesize is not maximum"
22323         rm $dom
22324
22325         # set threshold for further tests
22326         do_facet mds1 $LCTL set_param -n \
22327                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22328         echo "DOM threshold is $dom_threshold free space"
22329         local dom_def
22330         local dom_set
22331         # Spoof bfree to exceed threshold
22332         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22333         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22334         for spfree in 40 20 0 15 30 55; do
22335                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22336                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22337                         error "Failed to create $dom file"
22338                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22339                                         lod.${lodname}.dom_stripesize_cur_kb)
22340                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22341                 [[ $dom_def != $dom_current ]] ||
22342                         error "Default stripe size was not changed"
22343                 if [[ $spfree > 0 ]] ; then
22344                         dom_set=$($LFS getstripe -S $dom)
22345                         [[ $dom_set == $((dom_def * 1024)) ]] ||
22346                                 error "DOM component size is still old"
22347                 else
22348                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22349                                 error "DoM component is set with no free space"
22350                 fi
22351                 rm $dom
22352                 dom_current=$dom_def
22353         done
22354 }
22355 run_test 270g "DoM: default DoM stripe size depends on free space"
22356
22357 test_270h() {
22358         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22359                 skip "Need MDS version at least 2.13.53"
22360
22361         local mdtname=${FSNAME}-MDT0000-mdtlov
22362         local dom=$DIR/$tdir/$tfile
22363         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22364
22365         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22366         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22367
22368         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22369         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22370                 error "can't create OST file"
22371         # mirrored file with DOM entry in the second mirror
22372         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22373                 error "can't create mirror with DoM component"
22374
22375         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22376
22377         # DOM component in the middle and has other enries in the same mirror,
22378         # should succeed but lost DoM component
22379         $LFS setstripe --copy=${dom}_1 $dom ||
22380                 error "Can't create file from OST|DOM mirror layout"
22381         # check new file has no DoM layout after all
22382         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22383                 error "File has DoM component while DoM is disabled"
22384 }
22385 run_test 270h "DoM: DoM stripe removal when disabled on server"
22386
22387 test_270i() {
22388         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22389                 skip "Need MDS version at least 2.14.54"
22390
22391         mkdir $DIR/$tdir
22392         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22393                 error "setstripe should fail" || true
22394 }
22395 run_test 270i "DoM: setting invalid DoM striping should fail"
22396
22397 test_271a() {
22398         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22399                 skip "Need MDS version at least 2.10.55"
22400
22401         local dom=$DIR/$tdir/dom
22402
22403         mkdir -p $DIR/$tdir
22404
22405         $LFS setstripe -E 1024K -L mdt $dom
22406
22407         lctl set_param -n mdc.*.stats=clear
22408         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22409         cat $dom > /dev/null
22410         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22411         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22412         ls $dom
22413         rm -f $dom
22414 }
22415 run_test 271a "DoM: data is cached for read after write"
22416
22417 test_271b() {
22418         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22419                 skip "Need MDS version at least 2.10.55"
22420
22421         local dom=$DIR/$tdir/dom
22422
22423         mkdir -p $DIR/$tdir
22424
22425         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22426
22427         lctl set_param -n mdc.*.stats=clear
22428         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22429         cancel_lru_locks mdc
22430         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22431         # second stat to check size is cached on client
22432         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22433         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22434         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22435         rm -f $dom
22436 }
22437 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22438
22439 test_271ba() {
22440         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22441                 skip "Need MDS version at least 2.10.55"
22442
22443         local dom=$DIR/$tdir/dom
22444
22445         mkdir -p $DIR/$tdir
22446
22447         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22448
22449         lctl set_param -n mdc.*.stats=clear
22450         lctl set_param -n osc.*.stats=clear
22451         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22452         cancel_lru_locks mdc
22453         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22454         # second stat to check size is cached on client
22455         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22456         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22457         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22458         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22459         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22460         rm -f $dom
22461 }
22462 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22463
22464
22465 get_mdc_stats() {
22466         local mdtidx=$1
22467         local param=$2
22468         local mdt=MDT$(printf %04x $mdtidx)
22469
22470         if [ -z $param ]; then
22471                 lctl get_param -n mdc.*$mdt*.stats
22472         else
22473                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22474         fi
22475 }
22476
22477 test_271c() {
22478         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22479                 skip "Need MDS version at least 2.10.55"
22480
22481         local dom=$DIR/$tdir/dom
22482
22483         mkdir -p $DIR/$tdir
22484
22485         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22486
22487         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22488         local facet=mds$((mdtidx + 1))
22489
22490         cancel_lru_locks mdc
22491         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22492         createmany -o $dom 1000
22493         lctl set_param -n mdc.*.stats=clear
22494         smalliomany -w $dom 1000 200
22495         get_mdc_stats $mdtidx
22496         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22497         # Each file has 1 open, 1 IO enqueues, total 2000
22498         # but now we have also +1 getxattr for security.capability, total 3000
22499         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22500         unlinkmany $dom 1000
22501
22502         cancel_lru_locks mdc
22503         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22504         createmany -o $dom 1000
22505         lctl set_param -n mdc.*.stats=clear
22506         smalliomany -w $dom 1000 200
22507         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22508         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22509         # for OPEN and IO lock.
22510         [ $((enq - enq_2)) -ge 1000 ] ||
22511                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22512         unlinkmany $dom 1000
22513         return 0
22514 }
22515 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22516
22517 cleanup_271def_tests() {
22518         trap 0
22519         rm -f $1
22520 }
22521
22522 test_271d() {
22523         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22524                 skip "Need MDS version at least 2.10.57"
22525
22526         local dom=$DIR/$tdir/dom
22527         local tmp=$TMP/$tfile
22528         trap "cleanup_271def_tests $tmp" EXIT
22529
22530         mkdir -p $DIR/$tdir
22531
22532         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22533
22534         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22535
22536         cancel_lru_locks mdc
22537         dd if=/dev/urandom of=$tmp bs=1000 count=1
22538         dd if=$tmp of=$dom bs=1000 count=1
22539         cancel_lru_locks mdc
22540
22541         cat /etc/hosts >> $tmp
22542         lctl set_param -n mdc.*.stats=clear
22543
22544         # append data to the same file it should update local page
22545         echo "Append to the same page"
22546         cat /etc/hosts >> $dom
22547         local num=$(get_mdc_stats $mdtidx ost_read)
22548         local ra=$(get_mdc_stats $mdtidx req_active)
22549         local rw=$(get_mdc_stats $mdtidx req_waittime)
22550
22551         [ -z $num ] || error "$num READ RPC occured"
22552         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22553         echo "... DONE"
22554
22555         # compare content
22556         cmp $tmp $dom || error "file miscompare"
22557
22558         cancel_lru_locks mdc
22559         lctl set_param -n mdc.*.stats=clear
22560
22561         echo "Open and read file"
22562         cat $dom > /dev/null
22563         local num=$(get_mdc_stats $mdtidx ost_read)
22564         local ra=$(get_mdc_stats $mdtidx req_active)
22565         local rw=$(get_mdc_stats $mdtidx req_waittime)
22566
22567         [ -z $num ] || error "$num READ RPC occured"
22568         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22569         echo "... DONE"
22570
22571         # compare content
22572         cmp $tmp $dom || error "file miscompare"
22573
22574         return 0
22575 }
22576 run_test 271d "DoM: read on open (1K file in reply buffer)"
22577
22578 test_271f() {
22579         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22580                 skip "Need MDS version at least 2.10.57"
22581
22582         local dom=$DIR/$tdir/dom
22583         local tmp=$TMP/$tfile
22584         trap "cleanup_271def_tests $tmp" EXIT
22585
22586         mkdir -p $DIR/$tdir
22587
22588         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22589
22590         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22591
22592         cancel_lru_locks mdc
22593         dd if=/dev/urandom of=$tmp bs=265000 count=1
22594         dd if=$tmp of=$dom bs=265000 count=1
22595         cancel_lru_locks mdc
22596         cat /etc/hosts >> $tmp
22597         lctl set_param -n mdc.*.stats=clear
22598
22599         echo "Append to the same page"
22600         cat /etc/hosts >> $dom
22601         local num=$(get_mdc_stats $mdtidx ost_read)
22602         local ra=$(get_mdc_stats $mdtidx req_active)
22603         local rw=$(get_mdc_stats $mdtidx req_waittime)
22604
22605         [ -z $num ] || error "$num READ RPC occured"
22606         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22607         echo "... DONE"
22608
22609         # compare content
22610         cmp $tmp $dom || error "file miscompare"
22611
22612         cancel_lru_locks mdc
22613         lctl set_param -n mdc.*.stats=clear
22614
22615         echo "Open and read file"
22616         cat $dom > /dev/null
22617         local num=$(get_mdc_stats $mdtidx ost_read)
22618         local ra=$(get_mdc_stats $mdtidx req_active)
22619         local rw=$(get_mdc_stats $mdtidx req_waittime)
22620
22621         [ -z $num ] && num=0
22622         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22623         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22624         echo "... DONE"
22625
22626         # compare content
22627         cmp $tmp $dom || error "file miscompare"
22628
22629         return 0
22630 }
22631 run_test 271f "DoM: read on open (200K file and read tail)"
22632
22633 test_271g() {
22634         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22635                 skip "Skipping due to old client or server version"
22636
22637         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22638         # to get layout
22639         $CHECKSTAT -t file $DIR1/$tfile
22640
22641         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22642         MULTIOP_PID=$!
22643         sleep 1
22644         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22645         $LCTL set_param fail_loc=0x80000314
22646         rm $DIR1/$tfile || error "Unlink fails"
22647         RC=$?
22648         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22649         [ $RC -eq 0 ] || error "Failed write to stale object"
22650 }
22651 run_test 271g "Discard DoM data vs client flush race"
22652
22653 test_272a() {
22654         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22655                 skip "Need MDS version at least 2.11.50"
22656
22657         local dom=$DIR/$tdir/dom
22658         mkdir -p $DIR/$tdir
22659
22660         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22661         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22662                 error "failed to write data into $dom"
22663         local old_md5=$(md5sum $dom)
22664
22665         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22666                 error "failed to migrate to the same DoM component"
22667
22668         local new_md5=$(md5sum $dom)
22669
22670         [ "$old_md5" == "$new_md5" ] ||
22671                 error "md5sum differ: $old_md5, $new_md5"
22672
22673         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22674                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22675 }
22676 run_test 272a "DoM migration: new layout with the same DOM component"
22677
22678 test_272b() {
22679         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22680                 skip "Need MDS version at least 2.11.50"
22681
22682         local dom=$DIR/$tdir/dom
22683         mkdir -p $DIR/$tdir
22684         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22685
22686         local mdtidx=$($LFS getstripe -m $dom)
22687         local mdtname=MDT$(printf %04x $mdtidx)
22688         local facet=mds$((mdtidx + 1))
22689
22690         local mdtfree1=$(do_facet $facet \
22691                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22692         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22693                 error "failed to write data into $dom"
22694         local old_md5=$(md5sum $dom)
22695         cancel_lru_locks mdc
22696         local mdtfree1=$(do_facet $facet \
22697                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22698
22699         $LFS migrate -c2 $dom ||
22700                 error "failed to migrate to the new composite layout"
22701         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22702                 error "MDT stripe was not removed"
22703
22704         cancel_lru_locks mdc
22705         local new_md5=$(md5sum $dom)
22706         [ "$old_md5" == "$new_md5" ] ||
22707                 error "$old_md5 != $new_md5"
22708
22709         # Skip free space checks with ZFS
22710         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22711                 local mdtfree2=$(do_facet $facet \
22712                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22713                 [ $mdtfree2 -gt $mdtfree1 ] ||
22714                         error "MDT space is not freed after migration"
22715         fi
22716         return 0
22717 }
22718 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22719
22720 test_272c() {
22721         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22722                 skip "Need MDS version at least 2.11.50"
22723
22724         local dom=$DIR/$tdir/$tfile
22725         mkdir -p $DIR/$tdir
22726         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22727
22728         local mdtidx=$($LFS getstripe -m $dom)
22729         local mdtname=MDT$(printf %04x $mdtidx)
22730         local facet=mds$((mdtidx + 1))
22731
22732         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22733                 error "failed to write data into $dom"
22734         local old_md5=$(md5sum $dom)
22735         cancel_lru_locks mdc
22736         local mdtfree1=$(do_facet $facet \
22737                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22738
22739         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22740                 error "failed to migrate to the new composite layout"
22741         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22742                 error "MDT stripe was not removed"
22743
22744         cancel_lru_locks mdc
22745         local new_md5=$(md5sum $dom)
22746         [ "$old_md5" == "$new_md5" ] ||
22747                 error "$old_md5 != $new_md5"
22748
22749         # Skip free space checks with ZFS
22750         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22751                 local mdtfree2=$(do_facet $facet \
22752                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22753                 [ $mdtfree2 -gt $mdtfree1 ] ||
22754                         error "MDS space is not freed after migration"
22755         fi
22756         return 0
22757 }
22758 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22759
22760 test_272d() {
22761         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22762                 skip "Need MDS version at least 2.12.55"
22763
22764         local dom=$DIR/$tdir/$tfile
22765         mkdir -p $DIR/$tdir
22766         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22767
22768         local mdtidx=$($LFS getstripe -m $dom)
22769         local mdtname=MDT$(printf %04x $mdtidx)
22770         local facet=mds$((mdtidx + 1))
22771
22772         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22773                 error "failed to write data into $dom"
22774         local old_md5=$(md5sum $dom)
22775         cancel_lru_locks mdc
22776         local mdtfree1=$(do_facet $facet \
22777                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22778
22779         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22780                 error "failed mirroring to the new composite layout"
22781         $LFS mirror resync $dom ||
22782                 error "failed mirror resync"
22783         $LFS mirror split --mirror-id 1 -d $dom ||
22784                 error "failed mirror split"
22785
22786         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22787                 error "MDT stripe was not removed"
22788
22789         cancel_lru_locks mdc
22790         local new_md5=$(md5sum $dom)
22791         [ "$old_md5" == "$new_md5" ] ||
22792                 error "$old_md5 != $new_md5"
22793
22794         # Skip free space checks with ZFS
22795         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22796                 local mdtfree2=$(do_facet $facet \
22797                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22798                 [ $mdtfree2 -gt $mdtfree1 ] ||
22799                         error "MDS space is not freed after DOM mirror deletion"
22800         fi
22801         return 0
22802 }
22803 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22804
22805 test_272e() {
22806         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22807                 skip "Need MDS version at least 2.12.55"
22808
22809         local dom=$DIR/$tdir/$tfile
22810         mkdir -p $DIR/$tdir
22811         $LFS setstripe -c 2 $dom
22812
22813         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22814                 error "failed to write data into $dom"
22815         local old_md5=$(md5sum $dom)
22816         cancel_lru_locks
22817
22818         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22819                 error "failed mirroring to the DOM layout"
22820         $LFS mirror resync $dom ||
22821                 error "failed mirror resync"
22822         $LFS mirror split --mirror-id 1 -d $dom ||
22823                 error "failed mirror split"
22824
22825         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22826                 error "MDT stripe wasn't set"
22827
22828         cancel_lru_locks
22829         local new_md5=$(md5sum $dom)
22830         [ "$old_md5" == "$new_md5" ] ||
22831                 error "$old_md5 != $new_md5"
22832
22833         return 0
22834 }
22835 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22836
22837 test_272f() {
22838         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22839                 skip "Need MDS version at least 2.12.55"
22840
22841         local dom=$DIR/$tdir/$tfile
22842         mkdir -p $DIR/$tdir
22843         $LFS setstripe -c 2 $dom
22844
22845         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22846                 error "failed to write data into $dom"
22847         local old_md5=$(md5sum $dom)
22848         cancel_lru_locks
22849
22850         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22851                 error "failed migrating to the DOM file"
22852
22853         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22854                 error "MDT stripe wasn't set"
22855
22856         cancel_lru_locks
22857         local new_md5=$(md5sum $dom)
22858         [ "$old_md5" != "$new_md5" ] &&
22859                 error "$old_md5 != $new_md5"
22860
22861         return 0
22862 }
22863 run_test 272f "DoM migration: OST-striped file to DOM file"
22864
22865 test_273a() {
22866         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22867                 skip "Need MDS version at least 2.11.50"
22868
22869         # Layout swap cannot be done if either file has DOM component,
22870         # this will never be supported, migration should be used instead
22871
22872         local dom=$DIR/$tdir/$tfile
22873         mkdir -p $DIR/$tdir
22874
22875         $LFS setstripe -c2 ${dom}_plain
22876         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22877         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22878                 error "can swap layout with DoM component"
22879         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22880                 error "can swap layout with DoM component"
22881
22882         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22883         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22884                 error "can swap layout with DoM component"
22885         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22886                 error "can swap layout with DoM component"
22887         return 0
22888 }
22889 run_test 273a "DoM: layout swapping should fail with DOM"
22890
22891 test_273b() {
22892         mkdir -p $DIR/$tdir
22893         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22894
22895 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22896         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22897
22898         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22899 }
22900 run_test 273b "DoM: race writeback and object destroy"
22901
22902 test_275() {
22903         remote_ost_nodsh && skip "remote OST with nodsh"
22904         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22905                 skip "Need OST version >= 2.10.57"
22906
22907         local file=$DIR/$tfile
22908         local oss
22909
22910         oss=$(comma_list $(osts_nodes))
22911
22912         dd if=/dev/urandom of=$file bs=1M count=2 ||
22913                 error "failed to create a file"
22914         cancel_lru_locks osc
22915
22916         #lock 1
22917         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22918                 error "failed to read a file"
22919
22920 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22921         $LCTL set_param fail_loc=0x8000031f
22922
22923         cancel_lru_locks osc &
22924         sleep 1
22925
22926 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22927         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22928         #IO takes another lock, but matches the PENDING one
22929         #and places it to the IO RPC
22930         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22931                 error "failed to read a file with PENDING lock"
22932 }
22933 run_test 275 "Read on a canceled duplicate lock"
22934
22935 test_276() {
22936         remote_ost_nodsh && skip "remote OST with nodsh"
22937         local pid
22938
22939         do_facet ost1 "(while true; do \
22940                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22941                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22942         pid=$!
22943
22944         for LOOP in $(seq 20); do
22945                 stop ost1
22946                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22947         done
22948         kill -9 $pid
22949         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22950                 rm $TMP/sanity_276_pid"
22951 }
22952 run_test 276 "Race between mount and obd_statfs"
22953
22954 test_277() {
22955         $LCTL set_param ldlm.namespaces.*.lru_size=0
22956         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22957         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22958                         grep ^used_mb | awk '{print $2}')
22959         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22960         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22961                 oflag=direct conv=notrunc
22962         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22963                         grep ^used_mb | awk '{print $2}')
22964         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22965 }
22966 run_test 277 "Direct IO shall drop page cache"
22967
22968 test_278() {
22969         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22970         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22971         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22972                 skip "needs the same host for mdt1 mdt2" && return
22973
22974         local pid1
22975         local pid2
22976
22977 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22978         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22979         stop mds2 &
22980         pid2=$!
22981
22982         stop mds1
22983
22984         echo "Starting MDTs"
22985         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22986         wait $pid2
22987 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22988 #will return NULL
22989         do_facet mds2 $LCTL set_param fail_loc=0
22990
22991         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22992         wait_recovery_complete mds2
22993 }
22994 run_test 278 "Race starting MDS between MDTs stop/start"
22995
22996 test_280() {
22997         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22998                 skip "Need MGS version at least 2.13.52"
22999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23000         combined_mgs_mds || skip "needs combined MGS/MDT"
23001
23002         umount_client $MOUNT
23003 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23004         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23005
23006         mount_client $MOUNT &
23007         sleep 1
23008         stop mgs || error "stop mgs failed"
23009         #for a race mgs would crash
23010         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23011         # make sure we unmount client before remounting
23012         wait
23013         umount_client $MOUNT
23014         mount_client $MOUNT || error "mount client failed"
23015 }
23016 run_test 280 "Race between MGS umount and client llog processing"
23017
23018 cleanup_test_300() {
23019         trap 0
23020         umask $SAVE_UMASK
23021 }
23022 test_striped_dir() {
23023         local mdt_index=$1
23024         local stripe_count
23025         local stripe_index
23026
23027         mkdir -p $DIR/$tdir
23028
23029         SAVE_UMASK=$(umask)
23030         trap cleanup_test_300 RETURN EXIT
23031
23032         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23033                                                 $DIR/$tdir/striped_dir ||
23034                 error "set striped dir error"
23035
23036         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23037         [ "$mode" = "755" ] || error "expect 755 got $mode"
23038
23039         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23040                 error "getdirstripe failed"
23041         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23042         if [ "$stripe_count" != "2" ]; then
23043                 error "1:stripe_count is $stripe_count, expect 2"
23044         fi
23045         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23046         if [ "$stripe_count" != "2" ]; then
23047                 error "2:stripe_count is $stripe_count, expect 2"
23048         fi
23049
23050         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23051         if [ "$stripe_index" != "$mdt_index" ]; then
23052                 error "stripe_index is $stripe_index, expect $mdt_index"
23053         fi
23054
23055         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23056                 error "nlink error after create striped dir"
23057
23058         mkdir $DIR/$tdir/striped_dir/a
23059         mkdir $DIR/$tdir/striped_dir/b
23060
23061         stat $DIR/$tdir/striped_dir/a ||
23062                 error "create dir under striped dir failed"
23063         stat $DIR/$tdir/striped_dir/b ||
23064                 error "create dir under striped dir failed"
23065
23066         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23067                 error "nlink error after mkdir"
23068
23069         rmdir $DIR/$tdir/striped_dir/a
23070         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23071                 error "nlink error after rmdir"
23072
23073         rmdir $DIR/$tdir/striped_dir/b
23074         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23075                 error "nlink error after rmdir"
23076
23077         chattr +i $DIR/$tdir/striped_dir
23078         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23079                 error "immutable flags not working under striped dir!"
23080         chattr -i $DIR/$tdir/striped_dir
23081
23082         rmdir $DIR/$tdir/striped_dir ||
23083                 error "rmdir striped dir error"
23084
23085         cleanup_test_300
23086
23087         true
23088 }
23089
23090 test_300a() {
23091         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23092                 skip "skipped for lustre < 2.7.0"
23093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23094         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23095
23096         test_striped_dir 0 || error "failed on striped dir on MDT0"
23097         test_striped_dir 1 || error "failed on striped dir on MDT0"
23098 }
23099 run_test 300a "basic striped dir sanity test"
23100
23101 test_300b() {
23102         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23103                 skip "skipped for lustre < 2.7.0"
23104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23105         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23106
23107         local i
23108         local mtime1
23109         local mtime2
23110         local mtime3
23111
23112         test_mkdir $DIR/$tdir || error "mkdir fail"
23113         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23114                 error "set striped dir error"
23115         for i in {0..9}; do
23116                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23117                 sleep 1
23118                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23119                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23120                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23121                 sleep 1
23122                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23123                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23124                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23125         done
23126         true
23127 }
23128 run_test 300b "check ctime/mtime for striped dir"
23129
23130 test_300c() {
23131         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23132                 skip "skipped for lustre < 2.7.0"
23133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23134         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23135
23136         local file_count
23137
23138         mkdir_on_mdt0 $DIR/$tdir
23139         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23140                 error "set striped dir error"
23141
23142         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23143                 error "chown striped dir failed"
23144
23145         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23146                 error "create 5k files failed"
23147
23148         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23149
23150         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23151
23152         rm -rf $DIR/$tdir
23153 }
23154 run_test 300c "chown && check ls under striped directory"
23155
23156 test_300d() {
23157         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23158                 skip "skipped for lustre < 2.7.0"
23159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23160         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23161
23162         local stripe_count
23163         local file
23164
23165         mkdir -p $DIR/$tdir
23166         $LFS setstripe -c 2 $DIR/$tdir
23167
23168         #local striped directory
23169         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23170                 error "set striped dir error"
23171         #look at the directories for debug purposes
23172         ls -l $DIR/$tdir
23173         $LFS getdirstripe $DIR/$tdir
23174         ls -l $DIR/$tdir/striped_dir
23175         $LFS getdirstripe $DIR/$tdir/striped_dir
23176         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23177                 error "create 10 files failed"
23178
23179         #remote striped directory
23180         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23181                 error "set striped dir error"
23182         #look at the directories for debug purposes
23183         ls -l $DIR/$tdir
23184         $LFS getdirstripe $DIR/$tdir
23185         ls -l $DIR/$tdir/remote_striped_dir
23186         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23187         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23188                 error "create 10 files failed"
23189
23190         for file in $(find $DIR/$tdir); do
23191                 stripe_count=$($LFS getstripe -c $file)
23192                 [ $stripe_count -eq 2 ] ||
23193                         error "wrong stripe $stripe_count for $file"
23194         done
23195
23196         rm -rf $DIR/$tdir
23197 }
23198 run_test 300d "check default stripe under striped directory"
23199
23200 test_300e() {
23201         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23202                 skip "Need MDS version at least 2.7.55"
23203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23204         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23205
23206         local stripe_count
23207         local file
23208
23209         mkdir -p $DIR/$tdir
23210
23211         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23212                 error "set striped dir error"
23213
23214         touch $DIR/$tdir/striped_dir/a
23215         touch $DIR/$tdir/striped_dir/b
23216         touch $DIR/$tdir/striped_dir/c
23217
23218         mkdir $DIR/$tdir/striped_dir/dir_a
23219         mkdir $DIR/$tdir/striped_dir/dir_b
23220         mkdir $DIR/$tdir/striped_dir/dir_c
23221
23222         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23223                 error "set striped adir under striped dir error"
23224
23225         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23226                 error "set striped bdir under striped dir error"
23227
23228         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23229                 error "set striped cdir under striped dir error"
23230
23231         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23232                 error "rename dir under striped dir fails"
23233
23234         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23235                 error "rename dir under different stripes fails"
23236
23237         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23238                 error "rename file under striped dir should succeed"
23239
23240         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23241                 error "rename dir under striped dir should succeed"
23242
23243         rm -rf $DIR/$tdir
23244 }
23245 run_test 300e "check rename under striped directory"
23246
23247 test_300f() {
23248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23249         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23250         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23251                 skip "Need MDS version at least 2.7.55"
23252
23253         local stripe_count
23254         local file
23255
23256         rm -rf $DIR/$tdir
23257         mkdir -p $DIR/$tdir
23258
23259         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23260                 error "set striped dir error"
23261
23262         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23263                 error "set striped dir error"
23264
23265         touch $DIR/$tdir/striped_dir/a
23266         mkdir $DIR/$tdir/striped_dir/dir_a
23267         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23268                 error "create striped dir under striped dir fails"
23269
23270         touch $DIR/$tdir/striped_dir1/b
23271         mkdir $DIR/$tdir/striped_dir1/dir_b
23272         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23273                 error "create striped dir under striped dir fails"
23274
23275         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23276                 error "rename dir under different striped dir should fail"
23277
23278         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23279                 error "rename striped dir under diff striped dir should fail"
23280
23281         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23282                 error "rename file under diff striped dirs fails"
23283
23284         rm -rf $DIR/$tdir
23285 }
23286 run_test 300f "check rename cross striped directory"
23287
23288 test_300_check_default_striped_dir()
23289 {
23290         local dirname=$1
23291         local default_count=$2
23292         local default_index=$3
23293         local stripe_count
23294         local stripe_index
23295         local dir_stripe_index
23296         local dir
23297
23298         echo "checking $dirname $default_count $default_index"
23299         $LFS setdirstripe -D -c $default_count -i $default_index \
23300                                 -H all_char $DIR/$tdir/$dirname ||
23301                 error "set default stripe on striped dir error"
23302         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23303         [ $stripe_count -eq $default_count ] ||
23304                 error "expect $default_count get $stripe_count for $dirname"
23305
23306         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23307         [ $stripe_index -eq $default_index ] ||
23308                 error "expect $default_index get $stripe_index for $dirname"
23309
23310         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23311                                                 error "create dirs failed"
23312
23313         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23314         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23315         for dir in $(find $DIR/$tdir/$dirname/*); do
23316                 stripe_count=$($LFS getdirstripe -c $dir)
23317                 (( $stripe_count == $default_count )) ||
23318                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23319                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23320                 error "stripe count $default_count != $stripe_count for $dir"
23321
23322                 stripe_index=$($LFS getdirstripe -i $dir)
23323                 [ $default_index -eq -1 ] ||
23324                         [ $stripe_index -eq $default_index ] ||
23325                         error "$stripe_index != $default_index for $dir"
23326
23327                 #check default stripe
23328                 stripe_count=$($LFS getdirstripe -D -c $dir)
23329                 [ $stripe_count -eq $default_count ] ||
23330                 error "default count $default_count != $stripe_count for $dir"
23331
23332                 stripe_index=$($LFS getdirstripe -D -i $dir)
23333                 [ $stripe_index -eq $default_index ] ||
23334                 error "default index $default_index != $stripe_index for $dir"
23335         done
23336         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23337 }
23338
23339 test_300g() {
23340         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23341         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23342                 skip "Need MDS version at least 2.7.55"
23343
23344         local dir
23345         local stripe_count
23346         local stripe_index
23347
23348         mkdir_on_mdt0 $DIR/$tdir
23349         mkdir $DIR/$tdir/normal_dir
23350
23351         #Checking when client cache stripe index
23352         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23353         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23354                 error "create striped_dir failed"
23355
23356         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23357                 error "create dir0 fails"
23358         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23359         [ $stripe_index -eq 0 ] ||
23360                 error "dir0 expect index 0 got $stripe_index"
23361
23362         mkdir $DIR/$tdir/striped_dir/dir1 ||
23363                 error "create dir1 fails"
23364         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23365         [ $stripe_index -eq 1 ] ||
23366                 error "dir1 expect index 1 got $stripe_index"
23367
23368         #check default stripe count/stripe index
23369         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23370         test_300_check_default_striped_dir normal_dir 1 0
23371         test_300_check_default_striped_dir normal_dir -1 1
23372         test_300_check_default_striped_dir normal_dir 2 -1
23373
23374         #delete default stripe information
23375         echo "delete default stripeEA"
23376         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23377                 error "set default stripe on striped dir error"
23378
23379         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23380         for dir in $(find $DIR/$tdir/normal_dir/*); do
23381                 stripe_count=$($LFS getdirstripe -c $dir)
23382                 [ $stripe_count -eq 0 ] ||
23383                         error "expect 1 get $stripe_count for $dir"
23384         done
23385 }
23386 run_test 300g "check default striped directory for normal directory"
23387
23388 test_300h() {
23389         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23390         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23391                 skip "Need MDS version at least 2.7.55"
23392
23393         local dir
23394         local stripe_count
23395
23396         mkdir $DIR/$tdir
23397         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23398                 error "set striped dir error"
23399
23400         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23401         test_300_check_default_striped_dir striped_dir 1 0
23402         test_300_check_default_striped_dir striped_dir -1 1
23403         test_300_check_default_striped_dir striped_dir 2 -1
23404
23405         #delete default stripe information
23406         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23407                 error "set default stripe on striped dir error"
23408
23409         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23410         for dir in $(find $DIR/$tdir/striped_dir/*); do
23411                 stripe_count=$($LFS getdirstripe -c $dir)
23412                 [ $stripe_count -eq 0 ] ||
23413                         error "expect 1 get $stripe_count for $dir"
23414         done
23415 }
23416 run_test 300h "check default striped directory for striped directory"
23417
23418 test_300i() {
23419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23420         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23421         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23422                 skip "Need MDS version at least 2.7.55"
23423
23424         local stripe_count
23425         local file
23426
23427         mkdir $DIR/$tdir
23428
23429         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23430                 error "set striped dir error"
23431
23432         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23433                 error "create files under striped dir failed"
23434
23435         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23436                 error "set striped hashdir error"
23437
23438         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23439                 error "create dir0 under hash dir failed"
23440         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23441                 error "create dir1 under hash dir failed"
23442         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23443                 error "create dir2 under hash dir failed"
23444
23445         # unfortunately, we need to umount to clear dir layout cache for now
23446         # once we fully implement dir layout, we can drop this
23447         umount_client $MOUNT || error "umount failed"
23448         mount_client $MOUNT || error "mount failed"
23449
23450         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23451         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23452         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23453
23454         #set the stripe to be unknown hash type
23455         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23456         $LCTL set_param fail_loc=0x1901
23457         for ((i = 0; i < 10; i++)); do
23458                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23459                         error "stat f-$i failed"
23460                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23461         done
23462
23463         touch $DIR/$tdir/striped_dir/f0 &&
23464                 error "create under striped dir with unknown hash should fail"
23465
23466         $LCTL set_param fail_loc=0
23467
23468         umount_client $MOUNT || error "umount failed"
23469         mount_client $MOUNT || error "mount failed"
23470
23471         return 0
23472 }
23473 run_test 300i "client handle unknown hash type striped directory"
23474
23475 test_300j() {
23476         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23478         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23479                 skip "Need MDS version at least 2.7.55"
23480
23481         local stripe_count
23482         local file
23483
23484         mkdir $DIR/$tdir
23485
23486         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23487         $LCTL set_param fail_loc=0x1702
23488         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23489                 error "set striped dir error"
23490
23491         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23492                 error "create files under striped dir failed"
23493
23494         $LCTL set_param fail_loc=0
23495
23496         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23497
23498         return 0
23499 }
23500 run_test 300j "test large update record"
23501
23502 test_300k() {
23503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23504         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23505         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23506                 skip "Need MDS version at least 2.7.55"
23507
23508         # this test needs a huge transaction
23509         local kb
23510         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23511              osd*.$FSNAME-MDT0000.kbytestotal")
23512         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23513
23514         local stripe_count
23515         local file
23516
23517         mkdir $DIR/$tdir
23518
23519         #define OBD_FAIL_LARGE_STRIPE   0x1703
23520         $LCTL set_param fail_loc=0x1703
23521         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23522                 error "set striped dir error"
23523         $LCTL set_param fail_loc=0
23524
23525         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23526                 error "getstripeddir fails"
23527         rm -rf $DIR/$tdir/striped_dir ||
23528                 error "unlink striped dir fails"
23529
23530         return 0
23531 }
23532 run_test 300k "test large striped directory"
23533
23534 test_300l() {
23535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23536         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23537         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23538                 skip "Need MDS version at least 2.7.55"
23539
23540         local stripe_index
23541
23542         test_mkdir -p $DIR/$tdir/striped_dir
23543         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23544                         error "chown $RUNAS_ID failed"
23545         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23546                 error "set default striped dir failed"
23547
23548         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23549         $LCTL set_param fail_loc=0x80000158
23550         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23551
23552         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23553         [ $stripe_index -eq 1 ] ||
23554                 error "expect 1 get $stripe_index for $dir"
23555 }
23556 run_test 300l "non-root user to create dir under striped dir with stale layout"
23557
23558 test_300m() {
23559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23560         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23561         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23562                 skip "Need MDS version at least 2.7.55"
23563
23564         mkdir -p $DIR/$tdir/striped_dir
23565         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23566                 error "set default stripes dir error"
23567
23568         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23569
23570         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23571         [ $stripe_count -eq 0 ] ||
23572                         error "expect 0 get $stripe_count for a"
23573
23574         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23575                 error "set default stripes dir error"
23576
23577         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23578
23579         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23580         [ $stripe_count -eq 0 ] ||
23581                         error "expect 0 get $stripe_count for b"
23582
23583         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23584                 error "set default stripes dir error"
23585
23586         mkdir $DIR/$tdir/striped_dir/c &&
23587                 error "default stripe_index is invalid, mkdir c should fails"
23588
23589         rm -rf $DIR/$tdir || error "rmdir fails"
23590 }
23591 run_test 300m "setstriped directory on single MDT FS"
23592
23593 cleanup_300n() {
23594         local list=$(comma_list $(mdts_nodes))
23595
23596         trap 0
23597         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23598 }
23599
23600 test_300n() {
23601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23602         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23603         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23604                 skip "Need MDS version at least 2.7.55"
23605         remote_mds_nodsh && skip "remote MDS with nodsh"
23606
23607         local stripe_index
23608         local list=$(comma_list $(mdts_nodes))
23609
23610         trap cleanup_300n RETURN EXIT
23611         mkdir -p $DIR/$tdir
23612         chmod 777 $DIR/$tdir
23613         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23614                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23615                 error "create striped dir succeeds with gid=0"
23616
23617         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23618         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23619                 error "create striped dir fails with gid=-1"
23620
23621         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23622         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23623                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23624                 error "set default striped dir succeeds with gid=0"
23625
23626
23627         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23628         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23629                 error "set default striped dir fails with gid=-1"
23630
23631
23632         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23633         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23634                                         error "create test_dir fails"
23635         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23636                                         error "create test_dir1 fails"
23637         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23638                                         error "create test_dir2 fails"
23639         cleanup_300n
23640 }
23641 run_test 300n "non-root user to create dir under striped dir with default EA"
23642
23643 test_300o() {
23644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23645         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23646         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23647                 skip "Need MDS version at least 2.7.55"
23648
23649         local numfree1
23650         local numfree2
23651
23652         mkdir -p $DIR/$tdir
23653
23654         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23655         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23656         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23657                 skip "not enough free inodes $numfree1 $numfree2"
23658         fi
23659
23660         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23661         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23662         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23663                 skip "not enough free space $numfree1 $numfree2"
23664         fi
23665
23666         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23667                 error "setdirstripe fails"
23668
23669         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23670                 error "create dirs fails"
23671
23672         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23673         ls $DIR/$tdir/striped_dir > /dev/null ||
23674                 error "ls striped dir fails"
23675         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23676                 error "unlink big striped dir fails"
23677 }
23678 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23679
23680 test_300p() {
23681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23682         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23683         remote_mds_nodsh && skip "remote MDS with nodsh"
23684
23685         mkdir_on_mdt0 $DIR/$tdir
23686
23687         #define OBD_FAIL_OUT_ENOSPC     0x1704
23688         do_facet mds2 lctl set_param fail_loc=0x80001704
23689         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23690                  && error "create striped directory should fail"
23691
23692         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23693
23694         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23695         true
23696 }
23697 run_test 300p "create striped directory without space"
23698
23699 test_300q() {
23700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23701         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23702
23703         local fd=$(free_fd)
23704         local cmd="exec $fd<$tdir"
23705         cd $DIR
23706         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23707         eval $cmd
23708         cmd="exec $fd<&-"
23709         trap "eval $cmd" EXIT
23710         cd $tdir || error "cd $tdir fails"
23711         rmdir  ../$tdir || error "rmdir $tdir fails"
23712         mkdir local_dir && error "create dir succeeds"
23713         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23714         eval $cmd
23715         return 0
23716 }
23717 run_test 300q "create remote directory under orphan directory"
23718
23719 test_300r() {
23720         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23721                 skip "Need MDS version at least 2.7.55" && return
23722         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23723
23724         mkdir $DIR/$tdir
23725
23726         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23727                 error "set striped dir error"
23728
23729         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23730                 error "getstripeddir fails"
23731
23732         local stripe_count
23733         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23734                       awk '/lmv_stripe_count:/ { print $2 }')
23735
23736         [ $MDSCOUNT -ne $stripe_count ] &&
23737                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23738
23739         rm -rf $DIR/$tdir/striped_dir ||
23740                 error "unlink striped dir fails"
23741 }
23742 run_test 300r "test -1 striped directory"
23743
23744 test_300s_helper() {
23745         local count=$1
23746
23747         local stripe_dir=$DIR/$tdir/striped_dir.$count
23748
23749         $LFS mkdir -c $count $stripe_dir ||
23750                 error "lfs mkdir -c error"
23751
23752         $LFS getdirstripe $stripe_dir ||
23753                 error "lfs getdirstripe fails"
23754
23755         local stripe_count
23756         stripe_count=$($LFS getdirstripe $stripe_dir |
23757                       awk '/lmv_stripe_count:/ { print $2 }')
23758
23759         [ $count -ne $stripe_count ] &&
23760                 error_noexit "bad stripe count $stripe_count expected $count"
23761
23762         local dupe_stripes
23763         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23764                 awk '/0x/ {count[$1] += 1}; END {
23765                         for (idx in count) {
23766                                 if (count[idx]>1) {
23767                                         print "index " idx " count " count[idx]
23768                                 }
23769                         }
23770                 }')
23771
23772         if [[ -n "$dupe_stripes" ]] ; then
23773                 lfs getdirstripe $stripe_dir
23774                 error_noexit "Dupe MDT above: $dupe_stripes "
23775         fi
23776
23777         rm -rf $stripe_dir ||
23778                 error_noexit "unlink $stripe_dir fails"
23779 }
23780
23781 test_300s() {
23782         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23783                 skip "Need MDS version at least 2.7.55" && return
23784         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23785
23786         mkdir $DIR/$tdir
23787         for count in $(seq 2 $MDSCOUNT); do
23788                 test_300s_helper $count
23789         done
23790 }
23791 run_test 300s "test lfs mkdir -c without -i"
23792
23793 test_300t() {
23794         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
23795                 skip "need MDS 2.14.55 or later"
23796         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
23797
23798         local testdir="$DIR/$tdir/striped_dir"
23799         local dir1=$testdir/dir1
23800         local dir2=$testdir/dir2
23801
23802         mkdir -p $testdir
23803
23804         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
23805                 error "failed to set default stripe count for $testdir"
23806
23807         mkdir $dir1
23808         local stripe_count=$($LFS getdirstripe -c $dir1)
23809
23810         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
23811
23812         local max_count=$((MDSCOUNT - 1))
23813         local mdts=$(comma_list $(mdts_nodes))
23814
23815         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
23816         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
23817
23818         mkdir $dir2
23819         stripe_count=$($LFS getdirstripe -c $dir2)
23820
23821         (( $stripe_count == $max_count )) || error "wrong stripe count"
23822 }
23823 run_test 300t "test max_mdt_stripecount"
23824
23825 prepare_remote_file() {
23826         mkdir $DIR/$tdir/src_dir ||
23827                 error "create remote source failed"
23828
23829         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23830                  error "cp to remote source failed"
23831         touch $DIR/$tdir/src_dir/a
23832
23833         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23834                 error "create remote target dir failed"
23835
23836         touch $DIR/$tdir/tgt_dir/b
23837
23838         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23839                 error "rename dir cross MDT failed!"
23840
23841         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23842                 error "src_child still exists after rename"
23843
23844         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23845                 error "missing file(a) after rename"
23846
23847         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23848                 error "diff after rename"
23849 }
23850
23851 test_310a() {
23852         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23854
23855         local remote_file=$DIR/$tdir/tgt_dir/b
23856
23857         mkdir -p $DIR/$tdir
23858
23859         prepare_remote_file || error "prepare remote file failed"
23860
23861         #open-unlink file
23862         $OPENUNLINK $remote_file $remote_file ||
23863                 error "openunlink $remote_file failed"
23864         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23865 }
23866 run_test 310a "open unlink remote file"
23867
23868 test_310b() {
23869         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23871
23872         local remote_file=$DIR/$tdir/tgt_dir/b
23873
23874         mkdir -p $DIR/$tdir
23875
23876         prepare_remote_file || error "prepare remote file failed"
23877
23878         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23879         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23880         $CHECKSTAT -t file $remote_file || error "check file failed"
23881 }
23882 run_test 310b "unlink remote file with multiple links while open"
23883
23884 test_310c() {
23885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23886         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23887
23888         local remote_file=$DIR/$tdir/tgt_dir/b
23889
23890         mkdir -p $DIR/$tdir
23891
23892         prepare_remote_file || error "prepare remote file failed"
23893
23894         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23895         multiop_bg_pause $remote_file O_uc ||
23896                         error "mulitop failed for remote file"
23897         MULTIPID=$!
23898         $MULTIOP $DIR/$tfile Ouc
23899         kill -USR1 $MULTIPID
23900         wait $MULTIPID
23901 }
23902 run_test 310c "open-unlink remote file with multiple links"
23903
23904 #LU-4825
23905 test_311() {
23906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23907         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23908         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23909                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23910         remote_mds_nodsh && skip "remote MDS with nodsh"
23911
23912         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23913         local mdts=$(comma_list $(mdts_nodes))
23914
23915         mkdir -p $DIR/$tdir
23916         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23917         createmany -o $DIR/$tdir/$tfile. 1000
23918
23919         # statfs data is not real time, let's just calculate it
23920         old_iused=$((old_iused + 1000))
23921
23922         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23923                         osp.*OST0000*MDT0000.create_count")
23924         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23925                                 osp.*OST0000*MDT0000.max_create_count")
23926         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23927
23928         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23929         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23930         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23931
23932         unlinkmany $DIR/$tdir/$tfile. 1000
23933
23934         do_nodes $mdts "$LCTL set_param -n \
23935                         osp.*OST0000*.max_create_count=$max_count"
23936         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23937                 do_nodes $mdts "$LCTL set_param -n \
23938                                 osp.*OST0000*.create_count=$count"
23939         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23940                         grep "=0" && error "create_count is zero"
23941
23942         local new_iused
23943         for i in $(seq 120); do
23944                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23945                 # system may be too busy to destroy all objs in time, use
23946                 # a somewhat small value to not fail autotest
23947                 [ $((old_iused - new_iused)) -gt 400 ] && break
23948                 sleep 1
23949         done
23950
23951         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23952         [ $((old_iused - new_iused)) -gt 400 ] ||
23953                 error "objs not destroyed after unlink"
23954 }
23955 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23956
23957 zfs_oid_to_objid()
23958 {
23959         local ost=$1
23960         local objid=$2
23961
23962         local vdevdir=$(dirname $(facet_vdevice $ost))
23963         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23964         local zfs_zapid=$(do_facet $ost $cmd |
23965                           grep -w "/O/0/d$((objid%32))" -C 5 |
23966                           awk '/Object/{getline; print $1}')
23967         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23968                           awk "/$objid = /"'{printf $3}')
23969
23970         echo $zfs_objid
23971 }
23972
23973 zfs_object_blksz() {
23974         local ost=$1
23975         local objid=$2
23976
23977         local vdevdir=$(dirname $(facet_vdevice $ost))
23978         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23979         local blksz=$(do_facet $ost $cmd $objid |
23980                       awk '/dblk/{getline; printf $4}')
23981
23982         case "${blksz: -1}" in
23983                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23984                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23985                 *) ;;
23986         esac
23987
23988         echo $blksz
23989 }
23990
23991 test_312() { # LU-4856
23992         remote_ost_nodsh && skip "remote OST with nodsh"
23993         [ "$ost1_FSTYPE" = "zfs" ] ||
23994                 skip_env "the test only applies to zfs"
23995
23996         local max_blksz=$(do_facet ost1 \
23997                           $ZFS get -p recordsize $(facet_device ost1) |
23998                           awk '!/VALUE/{print $3}')
23999
24000         # to make life a little bit easier
24001         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24002         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24003
24004         local tf=$DIR/$tdir/$tfile
24005         touch $tf
24006         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24007
24008         # Get ZFS object id
24009         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24010         # block size change by sequential overwrite
24011         local bs
24012
24013         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24014                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24015
24016                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24017                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24018         done
24019         rm -f $tf
24020
24021         # block size change by sequential append write
24022         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24023         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24024         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24025         local count
24026
24027         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24028                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24029                         oflag=sync conv=notrunc
24030
24031                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24032                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24033                         error "blksz error, actual $blksz, " \
24034                                 "expected: 2 * $count * $PAGE_SIZE"
24035         done
24036         rm -f $tf
24037
24038         # random write
24039         touch $tf
24040         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24041         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24042
24043         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24044         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24045         [ $blksz -eq $PAGE_SIZE ] ||
24046                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24047
24048         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24049         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24050         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24051
24052         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24053         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24054         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24055 }
24056 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24057
24058 test_313() {
24059         remote_ost_nodsh && skip "remote OST with nodsh"
24060
24061         local file=$DIR/$tfile
24062
24063         rm -f $file
24064         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24065
24066         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24067         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24068         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24069                 error "write should failed"
24070         do_facet ost1 "$LCTL set_param fail_loc=0"
24071         rm -f $file
24072 }
24073 run_test 313 "io should fail after last_rcvd update fail"
24074
24075 test_314() {
24076         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24077
24078         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24079         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24080         rm -f $DIR/$tfile
24081         wait_delete_completed
24082         do_facet ost1 "$LCTL set_param fail_loc=0"
24083 }
24084 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24085
24086 test_315() { # LU-618
24087         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24088
24089         local file=$DIR/$tfile
24090         rm -f $file
24091
24092         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24093                 error "multiop file write failed"
24094         $MULTIOP $file oO_RDONLY:r4063232_c &
24095         PID=$!
24096
24097         sleep 2
24098
24099         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24100         kill -USR1 $PID
24101
24102         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24103         rm -f $file
24104 }
24105 run_test 315 "read should be accounted"
24106
24107 test_316() {
24108         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24109         large_xattr_enabled || skip_env "ea_inode feature disabled"
24110
24111         rm -rf $DIR/$tdir/d
24112         mkdir -p $DIR/$tdir/d
24113         chown nobody $DIR/$tdir/d
24114         touch $DIR/$tdir/d/file
24115
24116         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
24117 }
24118 run_test 316 "lfs mv"
24119
24120 test_317() {
24121         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24122                 skip "Need MDS version at least 2.11.53"
24123         if [ "$ost1_FSTYPE" == "zfs" ]; then
24124                 skip "LU-10370: no implementation for ZFS"
24125         fi
24126
24127         local trunc_sz
24128         local grant_blk_size
24129
24130         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24131                         awk '/grant_block_size:/ { print $2; exit; }')
24132         #
24133         # Create File of size 5M. Truncate it to below size's and verify
24134         # blocks count.
24135         #
24136         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24137                 error "Create file $DIR/$tfile failed"
24138         stack_trap "rm -f $DIR/$tfile" EXIT
24139
24140         for trunc_sz in 2097152 4097 4000 509 0; do
24141                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24142                         error "truncate $tfile to $trunc_sz failed"
24143                 local sz=$(stat --format=%s $DIR/$tfile)
24144                 local blk=$(stat --format=%b $DIR/$tfile)
24145                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24146                                      grant_blk_size) * 8))
24147
24148                 if [[ $blk -ne $trunc_blk ]]; then
24149                         $(which stat) $DIR/$tfile
24150                         error "Expected Block $trunc_blk got $blk for $tfile"
24151                 fi
24152
24153                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24154                         error "Expected Size $trunc_sz got $sz for $tfile"
24155         done
24156
24157         #
24158         # sparse file test
24159         # Create file with a hole and write actual 65536 bytes which aligned
24160         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24161         #
24162         local bs=65536
24163         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24164                 error "Create file : $DIR/$tfile"
24165
24166         #
24167         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24168         # blocks. The block count must drop to 8.
24169         #
24170         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - \
24171                 ((bs - grant_blk_size) + 1)))
24172         $TRUNCATE $DIR/$tfile $trunc_sz ||
24173                 error "truncate $tfile to $trunc_sz failed"
24174
24175         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24176         sz=$(stat --format=%s $DIR/$tfile)
24177         blk=$(stat --format=%b $DIR/$tfile)
24178
24179         if [[ $blk -ne $trunc_bsz ]]; then
24180                 $(which stat) $DIR/$tfile
24181                 error "Expected Block $trunc_bsz got $blk for $tfile"
24182         fi
24183
24184         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24185                 error "Expected Size $trunc_sz got $sz for $tfile"
24186 }
24187 run_test 317 "Verify blocks get correctly update after truncate"
24188
24189 test_318() {
24190         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24191         local old_max_active=$($LCTL get_param -n \
24192                             ${llite_name}.max_read_ahead_async_active \
24193                             2>/dev/null)
24194
24195         $LCTL set_param llite.*.max_read_ahead_async_active=256
24196         local max_active=$($LCTL get_param -n \
24197                            ${llite_name}.max_read_ahead_async_active \
24198                            2>/dev/null)
24199         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24200
24201         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24202                 error "set max_read_ahead_async_active should succeed"
24203
24204         $LCTL set_param llite.*.max_read_ahead_async_active=512
24205         max_active=$($LCTL get_param -n \
24206                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24207         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24208
24209         # restore @max_active
24210         [ $old_max_active -ne 0 ] && $LCTL set_param \
24211                 llite.*.max_read_ahead_async_active=$old_max_active
24212
24213         local old_threshold=$($LCTL get_param -n \
24214                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24215         local max_per_file_mb=$($LCTL get_param -n \
24216                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24217
24218         local invalid=$(($max_per_file_mb + 1))
24219         $LCTL set_param \
24220                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24221                         && error "set $invalid should fail"
24222
24223         local valid=$(($invalid - 1))
24224         $LCTL set_param \
24225                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24226                         error "set $valid should succeed"
24227         local threshold=$($LCTL get_param -n \
24228                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24229         [ $threshold -eq $valid ] || error \
24230                 "expect threshold $valid got $threshold"
24231         $LCTL set_param \
24232                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24233 }
24234 run_test 318 "Verify async readahead tunables"
24235
24236 test_319() {
24237         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
24238
24239         local before=$(date +%s)
24240         local evict
24241         local mdir=$DIR/$tdir
24242         local file=$mdir/xxx
24243
24244         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24245         touch $file
24246
24247 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24248         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24249         $LFS mv -m1 $file &
24250
24251         sleep 1
24252         dd if=$file of=/dev/null
24253         wait
24254         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24255           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24256
24257         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24258 }
24259 run_test 319 "lost lease lock on migrate error"
24260
24261 test_398a() { # LU-4198
24262         local ost1_imp=$(get_osc_import_name client ost1)
24263         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24264                          cut -d'.' -f2)
24265
24266         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24267         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24268
24269         # request a new lock on client
24270         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24271
24272         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24273         local lock_count=$($LCTL get_param -n \
24274                            ldlm.namespaces.$imp_name.lru_size)
24275         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24276
24277         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24278
24279         # no lock cached, should use lockless IO and not enqueue new lock
24280         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24281         lock_count=$($LCTL get_param -n \
24282                      ldlm.namespaces.$imp_name.lru_size)
24283         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24284 }
24285 run_test 398a "direct IO should cancel lock otherwise lockless"
24286
24287 test_398b() { # LU-4198
24288         which fio || skip_env "no fio installed"
24289         $LFS setstripe -c -1 $DIR/$tfile
24290
24291         local size=12
24292         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24293
24294         local njobs=4
24295         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
24296         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24297                 --numjobs=$njobs --fallocate=none \
24298                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24299                 --filename=$DIR/$tfile &
24300         bg_pid=$!
24301
24302         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
24303         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
24304                 --numjobs=$njobs --fallocate=none \
24305                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24306                 --filename=$DIR/$tfile || true
24307         wait $bg_pid
24308
24309         rm -f $DIR/$tfile
24310 }
24311 run_test 398b "DIO and buffer IO race"
24312
24313 test_398c() { # LU-4198
24314         local ost1_imp=$(get_osc_import_name client ost1)
24315         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24316                          cut -d'.' -f2)
24317
24318         which fio || skip_env "no fio installed"
24319
24320         saved_debug=$($LCTL get_param -n debug)
24321         $LCTL set_param debug=0
24322
24323         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24324         ((size /= 1024)) # by megabytes
24325         ((size /= 2)) # write half of the OST at most
24326         [ $size -gt 40 ] && size=40 #reduce test time anyway
24327
24328         $LFS setstripe -c 1 $DIR/$tfile
24329
24330         # it seems like ldiskfs reserves more space than necessary if the
24331         # writing blocks are not mapped, so it extends the file firstly
24332         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24333         cancel_lru_locks osc
24334
24335         # clear and verify rpc_stats later
24336         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24337
24338         local njobs=4
24339         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24340         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24341                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24342                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24343                 --filename=$DIR/$tfile
24344         [ $? -eq 0 ] || error "fio write error"
24345
24346         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24347                 error "Locks were requested while doing AIO"
24348
24349         # get the percentage of 1-page I/O
24350         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24351                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24352                 awk '{print $7}')
24353         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24354
24355         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24356         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24357                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24358                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24359                 --filename=$DIR/$tfile
24360         [ $? -eq 0 ] || error "fio mixed read write error"
24361
24362         echo "AIO with large block size ${size}M"
24363         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24364                 --numjobs=1 --fallocate=none --ioengine=libaio \
24365                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24366                 --filename=$DIR/$tfile
24367         [ $? -eq 0 ] || error "fio large block size failed"
24368
24369         rm -f $DIR/$tfile
24370         $LCTL set_param debug="$saved_debug"
24371 }
24372 run_test 398c "run fio to test AIO"
24373
24374 test_398d() { #  LU-13846
24375         which aiocp || skip_env "no aiocp installed"
24376         local aio_file=$DIR/$tfile.aio
24377
24378         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24379
24380         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24381         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24382         stack_trap "rm -f $DIR/$tfile $aio_file"
24383
24384         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24385
24386         # make sure we don't crash and fail properly
24387         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24388                 error "aio not aligned with PAGE SIZE should fail"
24389
24390         rm -f $DIR/$tfile $aio_file
24391 }
24392 run_test 398d "run aiocp to verify block size > stripe size"
24393
24394 test_398e() {
24395         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24396         touch $DIR/$tfile.new
24397         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24398 }
24399 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24400
24401 test_398f() { #  LU-14687
24402         which aiocp || skip_env "no aiocp installed"
24403         local aio_file=$DIR/$tfile.aio
24404
24405         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24406
24407         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24408         stack_trap "rm -f $DIR/$tfile $aio_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         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24414                 error "aio with page allocation failure succeeded"
24415         $LCTL set_param fail_loc=0
24416         diff $DIR/$tfile $aio_file
24417         [[ $? != 0 ]] || error "no diff after failed aiocp"
24418 }
24419 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24420
24421 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24422 # stripe and i/o size must be > stripe size
24423 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24424 # single RPC in flight.  This test shows async DIO submission is working by
24425 # showing multiple RPCs in flight.
24426 test_398g() { #  LU-13798
24427         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24428
24429         # We need to do some i/o first to acquire enough grant to put our RPCs
24430         # in flight; otherwise a new connection may not have enough grant
24431         # available
24432         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24433                 error "parallel dio failed"
24434         stack_trap "rm -f $DIR/$tfile"
24435
24436         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24437         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24438         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24439         stack_trap "$LCTL set_param -n $pages_per_rpc"
24440
24441         # Recreate file so it's empty
24442         rm -f $DIR/$tfile
24443         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24444         #Pause rpc completion to guarantee we see multiple rpcs in flight
24445         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24446         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24447         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24448
24449         # Clear rpc stats
24450         $LCTL set_param osc.*.rpc_stats=c
24451
24452         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24453                 error "parallel dio failed"
24454         stack_trap "rm -f $DIR/$tfile"
24455
24456         $LCTL get_param osc.*-OST0000-*.rpc_stats
24457         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24458                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24459                 grep "8:" | awk '{print $8}')
24460         # We look at the "8 rpcs in flight" field, and verify A) it is present
24461         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24462         # as expected for an 8M DIO to a file with 1M stripes.
24463         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24464
24465         # Verify turning off parallel dio works as expected
24466         # Clear rpc stats
24467         $LCTL set_param osc.*.rpc_stats=c
24468         $LCTL set_param llite.*.parallel_dio=0
24469         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24470
24471         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24472                 error "dio with parallel dio disabled failed"
24473
24474         # Ideally, we would see only one RPC in flight here, but there is an
24475         # unavoidable race between i/o completion and RPC in flight counting,
24476         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24477         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24478         # So instead we just verify it's always < 8.
24479         $LCTL get_param osc.*-OST0000-*.rpc_stats
24480         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24481                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24482                 grep '^$' -B1 | grep . | awk '{print $1}')
24483         [ $ret != "8:" ] ||
24484                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24485 }
24486 run_test 398g "verify parallel dio async RPC submission"
24487
24488 test_398h() { #  LU-13798
24489         local dio_file=$DIR/$tfile.dio
24490
24491         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24492
24493         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24494         stack_trap "rm -f $DIR/$tfile $dio_file"
24495
24496         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24497                 error "parallel dio failed"
24498         diff $DIR/$tfile $dio_file
24499         [[ $? == 0 ]] || error "file diff after aiocp"
24500 }
24501 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24502
24503 test_398i() { #  LU-13798
24504         local dio_file=$DIR/$tfile.dio
24505
24506         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24507
24508         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24509         stack_trap "rm -f $DIR/$tfile $dio_file"
24510
24511         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24512         $LCTL set_param fail_loc=0x1418
24513         # make sure we don't crash and fail properly
24514         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24515                 error "parallel dio page allocation failure succeeded"
24516         diff $DIR/$tfile $dio_file
24517         [[ $? != 0 ]] || error "no diff after failed aiocp"
24518 }
24519 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24520
24521 test_398j() { #  LU-13798
24522         # Stripe size > RPC size but less than i/o size tests split across
24523         # stripes and RPCs for individual i/o op
24524         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24525
24526         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24527         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24528         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24529         stack_trap "$LCTL set_param -n $pages_per_rpc"
24530
24531         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24532                 error "parallel dio write failed"
24533         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24534
24535         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24536                 error "parallel dio read failed"
24537         diff $DIR/$tfile $DIR/$tfile.2
24538         [[ $? == 0 ]] || error "file diff after parallel dio read"
24539 }
24540 run_test 398j "test parallel dio where stripe size > rpc_size"
24541
24542 test_398k() { #  LU-13798
24543         wait_delete_completed
24544         wait_mds_ost_sync
24545
24546         # 4 stripe file; we will cause out of space on OST0
24547         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24548
24549         # Fill OST0 (if it's not too large)
24550         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24551                    head -n1)
24552         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24553                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24554         fi
24555         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24556         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24557                 error "dd should fill OST0"
24558         stack_trap "rm -f $DIR/$tfile.1"
24559
24560         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24561         err=$?
24562
24563         ls -la $DIR/$tfile
24564         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24565                 error "file is not 0 bytes in size"
24566
24567         # dd above should not succeed, but don't error until here so we can
24568         # get debug info above
24569         [[ $err != 0 ]] ||
24570                 error "parallel dio write with enospc succeeded"
24571         stack_trap "rm -f $DIR/$tfile"
24572 }
24573 run_test 398k "test enospc on first stripe"
24574
24575 test_398l() { #  LU-13798
24576         wait_delete_completed
24577         wait_mds_ost_sync
24578
24579         # 4 stripe file; we will cause out of space on OST0
24580         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24581         # happens on the second i/o chunk we issue
24582         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24583
24584         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24585         stack_trap "rm -f $DIR/$tfile"
24586
24587         # Fill OST0 (if it's not too large)
24588         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24589                    head -n1)
24590         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24591                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24592         fi
24593         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24594         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24595                 error "dd should fill OST0"
24596         stack_trap "rm -f $DIR/$tfile.1"
24597
24598         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24599         err=$?
24600         stack_trap "rm -f $DIR/$tfile.2"
24601
24602         # Check that short write completed as expected
24603         ls -la $DIR/$tfile.2
24604         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24605                 error "file is not 1M in size"
24606
24607         # dd above should not succeed, but don't error until here so we can
24608         # get debug info above
24609         [[ $err != 0 ]] ||
24610                 error "parallel dio write with enospc succeeded"
24611
24612         # Truncate source file to same length as output file and diff them
24613         $TRUNCATE $DIR/$tfile 1048576
24614         diff $DIR/$tfile $DIR/$tfile.2
24615         [[ $? == 0 ]] || error "data incorrect after short write"
24616 }
24617 run_test 398l "test enospc on intermediate stripe/RPC"
24618
24619 test_398m() { #  LU-13798
24620         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24621
24622         # Set up failure on OST0, the first stripe:
24623         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24624         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24625         # So this fail_val specifies OST0
24626         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24627         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24628
24629         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24630                 error "parallel dio write with failure on first stripe succeeded"
24631         stack_trap "rm -f $DIR/$tfile"
24632         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24633
24634         # Place data in file for read
24635         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24636                 error "parallel dio write failed"
24637
24638         # Fail read on OST0, first stripe
24639         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24640         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24641         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24642                 error "parallel dio read with error on first stripe succeeded"
24643         rm -f $DIR/$tfile.2
24644         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24645
24646         # Switch to testing on OST1, second stripe
24647         # Clear file contents, maintain striping
24648         echo > $DIR/$tfile
24649         # Set up failure on OST1, second stripe:
24650         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24651         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24652
24653         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24654                 error "parallel dio write with failure on first stripe succeeded"
24655         stack_trap "rm -f $DIR/$tfile"
24656         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24657
24658         # Place data in file for read
24659         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24660                 error "parallel dio write failed"
24661
24662         # Fail read on OST1, second stripe
24663         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24664         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24665         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24666                 error "parallel dio read with error on first stripe succeeded"
24667         rm -f $DIR/$tfile.2
24668         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24669 }
24670 run_test 398m "test RPC failures with parallel dio"
24671
24672 # Parallel submission of DIO should not cause problems for append, but it's
24673 # important to verify.
24674 test_398n() { #  LU-13798
24675         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24676
24677         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24678                 error "dd to create source file failed"
24679         stack_trap "rm -f $DIR/$tfile"
24680
24681         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24682                 error "parallel dio write with failure on second stripe succeeded"
24683         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24684         diff $DIR/$tfile $DIR/$tfile.1
24685         [[ $? == 0 ]] || error "data incorrect after append"
24686
24687 }
24688 run_test 398n "test append with parallel DIO"
24689
24690 test_fake_rw() {
24691         local read_write=$1
24692         if [ "$read_write" = "write" ]; then
24693                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24694         elif [ "$read_write" = "read" ]; then
24695                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24696         else
24697                 error "argument error"
24698         fi
24699
24700         # turn off debug for performance testing
24701         local saved_debug=$($LCTL get_param -n debug)
24702         $LCTL set_param debug=0
24703
24704         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24705
24706         # get ost1 size - $FSNAME-OST0000
24707         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24708         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24709         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24710
24711         if [ "$read_write" = "read" ]; then
24712                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24713         fi
24714
24715         local start_time=$(date +%s.%N)
24716         $dd_cmd bs=1M count=$blocks oflag=sync ||
24717                 error "real dd $read_write error"
24718         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24719
24720         if [ "$read_write" = "write" ]; then
24721                 rm -f $DIR/$tfile
24722         fi
24723
24724         # define OBD_FAIL_OST_FAKE_RW           0x238
24725         do_facet ost1 $LCTL set_param fail_loc=0x238
24726
24727         local start_time=$(date +%s.%N)
24728         $dd_cmd bs=1M count=$blocks oflag=sync ||
24729                 error "fake dd $read_write error"
24730         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24731
24732         if [ "$read_write" = "write" ]; then
24733                 # verify file size
24734                 cancel_lru_locks osc
24735                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24736                         error "$tfile size not $blocks MB"
24737         fi
24738         do_facet ost1 $LCTL set_param fail_loc=0
24739
24740         echo "fake $read_write $duration_fake vs. normal $read_write" \
24741                 "$duration in seconds"
24742         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24743                 error_not_in_vm "fake write is slower"
24744
24745         $LCTL set_param -n debug="$saved_debug"
24746         rm -f $DIR/$tfile
24747 }
24748 test_399a() { # LU-7655 for OST fake write
24749         remote_ost_nodsh && skip "remote OST with nodsh"
24750
24751         test_fake_rw write
24752 }
24753 run_test 399a "fake write should not be slower than normal write"
24754
24755 test_399b() { # LU-8726 for OST fake read
24756         remote_ost_nodsh && skip "remote OST with nodsh"
24757         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24758                 skip_env "ldiskfs only test"
24759         fi
24760
24761         test_fake_rw read
24762 }
24763 run_test 399b "fake read should not be slower than normal read"
24764
24765 test_400a() { # LU-1606, was conf-sanity test_74
24766         if ! which $CC > /dev/null 2>&1; then
24767                 skip_env "$CC is not installed"
24768         fi
24769
24770         local extra_flags=''
24771         local out=$TMP/$tfile
24772         local prefix=/usr/include/lustre
24773         local prog
24774
24775         # Oleg removes c files in his test rig so test if any c files exist
24776         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24777                 skip_env "Needed c test files are missing"
24778
24779         if ! [[ -d $prefix ]]; then
24780                 # Assume we're running in tree and fixup the include path.
24781                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24782                 extra_flags+=" -L$LUSTRE/utils/.lib"
24783         fi
24784
24785         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24786                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24787                         error "client api broken"
24788         done
24789         rm -f $out
24790 }
24791 run_test 400a "Lustre client api program can compile and link"
24792
24793 test_400b() { # LU-1606, LU-5011
24794         local header
24795         local out=$TMP/$tfile
24796         local prefix=/usr/include/linux/lustre
24797
24798         # We use a hard coded prefix so that this test will not fail
24799         # when run in tree. There are headers in lustre/include/lustre/
24800         # that are not packaged (like lustre_idl.h) and have more
24801         # complicated include dependencies (like config.h and lnet/types.h).
24802         # Since this test about correct packaging we just skip them when
24803         # they don't exist (see below) rather than try to fixup cppflags.
24804
24805         if ! which $CC > /dev/null 2>&1; then
24806                 skip_env "$CC is not installed"
24807         fi
24808
24809         for header in $prefix/*.h; do
24810                 if ! [[ -f "$header" ]]; then
24811                         continue
24812                 fi
24813
24814                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24815                         continue # lustre_ioctl.h is internal header
24816                 fi
24817
24818                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24819                         error "cannot compile '$header'"
24820         done
24821         rm -f $out
24822 }
24823 run_test 400b "packaged headers can be compiled"
24824
24825 test_401a() { #LU-7437
24826         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24827         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24828
24829         #count the number of parameters by "list_param -R"
24830         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24831         #count the number of parameters by listing proc files
24832         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24833         echo "proc_dirs='$proc_dirs'"
24834         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24835         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24836                       sort -u | wc -l)
24837
24838         [ $params -eq $procs ] ||
24839                 error "found $params parameters vs. $procs proc files"
24840
24841         # test the list_param -D option only returns directories
24842         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24843         #count the number of parameters by listing proc directories
24844         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24845                 sort -u | wc -l)
24846
24847         [ $params -eq $procs ] ||
24848                 error "found $params parameters vs. $procs proc files"
24849 }
24850 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24851
24852 test_401b() {
24853         # jobid_var may not allow arbitrary values, so use jobid_name
24854         # if available
24855         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24856                 local testname=jobid_name tmp='testing%p'
24857         else
24858                 local testname=jobid_var tmp=testing
24859         fi
24860
24861         local save=$($LCTL get_param -n $testname)
24862
24863         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24864                 error "no error returned when setting bad parameters"
24865
24866         local jobid_new=$($LCTL get_param -n foe $testname baz)
24867         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24868
24869         $LCTL set_param -n fog=bam $testname=$save bat=fog
24870         local jobid_old=$($LCTL get_param -n foe $testname bag)
24871         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24872 }
24873 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24874
24875 test_401c() {
24876         # jobid_var may not allow arbitrary values, so use jobid_name
24877         # if available
24878         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24879                 local testname=jobid_name
24880         else
24881                 local testname=jobid_var
24882         fi
24883
24884         local jobid_var_old=$($LCTL get_param -n $testname)
24885         local jobid_var_new
24886
24887         $LCTL set_param $testname= &&
24888                 error "no error returned for 'set_param a='"
24889
24890         jobid_var_new=$($LCTL get_param -n $testname)
24891         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24892                 error "$testname was changed by setting without value"
24893
24894         $LCTL set_param $testname &&
24895                 error "no error returned for 'set_param a'"
24896
24897         jobid_var_new=$($LCTL get_param -n $testname)
24898         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24899                 error "$testname was changed by setting without value"
24900 }
24901 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24902
24903 test_401d() {
24904         # jobid_var may not allow arbitrary values, so use jobid_name
24905         # if available
24906         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24907                 local testname=jobid_name new_value='foo=bar%p'
24908         else
24909                 local testname=jobid_var new_valuie=foo=bar
24910         fi
24911
24912         local jobid_var_old=$($LCTL get_param -n $testname)
24913         local jobid_var_new
24914
24915         $LCTL set_param $testname=$new_value ||
24916                 error "'set_param a=b' did not accept a value containing '='"
24917
24918         jobid_var_new=$($LCTL get_param -n $testname)
24919         [[ "$jobid_var_new" == "$new_value" ]] ||
24920                 error "'set_param a=b' failed on a value containing '='"
24921
24922         # Reset the $testname to test the other format
24923         $LCTL set_param $testname=$jobid_var_old
24924         jobid_var_new=$($LCTL get_param -n $testname)
24925         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24926                 error "failed to reset $testname"
24927
24928         $LCTL set_param $testname $new_value ||
24929                 error "'set_param a b' did not accept a value containing '='"
24930
24931         jobid_var_new=$($LCTL get_param -n $testname)
24932         [[ "$jobid_var_new" == "$new_value" ]] ||
24933                 error "'set_param a b' failed on a value containing '='"
24934
24935         $LCTL set_param $testname $jobid_var_old
24936         jobid_var_new=$($LCTL get_param -n $testname)
24937         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24938                 error "failed to reset $testname"
24939 }
24940 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24941
24942 test_401e() { # LU-14779
24943         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24944                 error "lctl list_param MGC* failed"
24945         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24946         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24947                 error "lctl get_param lru_size failed"
24948 }
24949 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24950
24951 test_402() {
24952         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24953         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24954                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24955         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24956                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24957                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24958         remote_mds_nodsh && skip "remote MDS with nodsh"
24959
24960         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24961 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24962         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24963         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24964                 echo "Touch failed - OK"
24965 }
24966 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24967
24968 test_403() {
24969         local file1=$DIR/$tfile.1
24970         local file2=$DIR/$tfile.2
24971         local tfile=$TMP/$tfile
24972
24973         rm -f $file1 $file2 $tfile
24974
24975         touch $file1
24976         ln $file1 $file2
24977
24978         # 30 sec OBD_TIMEOUT in ll_getattr()
24979         # right before populating st_nlink
24980         $LCTL set_param fail_loc=0x80001409
24981         stat -c %h $file1 > $tfile &
24982
24983         # create an alias, drop all locks and reclaim the dentry
24984         < $file2
24985         cancel_lru_locks mdc
24986         cancel_lru_locks osc
24987         sysctl -w vm.drop_caches=2
24988
24989         wait
24990
24991         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24992
24993         rm -f $tfile $file1 $file2
24994 }
24995 run_test 403 "i_nlink should not drop to zero due to aliasing"
24996
24997 test_404() { # LU-6601
24998         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24999                 skip "Need server version newer than 2.8.52"
25000         remote_mds_nodsh && skip "remote MDS with nodsh"
25001
25002         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25003                 awk '/osp .*-osc-MDT/ { print $4}')
25004
25005         local osp
25006         for osp in $mosps; do
25007                 echo "Deactivate: " $osp
25008                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25009                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25010                         awk -vp=$osp '$4 == p { print $2 }')
25011                 [ $stat = IN ] || {
25012                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25013                         error "deactivate error"
25014                 }
25015                 echo "Activate: " $osp
25016                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25017                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25018                         awk -vp=$osp '$4 == p { print $2 }')
25019                 [ $stat = UP ] || {
25020                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25021                         error "activate error"
25022                 }
25023         done
25024 }
25025 run_test 404 "validate manual {de}activated works properly for OSPs"
25026
25027 test_405() {
25028         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25029         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25030                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25031                         skip "Layout swap lock is not supported"
25032
25033         check_swap_layouts_support
25034         check_swap_layout_no_dom $DIR
25035
25036         test_mkdir $DIR/$tdir
25037         swap_lock_test -d $DIR/$tdir ||
25038                 error "One layout swap locked test failed"
25039 }
25040 run_test 405 "Various layout swap lock tests"
25041
25042 test_406() {
25043         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25044         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25045         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25047         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25048                 skip "Need MDS version at least 2.8.50"
25049
25050         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25051         local test_pool=$TESTNAME
25052
25053         pool_add $test_pool || error "pool_add failed"
25054         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25055                 error "pool_add_targets failed"
25056
25057         save_layout_restore_at_exit $MOUNT
25058
25059         # parent set default stripe count only, child will stripe from both
25060         # parent and fs default
25061         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25062                 error "setstripe $MOUNT failed"
25063         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25064         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25065         for i in $(seq 10); do
25066                 local f=$DIR/$tdir/$tfile.$i
25067                 touch $f || error "touch failed"
25068                 local count=$($LFS getstripe -c $f)
25069                 [ $count -eq $OSTCOUNT ] ||
25070                         error "$f stripe count $count != $OSTCOUNT"
25071                 local offset=$($LFS getstripe -i $f)
25072                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25073                 local size=$($LFS getstripe -S $f)
25074                 [ $size -eq $((def_stripe_size * 2)) ] ||
25075                         error "$f stripe size $size != $((def_stripe_size * 2))"
25076                 local pool=$($LFS getstripe -p $f)
25077                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25078         done
25079
25080         # change fs default striping, delete parent default striping, now child
25081         # will stripe from new fs default striping only
25082         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25083                 error "change $MOUNT default stripe failed"
25084         $LFS setstripe -c 0 $DIR/$tdir ||
25085                 error "delete $tdir default stripe failed"
25086         for i in $(seq 11 20); do
25087                 local f=$DIR/$tdir/$tfile.$i
25088                 touch $f || error "touch $f failed"
25089                 local count=$($LFS getstripe -c $f)
25090                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25091                 local offset=$($LFS getstripe -i $f)
25092                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25093                 local size=$($LFS getstripe -S $f)
25094                 [ $size -eq $def_stripe_size ] ||
25095                         error "$f stripe size $size != $def_stripe_size"
25096                 local pool=$($LFS getstripe -p $f)
25097                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25098         done
25099
25100         unlinkmany $DIR/$tdir/$tfile. 1 20
25101
25102         local f=$DIR/$tdir/$tfile
25103         pool_remove_all_targets $test_pool $f
25104         pool_remove $test_pool $f
25105 }
25106 run_test 406 "DNE support fs default striping"
25107
25108 test_407() {
25109         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25110         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25111                 skip "Need MDS version at least 2.8.55"
25112         remote_mds_nodsh && skip "remote MDS with nodsh"
25113
25114         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25115                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25116         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25117                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25118         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25119
25120         #define OBD_FAIL_DT_TXN_STOP    0x2019
25121         for idx in $(seq $MDSCOUNT); do
25122                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25123         done
25124         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25125         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25126                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25127         true
25128 }
25129 run_test 407 "transaction fail should cause operation fail"
25130
25131 test_408() {
25132         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25133
25134         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25135         lctl set_param fail_loc=0x8000040a
25136         # let ll_prepare_partial_page() fail
25137         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25138
25139         rm -f $DIR/$tfile
25140
25141         # create at least 100 unused inodes so that
25142         # shrink_icache_memory(0) should not return 0
25143         touch $DIR/$tfile-{0..100}
25144         rm -f $DIR/$tfile-{0..100}
25145         sync
25146
25147         echo 2 > /proc/sys/vm/drop_caches
25148 }
25149 run_test 408 "drop_caches should not hang due to page leaks"
25150
25151 test_409()
25152 {
25153         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25154
25155         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25156         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25157         touch $DIR/$tdir/guard || error "(2) Fail to create"
25158
25159         local PREFIX=$(str_repeat 'A' 128)
25160         echo "Create 1K hard links start at $(date)"
25161         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25162                 error "(3) Fail to hard link"
25163
25164         echo "Links count should be right although linkEA overflow"
25165         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25166         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25167         [ $linkcount -eq 1001 ] ||
25168                 error "(5) Unexpected hard links count: $linkcount"
25169
25170         echo "List all links start at $(date)"
25171         ls -l $DIR/$tdir/foo > /dev/null ||
25172                 error "(6) Fail to list $DIR/$tdir/foo"
25173
25174         echo "Unlink hard links start at $(date)"
25175         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25176                 error "(7) Fail to unlink"
25177         echo "Unlink hard links finished at $(date)"
25178 }
25179 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25180
25181 test_410()
25182 {
25183         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25184                 skip "Need client version at least 2.9.59"
25185         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25186                 skip "Need MODULES build"
25187
25188         # Create a file, and stat it from the kernel
25189         local testfile=$DIR/$tfile
25190         touch $testfile
25191
25192         local run_id=$RANDOM
25193         local my_ino=$(stat --format "%i" $testfile)
25194
25195         # Try to insert the module. This will always fail as the
25196         # module is designed to not be inserted.
25197         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25198             &> /dev/null
25199
25200         # Anything but success is a test failure
25201         dmesg | grep -q \
25202             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25203             error "no inode match"
25204 }
25205 run_test 410 "Test inode number returned from kernel thread"
25206
25207 cleanup_test411_cgroup() {
25208         trap 0
25209         rmdir "$1"
25210 }
25211
25212 test_411() {
25213         local cg_basedir=/sys/fs/cgroup/memory
25214         # LU-9966
25215         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25216                 skip "no setup for cgroup"
25217
25218         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25219                 error "test file creation failed"
25220         cancel_lru_locks osc
25221
25222         # Create a very small memory cgroup to force a slab allocation error
25223         local cgdir=$cg_basedir/osc_slab_alloc
25224         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25225         trap "cleanup_test411_cgroup $cgdir" EXIT
25226         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25227         echo 1M > $cgdir/memory.limit_in_bytes
25228
25229         # Should not LBUG, just be killed by oom-killer
25230         # dd will return 0 even allocation failure in some environment.
25231         # So don't check return value
25232         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25233         cleanup_test411_cgroup $cgdir
25234
25235         return 0
25236 }
25237 run_test 411 "Slab allocation error with cgroup does not LBUG"
25238
25239 test_412() {
25240         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25241         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25242                 skip "Need server version at least 2.10.55"
25243
25244         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25245                 error "mkdir failed"
25246         $LFS getdirstripe $DIR/$tdir
25247         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25248         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25249                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25250         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25251         [ $stripe_count -eq 2 ] ||
25252                 error "expect 2 get $stripe_count"
25253
25254         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25255
25256         local index
25257         local index2
25258
25259         # subdirs should be on the same MDT as parent
25260         for i in $(seq 0 $((MDSCOUNT - 1))); do
25261                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25262                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25263                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25264                 (( index == i )) || error "mdt$i/sub on MDT$index"
25265         done
25266
25267         # stripe offset -1, ditto
25268         for i in {1..10}; do
25269                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25270                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25271                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25272                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25273                 (( index == index2 )) ||
25274                         error "qos$i on MDT$index, sub on MDT$index2"
25275         done
25276
25277         local testdir=$DIR/$tdir/inherit
25278
25279         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25280         # inherit 2 levels
25281         for i in 1 2; do
25282                 testdir=$testdir/s$i
25283                 mkdir $testdir || error "mkdir $testdir failed"
25284                 index=$($LFS getstripe -m $testdir)
25285                 (( index == 1 )) ||
25286                         error "$testdir on MDT$index"
25287         done
25288
25289         # not inherit any more
25290         testdir=$testdir/s3
25291         mkdir $testdir || error "mkdir $testdir failed"
25292         getfattr -d -m dmv $testdir | grep dmv &&
25293                 error "default LMV set on $testdir" || true
25294 }
25295 run_test 412 "mkdir on specific MDTs"
25296
25297 generate_uneven_mdts() {
25298         local threshold=$1
25299         local lmv_qos_maxage
25300         local lod_qos_maxage
25301         local ffree
25302         local bavail
25303         local max
25304         local min
25305         local max_index
25306         local min_index
25307         local tmp
25308         local i
25309
25310         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25311         $LCTL set_param lmv.*.qos_maxage=1
25312         stack_trap "$LCTL set_param \
25313                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25314         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25315                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25316         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25317                 lod.*.mdt_qos_maxage=1
25318         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25319                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25320
25321         echo
25322         echo "Check for uneven MDTs: "
25323
25324         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25325         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25326         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25327
25328         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25329         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25330         max_index=0
25331         min_index=0
25332         for ((i = 1; i < ${#ffree[@]}; i++)); do
25333                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25334                 if [ $tmp -gt $max ]; then
25335                         max=$tmp
25336                         max_index=$i
25337                 fi
25338                 if [ $tmp -lt $min ]; then
25339                         min=$tmp
25340                         min_index=$i
25341                 fi
25342         done
25343
25344         (( ${ffree[min_index]} > 0 )) ||
25345                 skip "no free files in MDT$min_index"
25346         (( ${ffree[min_index]} < 10000000 )) ||
25347                 skip "too many free files in MDT$min_index"
25348
25349         # Check if we need to generate uneven MDTs
25350         local diff=$(((max - min) * 100 / min))
25351         local testdir=$DIR/$tdir-fillmdt
25352         local start
25353
25354         mkdir -p $testdir
25355
25356         i=0
25357         while (( diff < threshold )); do
25358                 # generate uneven MDTs, create till $threshold% diff
25359                 echo -n "weight diff=$diff% must be > $threshold% ..."
25360                 echo "Fill MDT$min_index with 1000 files: loop $i"
25361                 testdir=$DIR/$tdir-fillmdt/$i
25362                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25363                         error "mkdir $testdir failed"
25364                 $LFS setstripe -E 1M -L mdt $testdir ||
25365                         error "setstripe $testdir failed"
25366                 start=$SECONDS
25367                 for F in f.{0..999}; do
25368                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25369                                 /dev/null 2>&1 || error "dd $F failed"
25370                 done
25371
25372                 # wait for QOS to update
25373                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25374
25375                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25376                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25377                 max=$(((${ffree[max_index]} >> 8) * \
25378                         (${bavail[max_index]} * bsize >> 16)))
25379                 min=$(((${ffree[min_index]} >> 8) * \
25380                         (${bavail[min_index]} * bsize >> 16)))
25381                 diff=$(((max - min) * 100 / min))
25382                 i=$((i + 1))
25383         done
25384
25385         echo "MDT filesfree available: ${ffree[@]}"
25386         echo "MDT blocks available: ${bavail[@]}"
25387         echo "weight diff=$diff%"
25388 }
25389
25390 test_qos_mkdir() {
25391         local mkdir_cmd=$1
25392         local stripe_count=$2
25393         local mdts=$(comma_list $(mdts_nodes))
25394
25395         local testdir
25396         local lmv_qos_prio_free
25397         local lmv_qos_threshold_rr
25398         local lmv_qos_maxage
25399         local lod_qos_prio_free
25400         local lod_qos_threshold_rr
25401         local lod_qos_maxage
25402         local count
25403         local i
25404
25405         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25406         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25407         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25408                 head -n1)
25409         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25410         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25411         stack_trap "$LCTL set_param \
25412                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25413         stack_trap "$LCTL set_param \
25414                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25415         stack_trap "$LCTL set_param \
25416                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25417
25418         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25419                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25420         lod_qos_prio_free=${lod_qos_prio_free%%%}
25421         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25422                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25423         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25424         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25425                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25426         stack_trap "do_nodes $mdts $LCTL set_param \
25427                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25428         stack_trap "do_nodes $mdts $LCTL set_param \
25429                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25430         stack_trap "do_nodes $mdts $LCTL set_param \
25431                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25432
25433         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25434         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25435
25436         testdir=$DIR/$tdir-s$stripe_count/rr
25437
25438         local stripe_index=$($LFS getstripe -m $testdir)
25439         local test_mkdir_rr=true
25440
25441         getfattr -d -m dmv -e hex $testdir | grep dmv
25442         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25443                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25444                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25445                         test_mkdir_rr=false
25446         fi
25447
25448         echo
25449         $test_mkdir_rr &&
25450                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25451                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25452
25453         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25454         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25455                 eval $mkdir_cmd $testdir/subdir$i ||
25456                         error "$mkdir_cmd subdir$i failed"
25457         done
25458
25459         for (( i = 0; i < $MDSCOUNT; i++ )); do
25460                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25461                 echo "$count directories created on MDT$i"
25462                 if $test_mkdir_rr; then
25463                         (( $count == 100 )) ||
25464                                 error "subdirs are not evenly distributed"
25465                 elif (( $i == $stripe_index )); then
25466                         (( $count == 100 * MDSCOUNT )) ||
25467                                 error "$count subdirs created on MDT$i"
25468                 else
25469                         (( $count == 0 )) ||
25470                                 error "$count subdirs created on MDT$i"
25471                 fi
25472
25473                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25474                         count=$($LFS getdirstripe $testdir/* |
25475                                 grep -c -P "^\s+$i\t")
25476                         echo "$count stripes created on MDT$i"
25477                         # deviation should < 5% of average
25478                         (( $count >= 95 * stripe_count &&
25479                            $count <= 105 * stripe_count)) ||
25480                                 error "stripes are not evenly distributed"
25481                 fi
25482         done
25483
25484         echo
25485         echo "Check for uneven MDTs: "
25486
25487         local ffree
25488         local bavail
25489         local max
25490         local min
25491         local max_index
25492         local min_index
25493         local tmp
25494
25495         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25496         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25497         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25498
25499         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25500         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25501         max_index=0
25502         min_index=0
25503         for ((i = 1; i < ${#ffree[@]}; i++)); do
25504                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25505                 if [ $tmp -gt $max ]; then
25506                         max=$tmp
25507                         max_index=$i
25508                 fi
25509                 if [ $tmp -lt $min ]; then
25510                         min=$tmp
25511                         min_index=$i
25512                 fi
25513         done
25514
25515         (( ${ffree[min_index]} > 0 )) ||
25516                 skip "no free files in MDT$min_index"
25517         (( ${ffree[min_index]} < 10000000 )) ||
25518                 skip "too many free files in MDT$min_index"
25519
25520         echo "MDT filesfree available: ${ffree[@]}"
25521         echo "MDT blocks available: ${bavail[@]}"
25522         echo "weight diff=$(((max - min) * 100 / min))%"
25523         echo
25524         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25525
25526         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25527         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25528         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25529         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25530         # decrease statfs age, so that it can be updated in time
25531         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25532         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25533
25534         sleep 1
25535
25536         testdir=$DIR/$tdir-s$stripe_count/qos
25537         local num=200
25538
25539         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25540         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25541                 eval $mkdir_cmd $testdir/subdir$i ||
25542                         error "$mkdir_cmd subdir$i failed"
25543         done
25544
25545         max=0
25546         for (( i = 0; i < $MDSCOUNT; i++ )); do
25547                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25548                 (( count > max )) && max=$count
25549                 echo "$count directories created on MDT$i"
25550         done
25551
25552         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25553
25554         # D-value should > 10% of averge
25555         (( max - min > num / 10 )) ||
25556                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25557
25558         # ditto for stripes
25559         if (( stripe_count > 1 )); then
25560                 max=0
25561                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25562                         count=$($LFS getdirstripe $testdir/* |
25563                                 grep -c -P "^\s+$i\t")
25564                         (( count > max )) && max=$count
25565                         echo "$count stripes created on MDT$i"
25566                 done
25567
25568                 min=$($LFS getdirstripe $testdir/* |
25569                         grep -c -P "^\s+$min_index\t")
25570                 (( max - min > num * stripe_count / 10 )) ||
25571                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25572         fi
25573 }
25574
25575 most_full_mdt() {
25576         local ffree
25577         local bavail
25578         local bsize
25579         local min
25580         local min_index
25581         local tmp
25582
25583         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25584         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25585         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25586
25587         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25588         min_index=0
25589         for ((i = 1; i < ${#ffree[@]}; i++)); do
25590                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25591                 (( tmp < min )) && min=$tmp && min_index=$i
25592         done
25593
25594         echo -n $min_index
25595 }
25596
25597 test_413a() {
25598         [ $MDSCOUNT -lt 2 ] &&
25599                 skip "We need at least 2 MDTs for this test"
25600
25601         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25602                 skip "Need server version at least 2.12.52"
25603
25604         local stripe_count
25605
25606         generate_uneven_mdts 100
25607         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25608                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25609                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25610                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25611                         error "mkdir failed"
25612                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25613         done
25614 }
25615 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25616
25617 test_413b() {
25618         [ $MDSCOUNT -lt 2 ] &&
25619                 skip "We need at least 2 MDTs for this test"
25620
25621         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25622                 skip "Need server version at least 2.12.52"
25623
25624         local testdir
25625         local stripe_count
25626
25627         generate_uneven_mdts 100
25628         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25629                 testdir=$DIR/$tdir-s$stripe_count
25630                 mkdir $testdir || error "mkdir $testdir failed"
25631                 mkdir $testdir/rr || error "mkdir rr failed"
25632                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25633                         error "mkdir qos failed"
25634                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25635                         $testdir/rr || error "setdirstripe rr failed"
25636                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25637                         error "setdirstripe failed"
25638                 test_qos_mkdir "mkdir" $stripe_count
25639         done
25640 }
25641 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25642
25643 test_413c() {
25644         (( $MDSCOUNT >= 2 )) ||
25645                 skip "We need at least 2 MDTs for this test"
25646
25647         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25648                 skip "Need server version at least 2.14.51"
25649
25650         local testdir
25651         local inherit
25652         local inherit_rr
25653
25654         testdir=$DIR/${tdir}-s1
25655         mkdir $testdir || error "mkdir $testdir failed"
25656         mkdir $testdir/rr || error "mkdir rr failed"
25657         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25658         # default max_inherit is -1, default max_inherit_rr is 0
25659         $LFS setdirstripe -D -c 1 $testdir/rr ||
25660                 error "setdirstripe rr failed"
25661         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25662                 error "setdirstripe qos failed"
25663         test_qos_mkdir "mkdir" 1
25664
25665         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25666         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25667         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25668         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25669         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25670
25671         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25672         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25673         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25674         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25675         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25676         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25677         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25678                 error "level2 shouldn't have default LMV" || true
25679 }
25680 run_test 413c "mkdir with default LMV max inherit rr"
25681
25682 test_413d() {
25683         (( MDSCOUNT >= 2 )) ||
25684                 skip "We need at least 2 MDTs for this test"
25685
25686         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25687                 skip "Need server version at least 2.14.51"
25688
25689         local lmv_qos_threshold_rr
25690
25691         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25692                 head -n1)
25693         stack_trap "$LCTL set_param \
25694                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25695
25696         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25697         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25698         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25699                 error "$tdir shouldn't have default LMV"
25700         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25701                 error "mkdir sub failed"
25702
25703         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25704
25705         (( count == 100 )) || error "$count subdirs on MDT0"
25706 }
25707 run_test 413d "inherit ROOT default LMV"
25708
25709 test_413e() {
25710         (( MDSCOUNT >= 2 )) ||
25711                 skip "We need at least 2 MDTs for this test"
25712         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25713                 skip "Need server version at least 2.14.55"
25714
25715         local testdir=$DIR/$tdir
25716         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25717         local max_inherit
25718         local sub_max_inherit
25719
25720         mkdir -p $testdir || error "failed to create $testdir"
25721
25722         # set default max-inherit to -1 if stripe count is 0 or 1
25723         $LFS setdirstripe -D -c 1 $testdir ||
25724                 error "failed to set default LMV"
25725         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25726         (( max_inherit == -1 )) ||
25727                 error "wrong max_inherit value $max_inherit"
25728
25729         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25730         $LFS setdirstripe -D -c -1 $testdir ||
25731                 error "failed to set default LMV"
25732         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25733         (( max_inherit > 0 )) ||
25734                 error "wrong max_inherit value $max_inherit"
25735
25736         # and the subdir will decrease the max_inherit by 1
25737         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25738         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
25739         (( sub_max_inherit == max_inherit - 1)) ||
25740                 error "wrong max-inherit of subdir $sub_max_inherit"
25741
25742         # check specified --max-inherit and warning message
25743         stack_trap "rm -f $tmpfile"
25744         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
25745                 error "failed to set default LMV"
25746         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25747         (( max_inherit == -1 )) ||
25748                 error "wrong max_inherit value $max_inherit"
25749
25750         # check the warning messages
25751         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
25752                 error "failed to detect warning string"
25753         fi
25754 }
25755 run_test 413e "check default max-inherit value"
25756
25757 test_413f() {
25758         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
25759
25760         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25761                 skip "Need server version at least 2.14.55"
25762
25763         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
25764                 error "dump $DIR default LMV failed"
25765         stack_trap "setfattr --restore=$TMP/dmv.ea"
25766
25767         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
25768                 error "set $DIR default LMV failed"
25769
25770         local testdir=$DIR/$tdir
25771
25772         local count
25773         local inherit
25774         local inherit_rr
25775
25776         for i in $(seq 3); do
25777                 mkdir $testdir || error "mkdir $testdir failed"
25778                 count=$($LFS getdirstripe -D -c $testdir)
25779                 (( count == 1 )) ||
25780                         error "$testdir default LMV count mismatch $count != 1"
25781                 inherit=$($LFS getdirstripe -D -X $testdir)
25782                 (( inherit == 3 - i )) ||
25783                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
25784                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
25785                 (( inherit_rr == 3 - i )) ||
25786                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
25787                 testdir=$testdir/sub
25788         done
25789
25790         mkdir $testdir || error "mkdir $testdir failed"
25791         count=$($LFS getdirstripe -D -c $testdir)
25792         (( count == 0 )) ||
25793                 error "$testdir default LMV count not zero: $count"
25794 }
25795 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
25796
25797 test_413z() {
25798         local pids=""
25799         local subdir
25800         local pid
25801
25802         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25803                 unlinkmany $subdir/f. 1000 &
25804                 pids="$pids $!"
25805         done
25806
25807         for pid in $pids; do
25808                 wait $pid
25809         done
25810 }
25811 run_test 413z "413 test cleanup"
25812
25813 test_414() {
25814 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25815         $LCTL set_param fail_loc=0x80000521
25816         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25817         rm -f $DIR/$tfile
25818 }
25819 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25820
25821 test_415() {
25822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25823         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25824                 skip "Need server version at least 2.11.52"
25825
25826         # LU-11102
25827         local total
25828         local setattr_pid
25829         local start_time
25830         local end_time
25831         local duration
25832
25833         total=500
25834         # this test may be slow on ZFS
25835         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25836
25837         # though this test is designed for striped directory, let's test normal
25838         # directory too since lock is always saved as CoS lock.
25839         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25840         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25841
25842         (
25843                 while true; do
25844                         touch $DIR/$tdir
25845                 done
25846         ) &
25847         setattr_pid=$!
25848
25849         start_time=$(date +%s)
25850         for i in $(seq $total); do
25851                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25852                         > /dev/null
25853         done
25854         end_time=$(date +%s)
25855         duration=$((end_time - start_time))
25856
25857         kill -9 $setattr_pid
25858
25859         echo "rename $total files took $duration sec"
25860         [ $duration -lt 100 ] || error "rename took $duration sec"
25861 }
25862 run_test 415 "lock revoke is not missing"
25863
25864 test_416() {
25865         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25866                 skip "Need server version at least 2.11.55"
25867
25868         # define OBD_FAIL_OSD_TXN_START    0x19a
25869         do_facet mds1 lctl set_param fail_loc=0x19a
25870
25871         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25872
25873         true
25874 }
25875 run_test 416 "transaction start failure won't cause system hung"
25876
25877 cleanup_417() {
25878         trap 0
25879         do_nodes $(comma_list $(mdts_nodes)) \
25880                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25881         do_nodes $(comma_list $(mdts_nodes)) \
25882                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25883         do_nodes $(comma_list $(mdts_nodes)) \
25884                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25885 }
25886
25887 test_417() {
25888         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25889         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25890                 skip "Need MDS version at least 2.11.56"
25891
25892         trap cleanup_417 RETURN EXIT
25893
25894         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25895         do_nodes $(comma_list $(mdts_nodes)) \
25896                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25897         $LFS migrate -m 0 $DIR/$tdir.1 &&
25898                 error "migrate dir $tdir.1 should fail"
25899
25900         do_nodes $(comma_list $(mdts_nodes)) \
25901                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25902         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25903                 error "create remote dir $tdir.2 should fail"
25904
25905         do_nodes $(comma_list $(mdts_nodes)) \
25906                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25907         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25908                 error "create striped dir $tdir.3 should fail"
25909         true
25910 }
25911 run_test 417 "disable remote dir, striped dir and dir migration"
25912
25913 # Checks that the outputs of df [-i] and lfs df [-i] match
25914 #
25915 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25916 check_lfs_df() {
25917         local dir=$2
25918         local inodes
25919         local df_out
25920         local lfs_df_out
25921         local count
25922         local passed=false
25923
25924         # blocks or inodes
25925         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25926
25927         for count in {1..100}; do
25928                 do_nodes "$CLIENTS" \
25929                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25930                 sync; sleep 0.2
25931
25932                 # read the lines of interest
25933                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25934                         error "df $inodes $dir | tail -n +2 failed"
25935                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25936                         error "lfs df $inodes $dir | grep summary: failed"
25937
25938                 # skip first substrings of each output as they are different
25939                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25940                 # compare the two outputs
25941                 passed=true
25942                 #  skip "available" on MDT until LU-13997 is fixed.
25943                 #for i in {1..5}; do
25944                 for i in 1 2 4 5; do
25945                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25946                 done
25947                 $passed && break
25948         done
25949
25950         if ! $passed; then
25951                 df -P $inodes $dir
25952                 echo
25953                 lfs df $inodes $dir
25954                 error "df and lfs df $1 output mismatch: "      \
25955                       "df ${inodes}: ${df_out[*]}, "            \
25956                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25957         fi
25958 }
25959
25960 test_418() {
25961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25962
25963         local dir=$DIR/$tdir
25964         local numfiles=$((RANDOM % 4096 + 2))
25965         local numblocks=$((RANDOM % 256 + 1))
25966
25967         wait_delete_completed
25968         test_mkdir $dir
25969
25970         # check block output
25971         check_lfs_df blocks $dir
25972         # check inode output
25973         check_lfs_df inodes $dir
25974
25975         # create a single file and retest
25976         echo "Creating a single file and testing"
25977         createmany -o $dir/$tfile- 1 &>/dev/null ||
25978                 error "creating 1 file in $dir failed"
25979         check_lfs_df blocks $dir
25980         check_lfs_df inodes $dir
25981
25982         # create a random number of files
25983         echo "Creating $((numfiles - 1)) files and testing"
25984         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25985                 error "creating $((numfiles - 1)) files in $dir failed"
25986
25987         # write a random number of blocks to the first test file
25988         echo "Writing $numblocks 4K blocks and testing"
25989         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25990                 count=$numblocks &>/dev/null ||
25991                 error "dd to $dir/${tfile}-0 failed"
25992
25993         # retest
25994         check_lfs_df blocks $dir
25995         check_lfs_df inodes $dir
25996
25997         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25998                 error "unlinking $numfiles files in $dir failed"
25999 }
26000 run_test 418 "df and lfs df outputs match"
26001
26002 test_419()
26003 {
26004         local dir=$DIR/$tdir
26005
26006         mkdir -p $dir
26007         touch $dir/file
26008
26009         cancel_lru_locks mdc
26010
26011         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26012         $LCTL set_param fail_loc=0x1410
26013         cat $dir/file
26014         $LCTL set_param fail_loc=0
26015         rm -rf $dir
26016 }
26017 run_test 419 "Verify open file by name doesn't crash kernel"
26018
26019 test_420()
26020 {
26021         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26022                 skip "Need MDS version at least 2.12.53"
26023
26024         local SAVE_UMASK=$(umask)
26025         local dir=$DIR/$tdir
26026         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26027
26028         mkdir -p $dir
26029         umask 0000
26030         mkdir -m03777 $dir/testdir
26031         ls -dn $dir/testdir
26032         # Need to remove trailing '.' when SELinux is enabled
26033         local dirperms=$(ls -dn $dir/testdir |
26034                          awk '{ sub(/\.$/, "", $1); print $1}')
26035         [ $dirperms == "drwxrwsrwt" ] ||
26036                 error "incorrect perms on $dir/testdir"
26037
26038         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26039                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26040         ls -n $dir/testdir/testfile
26041         local fileperms=$(ls -n $dir/testdir/testfile |
26042                           awk '{ sub(/\.$/, "", $1); print $1}')
26043         [ $fileperms == "-rwxr-xr-x" ] ||
26044                 error "incorrect perms on $dir/testdir/testfile"
26045
26046         umask $SAVE_UMASK
26047 }
26048 run_test 420 "clear SGID bit on non-directories for non-members"
26049
26050 test_421a() {
26051         local cnt
26052         local fid1
26053         local fid2
26054
26055         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26056                 skip "Need MDS version at least 2.12.54"
26057
26058         test_mkdir $DIR/$tdir
26059         createmany -o $DIR/$tdir/f 3
26060         cnt=$(ls -1 $DIR/$tdir | wc -l)
26061         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26062
26063         fid1=$(lfs path2fid $DIR/$tdir/f1)
26064         fid2=$(lfs path2fid $DIR/$tdir/f2)
26065         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26066
26067         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26068         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26069
26070         cnt=$(ls -1 $DIR/$tdir | wc -l)
26071         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26072
26073         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26074         createmany -o $DIR/$tdir/f 3
26075         cnt=$(ls -1 $DIR/$tdir | wc -l)
26076         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26077
26078         fid1=$(lfs path2fid $DIR/$tdir/f1)
26079         fid2=$(lfs path2fid $DIR/$tdir/f2)
26080         echo "remove using fsname $FSNAME"
26081         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26082
26083         cnt=$(ls -1 $DIR/$tdir | wc -l)
26084         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26085 }
26086 run_test 421a "simple rm by fid"
26087
26088 test_421b() {
26089         local cnt
26090         local FID1
26091         local FID2
26092
26093         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26094                 skip "Need MDS version at least 2.12.54"
26095
26096         test_mkdir $DIR/$tdir
26097         createmany -o $DIR/$tdir/f 3
26098         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26099         MULTIPID=$!
26100
26101         FID1=$(lfs path2fid $DIR/$tdir/f1)
26102         FID2=$(lfs path2fid $DIR/$tdir/f2)
26103         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26104
26105         kill -USR1 $MULTIPID
26106         wait
26107
26108         cnt=$(ls $DIR/$tdir | wc -l)
26109         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26110 }
26111 run_test 421b "rm by fid on open file"
26112
26113 test_421c() {
26114         local cnt
26115         local FIDS
26116
26117         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26118                 skip "Need MDS version at least 2.12.54"
26119
26120         test_mkdir $DIR/$tdir
26121         createmany -o $DIR/$tdir/f 3
26122         touch $DIR/$tdir/$tfile
26123         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26124         cnt=$(ls -1 $DIR/$tdir | wc -l)
26125         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26126
26127         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26128         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26129
26130         cnt=$(ls $DIR/$tdir | wc -l)
26131         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26132 }
26133 run_test 421c "rm by fid against hardlinked files"
26134
26135 test_421d() {
26136         local cnt
26137         local FIDS
26138
26139         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26140                 skip "Need MDS version at least 2.12.54"
26141
26142         test_mkdir $DIR/$tdir
26143         createmany -o $DIR/$tdir/f 4097
26144         cnt=$(ls -1 $DIR/$tdir | wc -l)
26145         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26146
26147         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26148         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26149
26150         cnt=$(ls $DIR/$tdir | wc -l)
26151         rm -rf $DIR/$tdir
26152         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26153 }
26154 run_test 421d "rmfid en masse"
26155
26156 test_421e() {
26157         local cnt
26158         local FID
26159
26160         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26161         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26162                 skip "Need MDS version at least 2.12.54"
26163
26164         mkdir -p $DIR/$tdir
26165         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26166         createmany -o $DIR/$tdir/striped_dir/f 512
26167         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26168         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26169
26170         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26171                 sed "s/[/][^:]*://g")
26172         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26173
26174         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26175         rm -rf $DIR/$tdir
26176         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26177 }
26178 run_test 421e "rmfid in DNE"
26179
26180 test_421f() {
26181         local cnt
26182         local FID
26183
26184         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26185                 skip "Need MDS version at least 2.12.54"
26186
26187         test_mkdir $DIR/$tdir
26188         touch $DIR/$tdir/f
26189         cnt=$(ls -1 $DIR/$tdir | wc -l)
26190         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26191
26192         FID=$(lfs path2fid $DIR/$tdir/f)
26193         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26194         # rmfid should fail
26195         cnt=$(ls -1 $DIR/$tdir | wc -l)
26196         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26197
26198         chmod a+rw $DIR/$tdir
26199         ls -la $DIR/$tdir
26200         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26201         # rmfid should fail
26202         cnt=$(ls -1 $DIR/$tdir | wc -l)
26203         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26204
26205         rm -f $DIR/$tdir/f
26206         $RUNAS touch $DIR/$tdir/f
26207         FID=$(lfs path2fid $DIR/$tdir/f)
26208         echo "rmfid as root"
26209         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26210         cnt=$(ls -1 $DIR/$tdir | wc -l)
26211         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26212
26213         rm -f $DIR/$tdir/f
26214         $RUNAS touch $DIR/$tdir/f
26215         cnt=$(ls -1 $DIR/$tdir | wc -l)
26216         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26217         FID=$(lfs path2fid $DIR/$tdir/f)
26218         # rmfid w/o user_fid2path mount option should fail
26219         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26220         cnt=$(ls -1 $DIR/$tdir | wc -l)
26221         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26222
26223         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26224         stack_trap "rmdir $tmpdir"
26225         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26226                 error "failed to mount client'"
26227         stack_trap "umount_client $tmpdir"
26228
26229         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26230         # rmfid should succeed
26231         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26232         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26233
26234         # rmfid shouldn't allow to remove files due to dir's permission
26235         chmod a+rwx $tmpdir/$tdir
26236         touch $tmpdir/$tdir/f
26237         ls -la $tmpdir/$tdir
26238         FID=$(lfs path2fid $tmpdir/$tdir/f)
26239         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26240         return 0
26241 }
26242 run_test 421f "rmfid checks permissions"
26243
26244 test_421g() {
26245         local cnt
26246         local FIDS
26247
26248         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26249         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26250                 skip "Need MDS version at least 2.12.54"
26251
26252         mkdir -p $DIR/$tdir
26253         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26254         createmany -o $DIR/$tdir/striped_dir/f 512
26255         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26256         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26257
26258         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26259                 sed "s/[/][^:]*://g")
26260
26261         rm -f $DIR/$tdir/striped_dir/f1*
26262         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26263         removed=$((512 - cnt))
26264
26265         # few files have been just removed, so we expect
26266         # rmfid to fail on their fids
26267         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26268         [ $removed != $errors ] && error "$errors != $removed"
26269
26270         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26271         rm -rf $DIR/$tdir
26272         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26273 }
26274 run_test 421g "rmfid to return errors properly"
26275
26276 test_422() {
26277         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26278         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26279         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26280         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26281         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26282
26283         local amc=$(at_max_get client)
26284         local amo=$(at_max_get mds1)
26285         local timeout=`lctl get_param -n timeout`
26286
26287         at_max_set 0 client
26288         at_max_set 0 mds1
26289
26290 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26291         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26292                         fail_val=$(((2*timeout + 10)*1000))
26293         touch $DIR/$tdir/d3/file &
26294         sleep 2
26295 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26296         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26297                         fail_val=$((2*timeout + 5))
26298         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26299         local pid=$!
26300         sleep 1
26301         kill -9 $pid
26302         sleep $((2 * timeout))
26303         echo kill $pid
26304         kill -9 $pid
26305         lctl mark touch
26306         touch $DIR/$tdir/d2/file3
26307         touch $DIR/$tdir/d2/file4
26308         touch $DIR/$tdir/d2/file5
26309
26310         wait
26311         at_max_set $amc client
26312         at_max_set $amo mds1
26313
26314         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26315         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26316                 error "Watchdog is always throttled"
26317 }
26318 run_test 422 "kill a process with RPC in progress"
26319
26320 stat_test() {
26321     df -h $MOUNT &
26322     df -h $MOUNT &
26323     df -h $MOUNT &
26324     df -h $MOUNT &
26325     df -h $MOUNT &
26326     df -h $MOUNT &
26327 }
26328
26329 test_423() {
26330     local _stats
26331     # ensure statfs cache is expired
26332     sleep 2;
26333
26334     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26335     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26336
26337     return 0
26338 }
26339 run_test 423 "statfs should return a right data"
26340
26341 test_424() {
26342 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26343         $LCTL set_param fail_loc=0x80000522
26344         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26345         rm -f $DIR/$tfile
26346 }
26347 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26348
26349 test_425() {
26350         test_mkdir -c -1 $DIR/$tdir
26351         $LFS setstripe -c -1 $DIR/$tdir
26352
26353         lru_resize_disable "" 100
26354         stack_trap "lru_resize_enable" EXIT
26355
26356         sleep 5
26357
26358         for i in $(seq $((MDSCOUNT * 125))); do
26359                 local t=$DIR/$tdir/$tfile_$i
26360
26361                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26362                         error_noexit "Create file $t"
26363         done
26364         stack_trap "rm -rf $DIR/$tdir" EXIT
26365
26366         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26367                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26368                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26369
26370                 [ $lock_count -le $lru_size ] ||
26371                         error "osc lock count $lock_count > lru size $lru_size"
26372         done
26373
26374         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26375                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26376                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26377
26378                 [ $lock_count -le $lru_size ] ||
26379                         error "mdc lock count $lock_count > lru size $lru_size"
26380         done
26381 }
26382 run_test 425 "lock count should not exceed lru size"
26383
26384 test_426() {
26385         splice-test -r $DIR/$tfile
26386         splice-test -rd $DIR/$tfile
26387         splice-test $DIR/$tfile
26388         splice-test -d $DIR/$tfile
26389 }
26390 run_test 426 "splice test on Lustre"
26391
26392 test_427() {
26393         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26394         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26395                 skip "Need MDS version at least 2.12.4"
26396         local log
26397
26398         mkdir $DIR/$tdir
26399         mkdir $DIR/$tdir/1
26400         mkdir $DIR/$tdir/2
26401         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26402         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26403
26404         $LFS getdirstripe $DIR/$tdir/1/dir
26405
26406         #first setfattr for creating updatelog
26407         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26408
26409 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26410         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26411         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26412         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26413
26414         sleep 2
26415         fail mds2
26416         wait_recovery_complete mds2 $((2*TIMEOUT))
26417
26418         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26419         echo $log | grep "get update log failed" &&
26420                 error "update log corruption is detected" || true
26421 }
26422 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26423
26424 test_428() {
26425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26426         local cache_limit=$CACHE_MAX
26427
26428         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26429         $LCTL set_param -n llite.*.max_cached_mb=64
26430
26431         mkdir $DIR/$tdir
26432         $LFS setstripe -c 1 $DIR/$tdir
26433         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26434         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26435         #test write
26436         for f in $(seq 4); do
26437                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26438         done
26439         wait
26440
26441         cancel_lru_locks osc
26442         # Test read
26443         for f in $(seq 4); do
26444                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26445         done
26446         wait
26447 }
26448 run_test 428 "large block size IO should not hang"
26449
26450 test_429() { # LU-7915 / LU-10948
26451         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26452         local testfile=$DIR/$tfile
26453         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26454         local new_flag=1
26455         local first_rpc
26456         local second_rpc
26457         local third_rpc
26458
26459         $LCTL get_param $ll_opencache_threshold_count ||
26460                 skip "client does not have opencache parameter"
26461
26462         set_opencache $new_flag
26463         stack_trap "restore_opencache"
26464         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26465                 error "enable opencache failed"
26466         touch $testfile
26467         # drop MDC DLM locks
26468         cancel_lru_locks mdc
26469         # clear MDC RPC stats counters
26470         $LCTL set_param $mdc_rpcstats=clear
26471
26472         # According to the current implementation, we need to run 3 times
26473         # open & close file to verify if opencache is enabled correctly.
26474         # 1st, RPCs are sent for lookup/open and open handle is released on
26475         #      close finally.
26476         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26477         #      so open handle won't be released thereafter.
26478         # 3rd, No RPC is sent out.
26479         $MULTIOP $testfile oc || error "multiop failed"
26480         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26481         echo "1st: $first_rpc RPCs in flight"
26482
26483         $MULTIOP $testfile oc || error "multiop failed"
26484         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26485         echo "2nd: $second_rpc RPCs in flight"
26486
26487         $MULTIOP $testfile oc || error "multiop failed"
26488         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26489         echo "3rd: $third_rpc RPCs in flight"
26490
26491         #verify no MDC RPC is sent
26492         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26493 }
26494 run_test 429 "verify if opencache flag on client side does work"
26495
26496 lseek_test_430() {
26497         local offset
26498         local file=$1
26499
26500         # data at [200K, 400K)
26501         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26502                 error "256K->512K dd fails"
26503         # data at [2M, 3M)
26504         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26505                 error "2M->3M dd fails"
26506         # data at [4M, 5M)
26507         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26508                 error "4M->5M dd fails"
26509         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26510         # start at first component hole #1
26511         printf "Seeking hole from 1000 ... "
26512         offset=$(lseek_test -l 1000 $file)
26513         echo $offset
26514         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26515         printf "Seeking data from 1000 ... "
26516         offset=$(lseek_test -d 1000 $file)
26517         echo $offset
26518         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26519
26520         # start at first component data block
26521         printf "Seeking hole from 300000 ... "
26522         offset=$(lseek_test -l 300000 $file)
26523         echo $offset
26524         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26525         printf "Seeking data from 300000 ... "
26526         offset=$(lseek_test -d 300000 $file)
26527         echo $offset
26528         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26529
26530         # start at the first component but beyond end of object size
26531         printf "Seeking hole from 1000000 ... "
26532         offset=$(lseek_test -l 1000000 $file)
26533         echo $offset
26534         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26535         printf "Seeking data from 1000000 ... "
26536         offset=$(lseek_test -d 1000000 $file)
26537         echo $offset
26538         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26539
26540         # start at second component stripe 2 (empty file)
26541         printf "Seeking hole from 1500000 ... "
26542         offset=$(lseek_test -l 1500000 $file)
26543         echo $offset
26544         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26545         printf "Seeking data from 1500000 ... "
26546         offset=$(lseek_test -d 1500000 $file)
26547         echo $offset
26548         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26549
26550         # start at second component stripe 1 (all data)
26551         printf "Seeking hole from 3000000 ... "
26552         offset=$(lseek_test -l 3000000 $file)
26553         echo $offset
26554         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26555         printf "Seeking data from 3000000 ... "
26556         offset=$(lseek_test -d 3000000 $file)
26557         echo $offset
26558         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26559
26560         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26561                 error "2nd dd fails"
26562         echo "Add data block at 640K...1280K"
26563
26564         # start at before new data block, in hole
26565         printf "Seeking hole from 600000 ... "
26566         offset=$(lseek_test -l 600000 $file)
26567         echo $offset
26568         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26569         printf "Seeking data from 600000 ... "
26570         offset=$(lseek_test -d 600000 $file)
26571         echo $offset
26572         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26573
26574         # start at the first component new data block
26575         printf "Seeking hole from 1000000 ... "
26576         offset=$(lseek_test -l 1000000 $file)
26577         echo $offset
26578         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26579         printf "Seeking data from 1000000 ... "
26580         offset=$(lseek_test -d 1000000 $file)
26581         echo $offset
26582         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26583
26584         # start at second component stripe 2, new data
26585         printf "Seeking hole from 1200000 ... "
26586         offset=$(lseek_test -l 1200000 $file)
26587         echo $offset
26588         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26589         printf "Seeking data from 1200000 ... "
26590         offset=$(lseek_test -d 1200000 $file)
26591         echo $offset
26592         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26593
26594         # start beyond file end
26595         printf "Using offset > filesize ... "
26596         lseek_test -l 4000000 $file && error "lseek should fail"
26597         printf "Using offset > filesize ... "
26598         lseek_test -d 4000000 $file && error "lseek should fail"
26599
26600         printf "Done\n\n"
26601 }
26602
26603 test_430a() {
26604         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26605                 skip "MDT does not support SEEK_HOLE"
26606
26607         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26608                 skip "OST does not support SEEK_HOLE"
26609
26610         local file=$DIR/$tdir/$tfile
26611
26612         mkdir -p $DIR/$tdir
26613
26614         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26615         # OST stripe #1 will have continuous data at [1M, 3M)
26616         # OST stripe #2 is empty
26617         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26618         lseek_test_430 $file
26619         rm $file
26620         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26621         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26622         lseek_test_430 $file
26623         rm $file
26624         $LFS setstripe -c2 -S 512K $file
26625         echo "Two stripes, stripe size 512K"
26626         lseek_test_430 $file
26627         rm $file
26628         # FLR with stale mirror
26629         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26630                        -N -c2 -S 1M $file
26631         echo "Mirrored file:"
26632         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26633         echo "Plain 2 stripes 1M"
26634         lseek_test_430 $file
26635         rm $file
26636 }
26637 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26638
26639 test_430b() {
26640         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26641                 skip "OST does not support SEEK_HOLE"
26642
26643         local offset
26644         local file=$DIR/$tdir/$tfile
26645
26646         mkdir -p $DIR/$tdir
26647         # Empty layout lseek should fail
26648         $MCREATE $file
26649         # seek from 0
26650         printf "Seeking hole from 0 ... "
26651         lseek_test -l 0 $file && error "lseek should fail"
26652         printf "Seeking data from 0 ... "
26653         lseek_test -d 0 $file && error "lseek should fail"
26654         rm $file
26655
26656         # 1M-hole file
26657         $LFS setstripe -E 1M -c2 -E eof $file
26658         $TRUNCATE $file 1048576
26659         printf "Seeking hole from 1000000 ... "
26660         offset=$(lseek_test -l 1000000 $file)
26661         echo $offset
26662         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26663         printf "Seeking data from 1000000 ... "
26664         lseek_test -d 1000000 $file && error "lseek should fail"
26665         rm $file
26666
26667         # full component followed by non-inited one
26668         $LFS setstripe -E 1M -c2 -E eof $file
26669         dd if=/dev/urandom of=$file bs=1M count=1
26670         printf "Seeking hole from 1000000 ... "
26671         offset=$(lseek_test -l 1000000 $file)
26672         echo $offset
26673         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26674         printf "Seeking hole from 1048576 ... "
26675         lseek_test -l 1048576 $file && error "lseek should fail"
26676         # init second component and truncate back
26677         echo "123" >> $file
26678         $TRUNCATE $file 1048576
26679         printf "Seeking hole from 1000000 ... "
26680         offset=$(lseek_test -l 1000000 $file)
26681         echo $offset
26682         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26683         printf "Seeking hole from 1048576 ... "
26684         lseek_test -l 1048576 $file && error "lseek should fail"
26685         # boundary checks for big values
26686         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26687         offset=$(lseek_test -d 0 $file.10g)
26688         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26689         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26690         offset=$(lseek_test -d 0 $file.100g)
26691         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26692         return 0
26693 }
26694 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26695
26696 test_430c() {
26697         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26698                 skip "OST does not support SEEK_HOLE"
26699
26700         local file=$DIR/$tdir/$tfile
26701         local start
26702
26703         mkdir -p $DIR/$tdir
26704         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26705
26706         # cp version 8.33+ prefers lseek over fiemap
26707         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26708                 start=$SECONDS
26709                 time cp $file /dev/null
26710                 (( SECONDS - start < 5 )) ||
26711                         error "cp: too long runtime $((SECONDS - start))"
26712
26713         fi
26714         # tar version 1.29+ supports SEEK_HOLE/DATA
26715         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26716                 start=$SECONDS
26717                 time tar cS $file - | cat > /dev/null
26718                 (( SECONDS - start < 5 )) ||
26719                         error "tar: too long runtime $((SECONDS - start))"
26720         fi
26721 }
26722 run_test 430c "lseek: external tools check"
26723
26724 test_431() { # LU-14187
26725         local file=$DIR/$tdir/$tfile
26726
26727         mkdir -p $DIR/$tdir
26728         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26729         dd if=/dev/urandom of=$file bs=4k count=1
26730         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26731         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26732         #define OBD_FAIL_OST_RESTART_IO 0x251
26733         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26734         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26735         cp $file $file.0
26736         cancel_lru_locks
26737         sync_all_data
26738         echo 3 > /proc/sys/vm/drop_caches
26739         diff  $file $file.0 || error "data diff"
26740 }
26741 run_test 431 "Restart transaction for IO"
26742
26743 cleanup_test_432() {
26744         do_facet mgs $LCTL nodemap_activate 0
26745         wait_nm_sync active
26746 }
26747
26748 test_432() {
26749         local tmpdir=$TMP/dir432
26750
26751         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26752                 skip "Need MDS version at least 2.14.52"
26753
26754         stack_trap cleanup_test_432 EXIT
26755         mkdir $DIR/$tdir
26756         mkdir $tmpdir
26757
26758         do_facet mgs $LCTL nodemap_activate 1
26759         wait_nm_sync active
26760         do_facet mgs $LCTL nodemap_modify --name default \
26761                 --property admin --value 1
26762         do_facet mgs $LCTL nodemap_modify --name default \
26763                 --property trusted --value 1
26764         cancel_lru_locks mdc
26765         wait_nm_sync default admin_nodemap
26766         wait_nm_sync default trusted_nodemap
26767
26768         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26769                grep -ci "Operation not permitted") -ne 0 ]; then
26770                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26771         fi
26772 }
26773 run_test 432 "mv dir from outside Lustre"
26774
26775 prep_801() {
26776         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26777         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26778                 skip "Need server version at least 2.9.55"
26779
26780         start_full_debug_logging
26781 }
26782
26783 post_801() {
26784         stop_full_debug_logging
26785 }
26786
26787 barrier_stat() {
26788         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26789                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26790                            awk '/The barrier for/ { print $7 }')
26791                 echo $st
26792         else
26793                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26794                 echo \'$st\'
26795         fi
26796 }
26797
26798 barrier_expired() {
26799         local expired
26800
26801         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26802                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26803                           awk '/will be expired/ { print $7 }')
26804         else
26805                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26806         fi
26807
26808         echo $expired
26809 }
26810
26811 test_801a() {
26812         prep_801
26813
26814         echo "Start barrier_freeze at: $(date)"
26815         #define OBD_FAIL_BARRIER_DELAY          0x2202
26816         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26817         # Do not reduce barrier time - See LU-11873
26818         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26819
26820         sleep 2
26821         local b_status=$(barrier_stat)
26822         echo "Got barrier status at: $(date)"
26823         [ "$b_status" = "'freezing_p1'" ] ||
26824                 error "(1) unexpected barrier status $b_status"
26825
26826         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26827         wait
26828         b_status=$(barrier_stat)
26829         [ "$b_status" = "'frozen'" ] ||
26830                 error "(2) unexpected barrier status $b_status"
26831
26832         local expired=$(barrier_expired)
26833         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26834         sleep $((expired + 3))
26835
26836         b_status=$(barrier_stat)
26837         [ "$b_status" = "'expired'" ] ||
26838                 error "(3) unexpected barrier status $b_status"
26839
26840         # Do not reduce barrier time - See LU-11873
26841         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26842                 error "(4) fail to freeze barrier"
26843
26844         b_status=$(barrier_stat)
26845         [ "$b_status" = "'frozen'" ] ||
26846                 error "(5) unexpected barrier status $b_status"
26847
26848         echo "Start barrier_thaw at: $(date)"
26849         #define OBD_FAIL_BARRIER_DELAY          0x2202
26850         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26851         do_facet mgs $LCTL barrier_thaw $FSNAME &
26852
26853         sleep 2
26854         b_status=$(barrier_stat)
26855         echo "Got barrier status at: $(date)"
26856         [ "$b_status" = "'thawing'" ] ||
26857                 error "(6) unexpected barrier status $b_status"
26858
26859         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26860         wait
26861         b_status=$(barrier_stat)
26862         [ "$b_status" = "'thawed'" ] ||
26863                 error "(7) unexpected barrier status $b_status"
26864
26865         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26866         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26867         do_facet mgs $LCTL barrier_freeze $FSNAME
26868
26869         b_status=$(barrier_stat)
26870         [ "$b_status" = "'failed'" ] ||
26871                 error "(8) unexpected barrier status $b_status"
26872
26873         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26874         do_facet mgs $LCTL barrier_thaw $FSNAME
26875
26876         post_801
26877 }
26878 run_test 801a "write barrier user interfaces and stat machine"
26879
26880 test_801b() {
26881         prep_801
26882
26883         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26884         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
26885         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26886         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26887         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26888
26889         cancel_lru_locks mdc
26890
26891         # 180 seconds should be long enough
26892         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26893
26894         local b_status=$(barrier_stat)
26895         [ "$b_status" = "'frozen'" ] ||
26896                 error "(6) unexpected barrier status $b_status"
26897
26898         mkdir $DIR/$tdir/d0/d10 &
26899         mkdir_pid=$!
26900
26901         touch $DIR/$tdir/d1/f13 &
26902         touch_pid=$!
26903
26904         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26905         ln_pid=$!
26906
26907         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26908         mv_pid=$!
26909
26910         rm -f $DIR/$tdir/d4/f12 &
26911         rm_pid=$!
26912
26913         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26914
26915         # To guarantee taht the 'stat' is not blocked
26916         b_status=$(barrier_stat)
26917         [ "$b_status" = "'frozen'" ] ||
26918                 error "(8) unexpected barrier status $b_status"
26919
26920         # let above commands to run at background
26921         sleep 5
26922
26923         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26924         ps -p $touch_pid || error "(10) touch should be blocked"
26925         ps -p $ln_pid || error "(11) link should be blocked"
26926         ps -p $mv_pid || error "(12) rename should be blocked"
26927         ps -p $rm_pid || error "(13) unlink should be blocked"
26928
26929         b_status=$(barrier_stat)
26930         [ "$b_status" = "'frozen'" ] ||
26931                 error "(14) unexpected barrier status $b_status"
26932
26933         do_facet mgs $LCTL barrier_thaw $FSNAME
26934         b_status=$(barrier_stat)
26935         [ "$b_status" = "'thawed'" ] ||
26936                 error "(15) unexpected barrier status $b_status"
26937
26938         wait $mkdir_pid || error "(16) mkdir should succeed"
26939         wait $touch_pid || error "(17) touch should succeed"
26940         wait $ln_pid || error "(18) link should succeed"
26941         wait $mv_pid || error "(19) rename should succeed"
26942         wait $rm_pid || error "(20) unlink should succeed"
26943
26944         post_801
26945 }
26946 run_test 801b "modification will be blocked by write barrier"
26947
26948 test_801c() {
26949         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26950
26951         prep_801
26952
26953         stop mds2 || error "(1) Fail to stop mds2"
26954
26955         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26956
26957         local b_status=$(barrier_stat)
26958         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26959                 do_facet mgs $LCTL barrier_thaw $FSNAME
26960                 error "(2) unexpected barrier status $b_status"
26961         }
26962
26963         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26964                 error "(3) Fail to rescan barrier bitmap"
26965
26966         # Do not reduce barrier time - See LU-11873
26967         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26968
26969         b_status=$(barrier_stat)
26970         [ "$b_status" = "'frozen'" ] ||
26971                 error "(4) unexpected barrier status $b_status"
26972
26973         do_facet mgs $LCTL barrier_thaw $FSNAME
26974         b_status=$(barrier_stat)
26975         [ "$b_status" = "'thawed'" ] ||
26976                 error "(5) unexpected barrier status $b_status"
26977
26978         local devname=$(mdsdevname 2)
26979
26980         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26981
26982         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26983                 error "(7) Fail to rescan barrier bitmap"
26984
26985         post_801
26986 }
26987 run_test 801c "rescan barrier bitmap"
26988
26989 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26990 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26991 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26992 saved_MOUNT_OPTS=$MOUNT_OPTS
26993
26994 cleanup_802a() {
26995         trap 0
26996
26997         stopall
26998         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26999         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27000         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27001         MOUNT_OPTS=$saved_MOUNT_OPTS
27002         setupall
27003 }
27004
27005 test_802a() {
27006         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27007         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27008         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27009                 skip "Need server version at least 2.9.55"
27010
27011         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27012
27013         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27014
27015         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27016                 error "(2) Fail to copy"
27017
27018         trap cleanup_802a EXIT
27019
27020         # sync by force before remount as readonly
27021         sync; sync_all_data; sleep 3; sync_all_data
27022
27023         stopall
27024
27025         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27026         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27027         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27028
27029         echo "Mount the server as read only"
27030         setupall server_only || error "(3) Fail to start servers"
27031
27032         echo "Mount client without ro should fail"
27033         mount_client $MOUNT &&
27034                 error "(4) Mount client without 'ro' should fail"
27035
27036         echo "Mount client with ro should succeed"
27037         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27038         mount_client $MOUNT ||
27039                 error "(5) Mount client with 'ro' should succeed"
27040
27041         echo "Modify should be refused"
27042         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27043
27044         echo "Read should be allowed"
27045         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27046                 error "(7) Read should succeed under ro mode"
27047
27048         cleanup_802a
27049 }
27050 run_test 802a "simulate readonly device"
27051
27052 test_802b() {
27053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27054         remote_mds_nodsh && skip "remote MDS with nodsh"
27055
27056         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27057                 skip "readonly option not available"
27058
27059         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27060
27061         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27062                 error "(2) Fail to copy"
27063
27064         # write back all cached data before setting MDT to readonly
27065         cancel_lru_locks
27066         sync_all_data
27067
27068         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27069         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27070
27071         echo "Modify should be refused"
27072         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27073
27074         echo "Read should be allowed"
27075         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27076                 error "(7) Read should succeed under ro mode"
27077
27078         # disable readonly
27079         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27080 }
27081 run_test 802b "be able to set MDTs to readonly"
27082
27083 test_803a() {
27084         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27085         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27086                 skip "MDS needs to be newer than 2.10.54"
27087
27088         mkdir_on_mdt0 $DIR/$tdir
27089         # Create some objects on all MDTs to trigger related logs objects
27090         for idx in $(seq $MDSCOUNT); do
27091                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27092                         $DIR/$tdir/dir${idx} ||
27093                         error "Fail to create $DIR/$tdir/dir${idx}"
27094         done
27095
27096         sync; sleep 3
27097         wait_delete_completed # ensure old test cleanups are finished
27098         echo "before create:"
27099         $LFS df -i $MOUNT
27100         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27101
27102         for i in {1..10}; do
27103                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27104                         error "Fail to create $DIR/$tdir/foo$i"
27105         done
27106
27107         sync; sleep 3
27108         echo "after create:"
27109         $LFS df -i $MOUNT
27110         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27111
27112         # allow for an llog to be cleaned up during the test
27113         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27114                 error "before ($before_used) + 10 > after ($after_used)"
27115
27116         for i in {1..10}; do
27117                 rm -rf $DIR/$tdir/foo$i ||
27118                         error "Fail to remove $DIR/$tdir/foo$i"
27119         done
27120
27121         sleep 3 # avoid MDT return cached statfs
27122         wait_delete_completed
27123         echo "after unlink:"
27124         $LFS df -i $MOUNT
27125         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27126
27127         # allow for an llog to be created during the test
27128         [ $after_used -le $((before_used + 1)) ] ||
27129                 error "after ($after_used) > before ($before_used) + 1"
27130 }
27131 run_test 803a "verify agent object for remote object"
27132
27133 test_803b() {
27134         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27135         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27136                 skip "MDS needs to be newer than 2.13.56"
27137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27138
27139         for i in $(seq 0 $((MDSCOUNT - 1))); do
27140                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27141         done
27142
27143         local before=0
27144         local after=0
27145
27146         local tmp
27147
27148         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27149         for i in $(seq 0 $((MDSCOUNT - 1))); do
27150                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27151                         awk '/getattr/ { print $2 }')
27152                 before=$((before + tmp))
27153         done
27154         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27155         for i in $(seq 0 $((MDSCOUNT - 1))); do
27156                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27157                         awk '/getattr/ { print $2 }')
27158                 after=$((after + tmp))
27159         done
27160
27161         [ $before -eq $after ] || error "getattr count $before != $after"
27162 }
27163 run_test 803b "remote object can getattr from cache"
27164
27165 test_804() {
27166         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27167         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27168                 skip "MDS needs to be newer than 2.10.54"
27169         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27170
27171         mkdir -p $DIR/$tdir
27172         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27173                 error "Fail to create $DIR/$tdir/dir0"
27174
27175         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27176         local dev=$(mdsdevname 2)
27177
27178         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27179                 grep ${fid} || error "NOT found agent entry for dir0"
27180
27181         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27182                 error "Fail to create $DIR/$tdir/dir1"
27183
27184         touch $DIR/$tdir/dir1/foo0 ||
27185                 error "Fail to create $DIR/$tdir/dir1/foo0"
27186         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27187         local rc=0
27188
27189         for idx in $(seq $MDSCOUNT); do
27190                 dev=$(mdsdevname $idx)
27191                 do_facet mds${idx} \
27192                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27193                         grep ${fid} && rc=$idx
27194         done
27195
27196         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27197                 error "Fail to rename foo0 to foo1"
27198         if [ $rc -eq 0 ]; then
27199                 for idx in $(seq $MDSCOUNT); do
27200                         dev=$(mdsdevname $idx)
27201                         do_facet mds${idx} \
27202                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27203                         grep ${fid} && rc=$idx
27204                 done
27205         fi
27206
27207         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27208                 error "Fail to rename foo1 to foo2"
27209         if [ $rc -eq 0 ]; then
27210                 for idx in $(seq $MDSCOUNT); do
27211                         dev=$(mdsdevname $idx)
27212                         do_facet mds${idx} \
27213                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27214                         grep ${fid} && rc=$idx
27215                 done
27216         fi
27217
27218         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27219
27220         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27221                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27222         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27223                 error "Fail to rename foo2 to foo0"
27224         unlink $DIR/$tdir/dir1/foo0 ||
27225                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27226         rm -rf $DIR/$tdir/dir0 ||
27227                 error "Fail to rm $DIR/$tdir/dir0"
27228
27229         for idx in $(seq $MDSCOUNT); do
27230                 rc=0
27231
27232                 stop mds${idx}
27233                 dev=$(mdsdevname $idx)
27234                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27235                         rc=$?
27236                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27237                         error "mount mds$idx failed"
27238                 df $MOUNT > /dev/null 2>&1
27239
27240                 # e2fsck should not return error
27241                 [ $rc -eq 0 ] ||
27242                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27243         done
27244 }
27245 run_test 804 "verify agent entry for remote entry"
27246
27247 cleanup_805() {
27248         do_facet $SINGLEMDS zfs set quota=$old $fsset
27249         unlinkmany $DIR/$tdir/f- 1000000
27250         trap 0
27251 }
27252
27253 test_805() {
27254         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27255         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27256         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27257                 skip "netfree not implemented before 0.7"
27258         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27259                 skip "Need MDS version at least 2.10.57"
27260
27261         local fsset
27262         local freekb
27263         local usedkb
27264         local old
27265         local quota
27266         local pref="osd-zfs.$FSNAME-MDT0000."
27267
27268         # limit available space on MDS dataset to meet nospace issue
27269         # quickly. then ZFS 0.7.2 can use reserved space if asked
27270         # properly (using netfree flag in osd_declare_destroy()
27271         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27272         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27273                 gawk '{print $3}')
27274         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27275         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27276         let "usedkb=usedkb-freekb"
27277         let "freekb=freekb/2"
27278         if let "freekb > 5000"; then
27279                 let "freekb=5000"
27280         fi
27281         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27282         trap cleanup_805 EXIT
27283         mkdir_on_mdt0 $DIR/$tdir
27284         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27285                 error "Can't set PFL layout"
27286         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27287         rm -rf $DIR/$tdir || error "not able to remove"
27288         do_facet $SINGLEMDS zfs set quota=$old $fsset
27289         trap 0
27290 }
27291 run_test 805 "ZFS can remove from full fs"
27292
27293 # Size-on-MDS test
27294 check_lsom_data()
27295 {
27296         local file=$1
27297         local expect=$(stat -c %s $file)
27298
27299         check_lsom_size $1 $expect
27300
27301         local blocks=$($LFS getsom -b $file)
27302         expect=$(stat -c %b $file)
27303         [[ $blocks == $expect ]] ||
27304                 error "$file expected blocks: $expect, got: $blocks"
27305 }
27306
27307 check_lsom_size()
27308 {
27309         local size
27310         local expect=$2
27311
27312         cancel_lru_locks mdc
27313
27314         size=$($LFS getsom -s $1)
27315         [[ $size == $expect ]] ||
27316                 error "$file expected size: $expect, got: $size"
27317 }
27318
27319 test_806() {
27320         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27321                 skip "Need MDS version at least 2.11.52"
27322
27323         local bs=1048576
27324
27325         touch $DIR/$tfile || error "touch $tfile failed"
27326
27327         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27328         save_lustre_params client "llite.*.xattr_cache" > $save
27329         lctl set_param llite.*.xattr_cache=0
27330         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27331
27332         # single-threaded write
27333         echo "Test SOM for single-threaded write"
27334         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27335                 error "write $tfile failed"
27336         check_lsom_size $DIR/$tfile $bs
27337
27338         local num=32
27339         local size=$(($num * $bs))
27340         local offset=0
27341         local i
27342
27343         echo "Test SOM for single client multi-threaded($num) write"
27344         $TRUNCATE $DIR/$tfile 0
27345         for ((i = 0; i < $num; i++)); do
27346                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27347                 local pids[$i]=$!
27348                 offset=$((offset + $bs))
27349         done
27350         for (( i=0; i < $num; i++ )); do
27351                 wait ${pids[$i]}
27352         done
27353         check_lsom_size $DIR/$tfile $size
27354
27355         $TRUNCATE $DIR/$tfile 0
27356         for ((i = 0; i < $num; i++)); do
27357                 offset=$((offset - $bs))
27358                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27359                 local pids[$i]=$!
27360         done
27361         for (( i=0; i < $num; i++ )); do
27362                 wait ${pids[$i]}
27363         done
27364         check_lsom_size $DIR/$tfile $size
27365
27366         # multi-client writes
27367         num=$(get_node_count ${CLIENTS//,/ })
27368         size=$(($num * $bs))
27369         offset=0
27370         i=0
27371
27372         echo "Test SOM for multi-client ($num) writes"
27373         $TRUNCATE $DIR/$tfile 0
27374         for client in ${CLIENTS//,/ }; do
27375                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27376                 local pids[$i]=$!
27377                 i=$((i + 1))
27378                 offset=$((offset + $bs))
27379         done
27380         for (( i=0; i < $num; i++ )); do
27381                 wait ${pids[$i]}
27382         done
27383         check_lsom_size $DIR/$tfile $offset
27384
27385         i=0
27386         $TRUNCATE $DIR/$tfile 0
27387         for client in ${CLIENTS//,/ }; do
27388                 offset=$((offset - $bs))
27389                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27390                 local pids[$i]=$!
27391                 i=$((i + 1))
27392         done
27393         for (( i=0; i < $num; i++ )); do
27394                 wait ${pids[$i]}
27395         done
27396         check_lsom_size $DIR/$tfile $size
27397
27398         # verify truncate
27399         echo "Test SOM for truncate"
27400         $TRUNCATE $DIR/$tfile 1048576
27401         check_lsom_size $DIR/$tfile 1048576
27402         $TRUNCATE $DIR/$tfile 1234
27403         check_lsom_size $DIR/$tfile 1234
27404
27405         # verify SOM blocks count
27406         echo "Verify SOM block count"
27407         $TRUNCATE $DIR/$tfile 0
27408         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27409                 error "failed to write file $tfile"
27410         check_lsom_data $DIR/$tfile
27411 }
27412 run_test 806 "Verify Lazy Size on MDS"
27413
27414 test_807() {
27415         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27416         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27417                 skip "Need MDS version at least 2.11.52"
27418
27419         # Registration step
27420         changelog_register || error "changelog_register failed"
27421         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27422         changelog_users $SINGLEMDS | grep -q $cl_user ||
27423                 error "User $cl_user not found in changelog_users"
27424
27425         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27426         save_lustre_params client "llite.*.xattr_cache" > $save
27427         lctl set_param llite.*.xattr_cache=0
27428         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27429
27430         rm -rf $DIR/$tdir || error "rm $tdir failed"
27431         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27432         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27433         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27434         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27435                 error "truncate $tdir/trunc failed"
27436
27437         local bs=1048576
27438         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27439                 error "write $tfile failed"
27440
27441         # multi-client wirtes
27442         local num=$(get_node_count ${CLIENTS//,/ })
27443         local offset=0
27444         local i=0
27445
27446         echo "Test SOM for multi-client ($num) writes"
27447         touch $DIR/$tfile || error "touch $tfile failed"
27448         $TRUNCATE $DIR/$tfile 0
27449         for client in ${CLIENTS//,/ }; do
27450                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27451                 local pids[$i]=$!
27452                 i=$((i + 1))
27453                 offset=$((offset + $bs))
27454         done
27455         for (( i=0; i < $num; i++ )); do
27456                 wait ${pids[$i]}
27457         done
27458
27459         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27460         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27461         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27462         check_lsom_data $DIR/$tdir/trunc
27463         check_lsom_data $DIR/$tdir/single_dd
27464         check_lsom_data $DIR/$tfile
27465
27466         rm -rf $DIR/$tdir
27467         # Deregistration step
27468         changelog_deregister || error "changelog_deregister failed"
27469 }
27470 run_test 807 "verify LSOM syncing tool"
27471
27472 check_som_nologged()
27473 {
27474         local lines=$($LFS changelog $FSNAME-MDT0000 |
27475                 grep 'x=trusted.som' | wc -l)
27476         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27477 }
27478
27479 test_808() {
27480         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27481                 skip "Need MDS version at least 2.11.55"
27482
27483         # Registration step
27484         changelog_register || error "changelog_register failed"
27485
27486         touch $DIR/$tfile || error "touch $tfile failed"
27487         check_som_nologged
27488
27489         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27490                 error "write $tfile failed"
27491         check_som_nologged
27492
27493         $TRUNCATE $DIR/$tfile 1234
27494         check_som_nologged
27495
27496         $TRUNCATE $DIR/$tfile 1048576
27497         check_som_nologged
27498
27499         # Deregistration step
27500         changelog_deregister || error "changelog_deregister failed"
27501 }
27502 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27503
27504 check_som_nodata()
27505 {
27506         $LFS getsom $1
27507         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27508 }
27509
27510 test_809() {
27511         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27512                 skip "Need MDS version at least 2.11.56"
27513
27514         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27515                 error "failed to create DoM-only file $DIR/$tfile"
27516         touch $DIR/$tfile || error "touch $tfile failed"
27517         check_som_nodata $DIR/$tfile
27518
27519         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27520                 error "write $tfile failed"
27521         check_som_nodata $DIR/$tfile
27522
27523         $TRUNCATE $DIR/$tfile 1234
27524         check_som_nodata $DIR/$tfile
27525
27526         $TRUNCATE $DIR/$tfile 4097
27527         check_som_nodata $DIR/$file
27528 }
27529 run_test 809 "Verify no SOM xattr store for DoM-only files"
27530
27531 test_810() {
27532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27533         $GSS && skip_env "could not run with gss"
27534         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27535                 skip "OST < 2.12.58 doesn't align checksum"
27536
27537         set_checksums 1
27538         stack_trap "set_checksums $ORIG_CSUM" EXIT
27539         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27540
27541         local csum
27542         local before
27543         local after
27544         for csum in $CKSUM_TYPES; do
27545                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27546                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27547                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27548                         eval set -- $i
27549                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27550                         before=$(md5sum $DIR/$tfile)
27551                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27552                         after=$(md5sum $DIR/$tfile)
27553                         [ "$before" == "$after" ] ||
27554                                 error "$csum: $before != $after bs=$1 seek=$2"
27555                 done
27556         done
27557 }
27558 run_test 810 "partial page writes on ZFS (LU-11663)"
27559
27560 test_812a() {
27561         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27562                 skip "OST < 2.12.51 doesn't support this fail_loc"
27563
27564         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27565         # ensure ost1 is connected
27566         stat $DIR/$tfile >/dev/null || error "can't stat"
27567         wait_osc_import_state client ost1 FULL
27568         # no locks, no reqs to let the connection idle
27569         cancel_lru_locks osc
27570
27571         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27572 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27573         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27574         wait_osc_import_state client ost1 CONNECTING
27575         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27576
27577         stat $DIR/$tfile >/dev/null || error "can't stat file"
27578 }
27579 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27580
27581 test_812b() { # LU-12378
27582         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27583                 skip "OST < 2.12.51 doesn't support this fail_loc"
27584
27585         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27586         # ensure ost1 is connected
27587         stat $DIR/$tfile >/dev/null || error "can't stat"
27588         wait_osc_import_state client ost1 FULL
27589         # no locks, no reqs to let the connection idle
27590         cancel_lru_locks osc
27591
27592         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27593 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27594         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27595         wait_osc_import_state client ost1 CONNECTING
27596         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27597
27598         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27599         wait_osc_import_state client ost1 IDLE
27600 }
27601 run_test 812b "do not drop no resend request for idle connect"
27602
27603 test_812c() {
27604         local old
27605
27606         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27607
27608         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27609         $LFS getstripe $DIR/$tfile
27610         $LCTL set_param osc.*.idle_timeout=10
27611         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27612         # ensure ost1 is connected
27613         stat $DIR/$tfile >/dev/null || error "can't stat"
27614         wait_osc_import_state client ost1 FULL
27615         # no locks, no reqs to let the connection idle
27616         cancel_lru_locks osc
27617
27618 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27619         $LCTL set_param fail_loc=0x80000533
27620         sleep 15
27621         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27622 }
27623 run_test 812c "idle import vs lock enqueue race"
27624
27625 test_813() {
27626         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27627         [ -z "$file_heat_sav" ] && skip "no file heat support"
27628
27629         local readsample
27630         local writesample
27631         local readbyte
27632         local writebyte
27633         local readsample1
27634         local writesample1
27635         local readbyte1
27636         local writebyte1
27637
27638         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27639         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27640
27641         $LCTL set_param -n llite.*.file_heat=1
27642         echo "Turn on file heat"
27643         echo "Period second: $period_second, Decay percentage: $decay_pct"
27644
27645         echo "QQQQ" > $DIR/$tfile
27646         echo "QQQQ" > $DIR/$tfile
27647         echo "QQQQ" > $DIR/$tfile
27648         cat $DIR/$tfile > /dev/null
27649         cat $DIR/$tfile > /dev/null
27650         cat $DIR/$tfile > /dev/null
27651         cat $DIR/$tfile > /dev/null
27652
27653         local out=$($LFS heat_get $DIR/$tfile)
27654
27655         $LFS heat_get $DIR/$tfile
27656         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27657         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27658         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27659         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27660
27661         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27662         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27663         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27664         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27665
27666         sleep $((period_second + 3))
27667         echo "Sleep $((period_second + 3)) seconds..."
27668         # The recursion formula to calculate the heat of the file f is as
27669         # follow:
27670         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27671         # Where Hi is the heat value in the period between time points i*I and
27672         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27673         # to the weight of Ci.
27674         out=$($LFS heat_get $DIR/$tfile)
27675         $LFS heat_get $DIR/$tfile
27676         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27677         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27678         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27679         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27680
27681         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27682                 error "read sample ($readsample) is wrong"
27683         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27684                 error "write sample ($writesample) is wrong"
27685         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27686                 error "read bytes ($readbyte) is wrong"
27687         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27688                 error "write bytes ($writebyte) is wrong"
27689
27690         echo "QQQQ" > $DIR/$tfile
27691         echo "QQQQ" > $DIR/$tfile
27692         echo "QQQQ" > $DIR/$tfile
27693         cat $DIR/$tfile > /dev/null
27694         cat $DIR/$tfile > /dev/null
27695         cat $DIR/$tfile > /dev/null
27696         cat $DIR/$tfile > /dev/null
27697
27698         sleep $((period_second + 3))
27699         echo "Sleep $((period_second + 3)) seconds..."
27700
27701         out=$($LFS heat_get $DIR/$tfile)
27702         $LFS heat_get $DIR/$tfile
27703         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27704         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27705         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27706         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27707
27708         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27709                 4 * $decay_pct) / 100") -eq 1 ] ||
27710                 error "read sample ($readsample1) is wrong"
27711         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27712                 3 * $decay_pct) / 100") -eq 1 ] ||
27713                 error "write sample ($writesample1) is wrong"
27714         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27715                 20 * $decay_pct) / 100") -eq 1 ] ||
27716                 error "read bytes ($readbyte1) is wrong"
27717         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27718                 15 * $decay_pct) / 100") -eq 1 ] ||
27719                 error "write bytes ($writebyte1) is wrong"
27720
27721         echo "Turn off file heat for the file $DIR/$tfile"
27722         $LFS heat_set -o $DIR/$tfile
27723
27724         echo "QQQQ" > $DIR/$tfile
27725         echo "QQQQ" > $DIR/$tfile
27726         echo "QQQQ" > $DIR/$tfile
27727         cat $DIR/$tfile > /dev/null
27728         cat $DIR/$tfile > /dev/null
27729         cat $DIR/$tfile > /dev/null
27730         cat $DIR/$tfile > /dev/null
27731
27732         out=$($LFS heat_get $DIR/$tfile)
27733         $LFS heat_get $DIR/$tfile
27734         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27735         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27736         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27737         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27738
27739         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27740         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27741         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27742         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27743
27744         echo "Trun on file heat for the file $DIR/$tfile"
27745         $LFS heat_set -O $DIR/$tfile
27746
27747         echo "QQQQ" > $DIR/$tfile
27748         echo "QQQQ" > $DIR/$tfile
27749         echo "QQQQ" > $DIR/$tfile
27750         cat $DIR/$tfile > /dev/null
27751         cat $DIR/$tfile > /dev/null
27752         cat $DIR/$tfile > /dev/null
27753         cat $DIR/$tfile > /dev/null
27754
27755         out=$($LFS heat_get $DIR/$tfile)
27756         $LFS heat_get $DIR/$tfile
27757         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27758         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27759         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27760         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27761
27762         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27763         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27764         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27765         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27766
27767         $LFS heat_set -c $DIR/$tfile
27768         $LCTL set_param -n llite.*.file_heat=0
27769         echo "Turn off file heat support for the Lustre filesystem"
27770
27771         echo "QQQQ" > $DIR/$tfile
27772         echo "QQQQ" > $DIR/$tfile
27773         echo "QQQQ" > $DIR/$tfile
27774         cat $DIR/$tfile > /dev/null
27775         cat $DIR/$tfile > /dev/null
27776         cat $DIR/$tfile > /dev/null
27777         cat $DIR/$tfile > /dev/null
27778
27779         out=$($LFS heat_get $DIR/$tfile)
27780         $LFS heat_get $DIR/$tfile
27781         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27782         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27783         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27784         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27785
27786         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27787         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27788         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27789         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27790
27791         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27792         rm -f $DIR/$tfile
27793 }
27794 run_test 813 "File heat verfication"
27795
27796 test_814()
27797 {
27798         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27799         echo -n y >> $DIR/$tfile
27800         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27801         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27802 }
27803 run_test 814 "sparse cp works as expected (LU-12361)"
27804
27805 test_815()
27806 {
27807         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27808         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27809 }
27810 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27811
27812 test_816() {
27813         local ost1_imp=$(get_osc_import_name client ost1)
27814         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27815                          cut -d'.' -f2)
27816
27817         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27818         # ensure ost1 is connected
27819
27820         stat $DIR/$tfile >/dev/null || error "can't stat"
27821         wait_osc_import_state client ost1 FULL
27822         # no locks, no reqs to let the connection idle
27823         cancel_lru_locks osc
27824         lru_resize_disable osc
27825         local before
27826         local now
27827         before=$($LCTL get_param -n \
27828                  ldlm.namespaces.$imp_name.lru_size)
27829
27830         wait_osc_import_state client ost1 IDLE
27831         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27832         now=$($LCTL get_param -n \
27833               ldlm.namespaces.$imp_name.lru_size)
27834         [ $before == $now ] || error "lru_size changed $before != $now"
27835 }
27836 run_test 816 "do not reset lru_resize on idle reconnect"
27837
27838 cleanup_817() {
27839         umount $tmpdir
27840         exportfs -u localhost:$DIR/nfsexp
27841         rm -rf $DIR/nfsexp
27842 }
27843
27844 test_817() {
27845         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27846
27847         mkdir -p $DIR/nfsexp
27848         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27849                 error "failed to export nfs"
27850
27851         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27852         stack_trap cleanup_817 EXIT
27853
27854         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27855                 error "failed to mount nfs to $tmpdir"
27856
27857         cp /bin/true $tmpdir
27858         $DIR/nfsexp/true || error "failed to execute 'true' command"
27859 }
27860 run_test 817 "nfsd won't cache write lock for exec file"
27861
27862 test_818() {
27863         test_mkdir -i0 -c1 $DIR/$tdir
27864         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
27865         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
27866         stop $SINGLEMDS
27867
27868         # restore osp-syn threads
27869         stack_trap "fail $SINGLEMDS"
27870
27871         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27872         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27873         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27874                 error "start $SINGLEMDS failed"
27875         rm -rf $DIR/$tdir
27876
27877         local testid=$(echo $TESTNAME | tr '_' ' ')
27878
27879         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
27880                 grep "run LFSCK" || error "run LFSCK is not suggested"
27881 }
27882 run_test 818 "unlink with failed llog"
27883
27884 test_819a() {
27885         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27886         cancel_lru_locks osc
27887         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27888         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27889         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27890         rm -f $TDIR/$tfile
27891 }
27892 run_test 819a "too big niobuf in read"
27893
27894 test_819b() {
27895         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27896         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27897         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27898         cancel_lru_locks osc
27899         sleep 1
27900         rm -f $TDIR/$tfile
27901 }
27902 run_test 819b "too big niobuf in write"
27903
27904
27905 function test_820_start_ost() {
27906         sleep 5
27907
27908         for num in $(seq $OSTCOUNT); do
27909                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27910         done
27911 }
27912
27913 test_820() {
27914         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27915
27916         mkdir $DIR/$tdir
27917         umount_client $MOUNT || error "umount failed"
27918         for num in $(seq $OSTCOUNT); do
27919                 stop ost$num
27920         done
27921
27922         # mount client with no active OSTs
27923         # so that the client can't initialize max LOV EA size
27924         # from OSC notifications
27925         mount_client $MOUNT || error "mount failed"
27926         # delay OST starting to keep this 0 max EA size for a while
27927         test_820_start_ost &
27928
27929         # create a directory on MDS2
27930         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27931                 error "Failed to create directory"
27932         # open intent should update default EA size
27933         # see mdc_update_max_ea_from_body()
27934         # notice this is the very first RPC to MDS2
27935         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27936         ret=$?
27937         echo $out
27938         # With SSK, this situation can lead to -EPERM being returned.
27939         # In that case, simply retry.
27940         if [ $ret -ne 0 ] && $SHARED_KEY; then
27941                 if echo "$out" | grep -q "not permitted"; then
27942                         cp /etc/services $DIR/$tdir/mds2
27943                         ret=$?
27944                 fi
27945         fi
27946         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27947 }
27948 run_test 820 "update max EA from open intent"
27949
27950 test_822() {
27951         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27952
27953         save_lustre_params mds1 \
27954                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27955         do_facet $SINGLEMDS "$LCTL set_param -n \
27956                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27957         do_facet $SINGLEMDS "$LCTL set_param -n \
27958                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27959
27960         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27961         local maxage=$(do_facet mds1 $LCTL get_param -n \
27962                        osp.$FSNAME-OST0000*MDT0000.maxage)
27963         sleep $((maxage + 1))
27964
27965         #define OBD_FAIL_NET_ERROR_RPC          0x532
27966         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27967
27968         stack_trap "restore_lustre_params < $p; rm $p"
27969
27970         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27971                       osp.$FSNAME-OST0000*MDT0000.create_count")
27972         for i in $(seq 1 $count); do
27973                 touch $DIR/$tfile.${i} || error "touch failed"
27974         done
27975 }
27976 run_test 822 "test precreate failure"
27977
27978 test_823() {
27979         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27980         local OST_MAX_PRECREATE=20000
27981
27982         save_lustre_params mds1 \
27983                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27984         do_facet $SINGLEMDS "$LCTL set_param -n \
27985                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
27986         do_facet $SINGLEMDS "$LCTL set_param -n \
27987                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
27988
27989         stack_trap "restore_lustre_params < $p; rm $p"
27990
27991         do_facet $SINGLEMDS "$LCTL set_param -n \
27992                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
27993
27994         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27995                       osp.$FSNAME-OST0000*MDT0000.create_count")
27996         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27997                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
27998         local expect_count=$(((($max/2)/256) * 256))
27999
28000         log "setting create_count to 100200:"
28001         log " -result- count: $count with max: $max, expecting: $expect_count"
28002
28003         [[ $count -eq expect_count ]] ||
28004                 error "Create count not set to max precreate."
28005 }
28006 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28007
28008 test_831() {
28009         local sync_changes=$(do_facet $SINGLEMDS \
28010                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28011
28012         [ "$sync_changes" -gt 100 ] &&
28013                 skip "Sync changes $sync_changes > 100 already"
28014
28015         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28016
28017         $LFS mkdir -i 0 $DIR/$tdir
28018         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28019
28020         save_lustre_params mds1 \
28021                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28022         save_lustre_params mds1 \
28023                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28024
28025         do_facet mds1 "$LCTL set_param -n \
28026                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28027                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28028         stack_trap "restore_lustre_params < $p" EXIT
28029
28030         createmany -o $DIR/$tdir/f- 1000
28031         unlinkmany $DIR/$tdir/f- 1000 &
28032         local UNLINK_PID=$!
28033
28034         while sleep 1; do
28035                 sync_changes=$(do_facet mds1 \
28036                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28037                 # the check in the code is racy, fail the test
28038                 # if the value above the limit by 10.
28039                 [ $sync_changes -gt 110 ] && {
28040                         kill -2 $UNLINK_PID
28041                         wait
28042                         error "osp changes throttling failed, $sync_changes>110"
28043                 }
28044                 kill -0 $UNLINK_PID 2> /dev/null || break
28045         done
28046         wait
28047 }
28048 run_test 831 "throttling unlink/setattr queuing on OSP"
28049
28050 #
28051 # tests that do cleanup/setup should be run at the end
28052 #
28053
28054 test_900() {
28055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28056         local ls
28057
28058         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28059         $LCTL set_param fail_loc=0x903
28060
28061         cancel_lru_locks MGC
28062
28063         FAIL_ON_ERROR=true cleanup
28064         FAIL_ON_ERROR=true setup
28065 }
28066 run_test 900 "umount should not race with any mgc requeue thread"
28067
28068 # LUS-6253/LU-11185
28069 test_901() {
28070         local old
28071         local count
28072         local oldc
28073         local newc
28074         local olds
28075         local news
28076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28077
28078         # some get_param have a bug to handle dot in param name
28079         cancel_lru_locks MGC
28080         old=$(mount -t lustre | wc -l)
28081         # 1 config+sptlrpc
28082         # 2 params
28083         # 3 nodemap
28084         # 4 IR
28085         old=$((old * 4))
28086         oldc=0
28087         count=0
28088         while [ $old -ne $oldc ]; do
28089                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28090                 sleep 1
28091                 ((count++))
28092                 if [ $count -ge $TIMEOUT ]; then
28093                         error "too large timeout"
28094                 fi
28095         done
28096         umount_client $MOUNT || error "umount failed"
28097         mount_client $MOUNT || error "mount failed"
28098         cancel_lru_locks MGC
28099         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28100
28101         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28102
28103         return 0
28104 }
28105 run_test 901 "don't leak a mgc lock on client umount"
28106
28107 # LU-13377
28108 test_902() {
28109         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28110                 skip "client does not have LU-13377 fix"
28111         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28112         $LCTL set_param fail_loc=0x1415
28113         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28114         cancel_lru_locks osc
28115         rm -f $DIR/$tfile
28116 }
28117 run_test 902 "test short write doesn't hang lustre"
28118
28119 # LU-14711
28120 test_903() {
28121         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28122         echo "blah" > $DIR/${tfile}-2
28123         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28124         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28125         $LCTL set_param fail_loc=0x417 fail_val=20
28126
28127         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28128         sleep 1 # To start the destroy
28129         wait_destroy_complete 150 || error "Destroy taking too long"
28130         cat $DIR/$tfile > /dev/null || error "Evicted"
28131 }
28132 run_test 903 "Test long page discard does not cause evictions"
28133
28134 test_904() {
28135         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28136         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28137                 grep -q project || skip "skip project quota not supported"
28138
28139         local testfile="$DIR/$tdir/$tfile"
28140         local xattr="trusted.projid"
28141         local projid
28142
28143         mkdir -p $DIR/$tdir
28144         touch $testfile
28145         #should be hidden when projid is 0
28146         $LFS project -p 0 $testfile ||
28147                 error "set $testfile project id failed"
28148         getfattr -m - $testfile | grep $xattr &&
28149                 error "do not show trusted.projid with project ID 0"
28150
28151         #still can getxattr explicitly
28152         projid=$(getfattr -n $xattr $testfile |
28153                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28154         [ $projid == "0" ] ||
28155                 error "projid expected 0 not $projid"
28156
28157         #set the projid via setxattr
28158         setfattr -n $xattr -v "1000" $testfile ||
28159                 error "setattr failed with $?"
28160         projid=($($LFS project $testfile))
28161         [ ${projid[0]} == "1000" ] ||
28162                 error "projid expected 1000 not $projid"
28163
28164         #check the new projid via getxattr
28165         $LFS project -p 1001 $testfile ||
28166                 error "set $testfile project id failed"
28167         projid=$(getfattr -n $xattr $testfile |
28168                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28169         [ $projid == "1001" ] ||
28170                 error "projid expected 1001 not $projid"
28171
28172         #try to set invalid projid
28173         setfattr -n $xattr -v "4294967295" $testfile &&
28174                 error "set invalid projid should fail"
28175
28176         #remove the xattr means setting projid to 0
28177         setfattr -x $xattr $testfile ||
28178                 error "setfattr failed with $?"
28179         projid=($($LFS project $testfile))
28180         [ ${projid[0]} == "0" ] ||
28181                 error "projid expected 0 not $projid"
28182
28183         #should be hidden when parent has inherit flag and same projid
28184         $LFS project -srp 1002 $DIR/$tdir ||
28185                 error "set $tdir project id failed"
28186         getfattr -m - $testfile | grep $xattr &&
28187                 error "do not show trusted.projid with inherit flag"
28188
28189         #still can getxattr explicitly
28190         projid=$(getfattr -n $xattr $testfile |
28191                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28192         [ $projid == "1002" ] ||
28193                 error "projid expected 1002 not $projid"
28194 }
28195 run_test 904 "virtual project ID xattr"
28196
28197 complete $SECONDS
28198 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28199 check_and_cleanup_lustre
28200 if [ "$I_MOUNTED" != "yes" ]; then
28201         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28202 fi
28203 exit_status