Whamcloud - gitweb
LU-15577 tests: fix interop issue
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11671
61         ALWAYS_EXCEPT+=" 45"
62         # bug number:    LU-14067 LU-14067
63         ALWAYS_EXCEPT+=" 400a     400b"
64 fi
65
66 # skip nfs tests on kernels >= 4.12.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
68         # bug number:   LU-12661
69         ALWAYS_EXCEPT+=" 817"
70 fi
71 # skip cgroup tests on RHEL8.1 kernels until they are fixed
72 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
73       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
74         # bug number:   LU-13063
75         ALWAYS_EXCEPT+=" 411"
76 fi
77
78 #skip ACL tests on RHEL8 and SLES15 until tests changed to use other users
79 if (( $(egrep -cw "^bin|^daemon" /etc/passwd) < 2 )); then
80         # bug number:   LU-15259 LU-15259
81         ALWAYS_EXCEPT+=" 103a  125   154a"
82 fi
83
84 #                                  5              12     8   12  15   (min)"
85 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
86
87 if [ "$mds1_FSTYPE" = "zfs" ]; then
88         # bug number for skipped test:
89         ALWAYS_EXCEPT+="              "
90         #                                               13    (min)"
91         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
92 fi
93
94 if [ "$ost1_FSTYPE" = "zfs" ]; then
95         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
96         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
97 fi
98
99 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
100
101 # Get the SLES distro version
102 #
103 # Returns a version string that should only be used in comparing
104 # strings returned by version_code()
105 sles_version_code()
106 {
107         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
108
109         # All SuSE Linux versions have one decimal. version_code expects two
110         local sles_version=$version.0
111         version_code $sles_version
112 }
113
114 # Check if we are running on Ubuntu or SLES so we can make decisions on
115 # what tests to run
116 if [ -r /etc/SuSE-release ]; then
117         sles_version=$(sles_version_code)
118         [ $sles_version -lt $(version_code 11.4.0) ] &&
119                 # bug number for skipped test: LU-4341
120                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
121         [ $sles_version -lt $(version_code 12.0.0) ] &&
122                 # bug number for skipped test: LU-3703
123                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
124 elif [ -r /etc/os-release ]; then
125         if grep -qi ubuntu /etc/os-release; then
126                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
127                                                 -e 's/^VERSION=//p' \
128                                                 /etc/os-release |
129                                                 awk '{ print $1 }'))
130
131                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
132                         # bug number for skipped test:
133                         #                LU-10334 LU-10366
134                         ALWAYS_EXCEPT+=" 103a     410"
135                 fi
136         fi
137 fi
138
139 build_test_filter
140 FAIL_ON_ERROR=false
141
142 cleanup() {
143         echo -n "cln.."
144         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
145         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
146 }
147 setup() {
148         echo -n "mnt.."
149         load_modules
150         setupall || exit 10
151         echo "done"
152 }
153
154 check_swap_layouts_support()
155 {
156         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
157                 skip "Does not support layout lock."
158 }
159
160 check_swap_layout_no_dom()
161 {
162         local FOLDER=$1
163         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
164         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
165 }
166
167 check_and_setup_lustre
168 DIR=${DIR:-$MOUNT}
169 assert_DIR
170
171 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
172
173 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
174 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
175 rm -rf $DIR/[Rdfs][0-9]*
176
177 # $RUNAS_ID may get set incorrectly somewhere else
178 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
179         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
180
181 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
182
183 if [ "${ONLY}" = "MOUNT" ] ; then
184         echo "Lustre is up, please go on"
185         exit
186 fi
187
188 echo "preparing for tests involving mounts"
189 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
190 touch $EXT2_DEV
191 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
192 echo # add a newline after mke2fs.
193
194 umask 077
195
196 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
197 lctl set_param debug=-1 2> /dev/null || true
198 test_0a() {
199         touch $DIR/$tfile
200         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
201         rm $DIR/$tfile
202         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
203 }
204 run_test 0a "touch; rm ====================="
205
206 test_0b() {
207         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
208         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
209 }
210 run_test 0b "chmod 0755 $DIR ============================="
211
212 test_0c() {
213         $LCTL get_param mdc.*.import | grep "state: FULL" ||
214                 error "import not FULL"
215         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
216                 error "bad target"
217 }
218 run_test 0c "check import proc"
219
220 test_0d() { # LU-3397
221         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
222                 skip "proc exports not supported before 2.10.57"
223
224         local mgs_exp="mgs.MGS.exports"
225         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
226         local exp_client_nid
227         local exp_client_version
228         local exp_val
229         local imp_val
230         local temp_imp=$DIR/$tfile.import
231         local temp_exp=$DIR/$tfile.export
232
233         # save mgc import file to $temp_imp
234         $LCTL get_param mgc.*.import | tee $temp_imp
235         # Check if client uuid is found in MGS export
236         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
237                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
238                         $client_uuid ] &&
239                         break;
240         done
241         # save mgs export file to $temp_exp
242         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
243
244         # Compare the value of field "connect_flags"
245         imp_val=$(grep "connect_flags" $temp_imp)
246         exp_val=$(grep "connect_flags" $temp_exp)
247         [ "$exp_val" == "$imp_val" ] ||
248                 error "export flags '$exp_val' != import flags '$imp_val'"
249
250         # Compare client versions.  Only compare top-3 fields for compatibility
251         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
252         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
253         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
254         [ "$exp_val" == "$imp_val" ] ||
255                 error "exp version '$exp_client_version'($exp_val) != " \
256                         "'$(lustre_build_version client)'($imp_val)"
257 }
258 run_test 0d "check export proc ============================="
259
260 test_0e() { # LU-13417
261         (( $MDSCOUNT > 1 )) ||
262                 skip "We need at least 2 MDTs for this test"
263
264         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
265                 skip "Need server version at least 2.14.51"
266
267         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
268         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
269
270         [ $default_lmv_count -eq 1 ] ||
271                 error "$MOUNT default stripe count $default_lmv_count"
272
273         [ $default_lmv_index -eq -1 ] ||
274                 error "$MOUNT default stripe index $default_lmv_index"
275
276         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
277         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
278
279         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
280         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
281
282         [ $mdt_index1 -eq $mdt_index2 ] &&
283                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
284
285         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
286 }
287 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
288
289 test_1() {
290         test_mkdir $DIR/$tdir
291         test_mkdir $DIR/$tdir/d2
292         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
293         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
294         rmdir $DIR/$tdir/d2
295         rmdir $DIR/$tdir
296         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
297 }
298 run_test 1 "mkdir; remkdir; rmdir"
299
300 test_2() {
301         test_mkdir $DIR/$tdir
302         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
303         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
304         rm -r $DIR/$tdir
305         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
306 }
307 run_test 2 "mkdir; touch; rmdir; check file"
308
309 test_3() {
310         test_mkdir $DIR/$tdir
311         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
312         touch $DIR/$tdir/$tfile
313         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
314         rm -r $DIR/$tdir
315         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
316 }
317 run_test 3 "mkdir; touch; rmdir; check dir"
318
319 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
320 test_4() {
321         test_mkdir -i 1 $DIR/$tdir
322
323         touch $DIR/$tdir/$tfile ||
324                 error "Create file under remote directory failed"
325
326         rmdir $DIR/$tdir &&
327                 error "Expect error removing in-use dir $DIR/$tdir"
328
329         test -d $DIR/$tdir || error "Remote directory disappeared"
330
331         rm -rf $DIR/$tdir || error "remove remote dir error"
332 }
333 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
334
335 test_5() {
336         test_mkdir $DIR/$tdir
337         test_mkdir $DIR/$tdir/d2
338         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
339         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
340         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
341 }
342 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
343
344 test_6a() {
345         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
346         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
347         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
348                 error "$tfile does not have perm 0666 or UID $UID"
349         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
350         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
351                 error "$tfile should be 0666 and owned by UID $UID"
352 }
353 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
354
355 test_6c() {
356         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
357
358         touch $DIR/$tfile
359         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
360         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
361                 error "$tfile should be owned by UID $RUNAS_ID"
362         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
363         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
364                 error "$tfile should be owned by UID $RUNAS_ID"
365 }
366 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
367
368 test_6e() {
369         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
370
371         touch $DIR/$tfile
372         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
373         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
374                 error "$tfile should be owned by GID $UID"
375         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
376         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
377                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
378 }
379 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
380
381 test_6g() {
382         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
383
384         test_mkdir $DIR/$tdir
385         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
386         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
387         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
388         test_mkdir $DIR/$tdir/d/subdir
389         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
390                 error "$tdir/d/subdir should be GID $RUNAS_GID"
391         if [[ $MDSCOUNT -gt 1 ]]; then
392                 # check remote dir sgid inherite
393                 $LFS mkdir -i 0 $DIR/$tdir.local ||
394                         error "mkdir $tdir.local failed"
395                 chmod g+s $DIR/$tdir.local ||
396                         error "chmod $tdir.local failed"
397                 chgrp $RUNAS_GID $DIR/$tdir.local ||
398                         error "chgrp $tdir.local failed"
399                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
400                         error "mkdir $tdir.remote failed"
401                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
402                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
403                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
404                         error "$tdir.remote should be mode 02755"
405         fi
406 }
407 run_test 6g "verify new dir in sgid dir inherits group"
408
409 test_6h() { # bug 7331
410         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
411
412         touch $DIR/$tfile || error "touch failed"
413         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
414         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
415                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
416         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
417                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
418 }
419 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
420
421 test_7a() {
422         test_mkdir $DIR/$tdir
423         $MCREATE $DIR/$tdir/$tfile
424         chmod 0666 $DIR/$tdir/$tfile
425         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
426                 error "$tdir/$tfile should be mode 0666"
427 }
428 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
429
430 test_7b() {
431         if [ ! -d $DIR/$tdir ]; then
432                 test_mkdir $DIR/$tdir
433         fi
434         $MCREATE $DIR/$tdir/$tfile
435         echo -n foo > $DIR/$tdir/$tfile
436         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
437         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
438 }
439 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
440
441 test_8() {
442         test_mkdir $DIR/$tdir
443         touch $DIR/$tdir/$tfile
444         chmod 0666 $DIR/$tdir/$tfile
445         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
446                 error "$tfile mode not 0666"
447 }
448 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
449
450 test_9() {
451         test_mkdir $DIR/$tdir
452         test_mkdir $DIR/$tdir/d2
453         test_mkdir $DIR/$tdir/d2/d3
454         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
455 }
456 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
457
458 test_10() {
459         test_mkdir $DIR/$tdir
460         test_mkdir $DIR/$tdir/d2
461         touch $DIR/$tdir/d2/$tfile
462         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
463                 error "$tdir/d2/$tfile not a file"
464 }
465 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
466
467 test_11() {
468         test_mkdir $DIR/$tdir
469         test_mkdir $DIR/$tdir/d2
470         chmod 0666 $DIR/$tdir/d2
471         chmod 0705 $DIR/$tdir/d2
472         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
473                 error "$tdir/d2 mode not 0705"
474 }
475 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
476
477 test_12() {
478         test_mkdir $DIR/$tdir
479         touch $DIR/$tdir/$tfile
480         chmod 0666 $DIR/$tdir/$tfile
481         chmod 0654 $DIR/$tdir/$tfile
482         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
483                 error "$tdir/d2 mode not 0654"
484 }
485 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
486
487 test_13() {
488         test_mkdir $DIR/$tdir
489         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
490         >  $DIR/$tdir/$tfile
491         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
492                 error "$tdir/$tfile size not 0 after truncate"
493 }
494 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
495
496 test_14() {
497         test_mkdir $DIR/$tdir
498         touch $DIR/$tdir/$tfile
499         rm $DIR/$tdir/$tfile
500         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
501 }
502 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
503
504 test_15() {
505         test_mkdir $DIR/$tdir
506         touch $DIR/$tdir/$tfile
507         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
508         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
509                 error "$tdir/${tfile_2} not a file after rename"
510         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
511 }
512 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
513
514 test_16() {
515         test_mkdir $DIR/$tdir
516         touch $DIR/$tdir/$tfile
517         rm -rf $DIR/$tdir/$tfile
518         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
519 }
520 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
521
522 test_17a() {
523         test_mkdir $DIR/$tdir
524         touch $DIR/$tdir/$tfile
525         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
526         ls -l $DIR/$tdir
527         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
528                 error "$tdir/l-exist not a symlink"
529         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
530                 error "$tdir/l-exist not referencing a file"
531         rm -f $DIR/$tdir/l-exist
532         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
533 }
534 run_test 17a "symlinks: create, remove (real)"
535
536 test_17b() {
537         test_mkdir $DIR/$tdir
538         ln -s no-such-file $DIR/$tdir/l-dangle
539         ls -l $DIR/$tdir
540         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
541                 error "$tdir/l-dangle not referencing no-such-file"
542         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
543                 error "$tdir/l-dangle not referencing non-existent file"
544         rm -f $DIR/$tdir/l-dangle
545         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
546 }
547 run_test 17b "symlinks: create, remove (dangling)"
548
549 test_17c() { # bug 3440 - don't save failed open RPC for replay
550         test_mkdir $DIR/$tdir
551         ln -s foo $DIR/$tdir/$tfile
552         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
553 }
554 run_test 17c "symlinks: open dangling (should return error)"
555
556 test_17d() {
557         test_mkdir $DIR/$tdir
558         ln -s foo $DIR/$tdir/$tfile
559         touch $DIR/$tdir/$tfile || error "creating to new symlink"
560 }
561 run_test 17d "symlinks: create dangling"
562
563 test_17e() {
564         test_mkdir $DIR/$tdir
565         local foo=$DIR/$tdir/$tfile
566         ln -s $foo $foo || error "create symlink failed"
567         ls -l $foo || error "ls -l failed"
568         ls $foo && error "ls not failed" || true
569 }
570 run_test 17e "symlinks: create recursive symlink (should return error)"
571
572 test_17f() {
573         test_mkdir $DIR/$tdir
574         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
575         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
576         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
577         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
578         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
579         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
580         ls -l  $DIR/$tdir
581 }
582 run_test 17f "symlinks: long and very long symlink name"
583
584 # str_repeat(S, N) generate a string that is string S repeated N times
585 str_repeat() {
586         local s=$1
587         local n=$2
588         local ret=''
589         while [ $((n -= 1)) -ge 0 ]; do
590                 ret=$ret$s
591         done
592         echo $ret
593 }
594
595 # Long symlinks and LU-2241
596 test_17g() {
597         test_mkdir $DIR/$tdir
598         local TESTS="59 60 61 4094 4095"
599
600         # Fix for inode size boundary in 2.1.4
601         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
602                 TESTS="4094 4095"
603
604         # Patch not applied to 2.2 or 2.3 branches
605         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
606         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
607                 TESTS="4094 4095"
608
609         for i in $TESTS; do
610                 local SYMNAME=$(str_repeat 'x' $i)
611                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
612                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
613         done
614 }
615 run_test 17g "symlinks: really long symlink name and inode boundaries"
616
617 test_17h() { #bug 17378
618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
619         remote_mds_nodsh && skip "remote MDS with nodsh"
620
621         local mdt_idx
622
623         test_mkdir $DIR/$tdir
624         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
625         $LFS setstripe -c -1 $DIR/$tdir
626         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
627         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
628         touch $DIR/$tdir/$tfile || true
629 }
630 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
631
632 test_17i() { #bug 20018
633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
634         remote_mds_nodsh && skip "remote MDS with nodsh"
635
636         local foo=$DIR/$tdir/$tfile
637         local mdt_idx
638
639         test_mkdir -c1 $DIR/$tdir
640         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
641         ln -s $foo $foo || error "create symlink failed"
642 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
643         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
644         ls -l $foo && error "error not detected"
645         return 0
646 }
647 run_test 17i "don't panic on short symlink (should return error)"
648
649 test_17k() { #bug 22301
650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
651         [[ -z "$(which rsync 2>/dev/null)" ]] &&
652                 skip "no rsync command"
653         rsync --help | grep -q xattr ||
654                 skip_env "$(rsync --version | head -n1) does not support xattrs"
655         test_mkdir $DIR/$tdir
656         test_mkdir $DIR/$tdir.new
657         touch $DIR/$tdir/$tfile
658         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
659         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
660                 error "rsync failed with xattrs enabled"
661 }
662 run_test 17k "symlinks: rsync with xattrs enabled"
663
664 test_17l() { # LU-279
665         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
666                 skip "no getfattr command"
667
668         test_mkdir $DIR/$tdir
669         touch $DIR/$tdir/$tfile
670         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
671         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
672                 # -h to not follow symlinks. -m '' to list all the xattrs.
673                 # grep to remove first line: '# file: $path'.
674                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
675                 do
676                         lgetxattr_size_check $path $xattr ||
677                                 error "lgetxattr_size_check $path $xattr failed"
678                 done
679         done
680 }
681 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
682
683 # LU-1540
684 test_17m() {
685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
686         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
687         remote_mds_nodsh && skip "remote MDS with nodsh"
688         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
689         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
690                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
691
692         local short_sym="0123456789"
693         local wdir=$DIR/$tdir
694         local i
695
696         test_mkdir $wdir
697         long_sym=$short_sym
698         # create a long symlink file
699         for ((i = 0; i < 4; ++i)); do
700                 long_sym=${long_sym}${long_sym}
701         done
702
703         echo "create 512 short and long symlink files under $wdir"
704         for ((i = 0; i < 256; ++i)); do
705                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
706                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
707         done
708
709         echo "erase them"
710         rm -f $wdir/*
711         sync
712         wait_delete_completed
713
714         echo "recreate the 512 symlink files with a shorter string"
715         for ((i = 0; i < 512; ++i)); do
716                 # rewrite the symlink file with a shorter string
717                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
718                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
719         done
720
721         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
722
723         echo "stop and checking mds${mds_index}:"
724         # e2fsck should not return error
725         stop mds${mds_index}
726         local devname=$(mdsdevname $mds_index)
727         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
728         rc=$?
729
730         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
731                 error "start mds${mds_index} failed"
732         df $MOUNT > /dev/null 2>&1
733         [ $rc -eq 0 ] ||
734                 error "e2fsck detected error for short/long symlink: rc=$rc"
735         rm -f $wdir/*
736 }
737 run_test 17m "run e2fsck against MDT which contains short/long symlink"
738
739 check_fs_consistency_17n() {
740         local mdt_index
741         local rc=0
742
743         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
744         # so it only check MDT1/MDT2 instead of all of MDTs.
745         for mdt_index in 1 2; do
746                 # e2fsck should not return error
747                 stop mds${mdt_index}
748                 local devname=$(mdsdevname $mdt_index)
749                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
750                         rc=$((rc + $?))
751
752                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
753                         error "mount mds$mdt_index failed"
754                 df $MOUNT > /dev/null 2>&1
755         done
756         return $rc
757 }
758
759 test_17n() {
760         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
762         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
763         remote_mds_nodsh && skip "remote MDS with nodsh"
764         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
765         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
766                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
767
768         local i
769
770         test_mkdir $DIR/$tdir
771         for ((i=0; i<10; i++)); do
772                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
773                         error "create remote dir error $i"
774                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
775                         error "create files under remote dir failed $i"
776         done
777
778         check_fs_consistency_17n ||
779                 error "e2fsck report error after create files under remote dir"
780
781         for ((i = 0; i < 10; i++)); do
782                 rm -rf $DIR/$tdir/remote_dir_${i} ||
783                         error "destroy remote dir error $i"
784         done
785
786         check_fs_consistency_17n ||
787                 error "e2fsck report error after unlink files under remote dir"
788
789         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
790                 skip "lustre < 2.4.50 does not support migrate mv"
791
792         for ((i = 0; i < 10; i++)); do
793                 mkdir -p $DIR/$tdir/remote_dir_${i}
794                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
795                         error "create files under remote dir failed $i"
796                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
797                         error "migrate remote dir error $i"
798         done
799         check_fs_consistency_17n || error "e2fsck report error after migration"
800
801         for ((i = 0; i < 10; i++)); do
802                 rm -rf $DIR/$tdir/remote_dir_${i} ||
803                         error "destroy remote dir error $i"
804         done
805
806         check_fs_consistency_17n || error "e2fsck report error after unlink"
807 }
808 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
809
810 test_17o() {
811         remote_mds_nodsh && skip "remote MDS with nodsh"
812         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
813                 skip "Need MDS version at least 2.3.64"
814
815         local wdir=$DIR/${tdir}o
816         local mdt_index
817         local rc=0
818
819         test_mkdir $wdir
820         touch $wdir/$tfile
821         mdt_index=$($LFS getstripe -m $wdir/$tfile)
822         mdt_index=$((mdt_index + 1))
823
824         cancel_lru_locks mdc
825         #fail mds will wait the failover finish then set
826         #following fail_loc to avoid interfer the recovery process.
827         fail mds${mdt_index}
828
829         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
830         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
831         ls -l $wdir/$tfile && rc=1
832         do_facet mds${mdt_index} lctl set_param fail_loc=0
833         [[ $rc -eq 0 ]] || error "stat file should fail"
834 }
835 run_test 17o "stat file with incompat LMA feature"
836
837 test_18() {
838         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
839         ls $DIR || error "Failed to ls $DIR: $?"
840 }
841 run_test 18 "touch .../f ; ls ... =============================="
842
843 test_19a() {
844         touch $DIR/$tfile
845         ls -l $DIR
846         rm $DIR/$tfile
847         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
848 }
849 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
850
851 test_19b() {
852         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
853 }
854 run_test 19b "ls -l .../f19 (should return error) =============="
855
856 test_19c() {
857         [ $RUNAS_ID -eq $UID ] &&
858                 skip_env "RUNAS_ID = UID = $UID -- skipping"
859
860         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
861 }
862 run_test 19c "$RUNAS touch .../f19 (should return error) =="
863
864 test_19d() {
865         cat $DIR/f19 && error || true
866 }
867 run_test 19d "cat .../f19 (should return error) =============="
868
869 test_20() {
870         touch $DIR/$tfile
871         rm $DIR/$tfile
872         touch $DIR/$tfile
873         rm $DIR/$tfile
874         touch $DIR/$tfile
875         rm $DIR/$tfile
876         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
877 }
878 run_test 20 "touch .../f ; ls -l ..."
879
880 test_21() {
881         test_mkdir $DIR/$tdir
882         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
883         ln -s dangle $DIR/$tdir/link
884         echo foo >> $DIR/$tdir/link
885         cat $DIR/$tdir/dangle
886         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
887         $CHECKSTAT -f -t file $DIR/$tdir/link ||
888                 error "$tdir/link not linked to a file"
889 }
890 run_test 21 "write to dangling link"
891
892 test_22() {
893         local wdir=$DIR/$tdir
894         test_mkdir $wdir
895         chown $RUNAS_ID:$RUNAS_GID $wdir
896         (cd $wdir || error "cd $wdir failed";
897                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
898                 $RUNAS tar xf -)
899         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
900         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
901         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
902                 error "checkstat -u failed"
903 }
904 run_test 22 "unpack tar archive as non-root user"
905
906 # was test_23
907 test_23a() {
908         test_mkdir $DIR/$tdir
909         local file=$DIR/$tdir/$tfile
910
911         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
912         openfile -f O_CREAT:O_EXCL $file &&
913                 error "$file recreate succeeded" || true
914 }
915 run_test 23a "O_CREAT|O_EXCL in subdir"
916
917 test_23b() { # bug 18988
918         test_mkdir $DIR/$tdir
919         local file=$DIR/$tdir/$tfile
920
921         rm -f $file
922         echo foo > $file || error "write filed"
923         echo bar >> $file || error "append filed"
924         $CHECKSTAT -s 8 $file || error "wrong size"
925         rm $file
926 }
927 run_test 23b "O_APPEND check"
928
929 # LU-9409, size with O_APPEND and tiny writes
930 test_23c() {
931         local file=$DIR/$tfile
932
933         # single dd
934         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
935         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
936         rm -f $file
937
938         # racing tiny writes
939         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
940         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
941         wait
942         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
943         rm -f $file
944
945         #racing tiny & normal writes
946         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
947         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
948         wait
949         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
950         rm -f $file
951
952         #racing tiny & normal writes 2, ugly numbers
953         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
954         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
955         wait
956         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
957         rm -f $file
958 }
959 run_test 23c "O_APPEND size checks for tiny writes"
960
961 # LU-11069 file offset is correct after appending writes
962 test_23d() {
963         local file=$DIR/$tfile
964         local offset
965
966         echo CentaurHauls > $file
967         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
968         if ((offset != 26)); then
969                 error "wrong offset, expected 26, got '$offset'"
970         fi
971 }
972 run_test 23d "file offset is correct after appending writes"
973
974 # rename sanity
975 test_24a() {
976         echo '-- same directory rename'
977         test_mkdir $DIR/$tdir
978         touch $DIR/$tdir/$tfile.1
979         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
980         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
981 }
982 run_test 24a "rename file to non-existent target"
983
984 test_24b() {
985         test_mkdir $DIR/$tdir
986         touch $DIR/$tdir/$tfile.{1,2}
987         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
988         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
989         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
990 }
991 run_test 24b "rename file to existing target"
992
993 test_24c() {
994         test_mkdir $DIR/$tdir
995         test_mkdir $DIR/$tdir/d$testnum.1
996         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
997         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
998         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
999 }
1000 run_test 24c "rename directory to non-existent target"
1001
1002 test_24d() {
1003         test_mkdir -c1 $DIR/$tdir
1004         test_mkdir -c1 $DIR/$tdir/d$testnum.1
1005         test_mkdir -c1 $DIR/$tdir/d$testnum.2
1006         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1007         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1008         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1009 }
1010 run_test 24d "rename directory to existing target"
1011
1012 test_24e() {
1013         echo '-- cross directory renames --'
1014         test_mkdir $DIR/R5a
1015         test_mkdir $DIR/R5b
1016         touch $DIR/R5a/f
1017         mv $DIR/R5a/f $DIR/R5b/g
1018         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1019         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1020 }
1021 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1022
1023 test_24f() {
1024         test_mkdir $DIR/R6a
1025         test_mkdir $DIR/R6b
1026         touch $DIR/R6a/f $DIR/R6b/g
1027         mv $DIR/R6a/f $DIR/R6b/g
1028         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1029         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1030 }
1031 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1032
1033 test_24g() {
1034         test_mkdir $DIR/R7a
1035         test_mkdir $DIR/R7b
1036         test_mkdir $DIR/R7a/d
1037         mv $DIR/R7a/d $DIR/R7b/e
1038         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1039         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1040 }
1041 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1042
1043 test_24h() {
1044         test_mkdir -c1 $DIR/R8a
1045         test_mkdir -c1 $DIR/R8b
1046         test_mkdir -c1 $DIR/R8a/d
1047         test_mkdir -c1 $DIR/R8b/e
1048         mrename $DIR/R8a/d $DIR/R8b/e
1049         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1050         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1051 }
1052 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1053
1054 test_24i() {
1055         echo "-- rename error cases"
1056         test_mkdir $DIR/R9
1057         test_mkdir $DIR/R9/a
1058         touch $DIR/R9/f
1059         mrename $DIR/R9/f $DIR/R9/a
1060         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1061         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1062         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1063 }
1064 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1065
1066 test_24j() {
1067         test_mkdir $DIR/R10
1068         mrename $DIR/R10/f $DIR/R10/g
1069         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1070         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1071         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1072 }
1073 run_test 24j "source does not exist ============================"
1074
1075 test_24k() {
1076         test_mkdir $DIR/R11a
1077         test_mkdir $DIR/R11a/d
1078         touch $DIR/R11a/f
1079         mv $DIR/R11a/f $DIR/R11a/d
1080         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1081         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1082 }
1083 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1084
1085 # bug 2429 - rename foo foo foo creates invalid file
1086 test_24l() {
1087         f="$DIR/f24l"
1088         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1089 }
1090 run_test 24l "Renaming a file to itself ========================"
1091
1092 test_24m() {
1093         f="$DIR/f24m"
1094         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1095         # on ext3 this does not remove either the source or target files
1096         # though the "expected" operation would be to remove the source
1097         $CHECKSTAT -t file ${f} || error "${f} missing"
1098         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1099 }
1100 run_test 24m "Renaming a file to a hard link to itself ========="
1101
1102 test_24n() {
1103     f="$DIR/f24n"
1104     # this stats the old file after it was renamed, so it should fail
1105     touch ${f}
1106     $CHECKSTAT ${f} || error "${f} missing"
1107     mv ${f} ${f}.rename
1108     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1109     $CHECKSTAT -a ${f} || error "${f} exists"
1110 }
1111 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1112
1113 test_24o() {
1114         test_mkdir $DIR/$tdir
1115         rename_many -s random -v -n 10 $DIR/$tdir
1116 }
1117 run_test 24o "rename of files during htree split"
1118
1119 test_24p() {
1120         test_mkdir $DIR/R12a
1121         test_mkdir $DIR/R12b
1122         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1123         mrename $DIR/R12a $DIR/R12b
1124         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1125         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1126         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1127         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1128 }
1129 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1130
1131 cleanup_multiop_pause() {
1132         trap 0
1133         kill -USR1 $MULTIPID
1134 }
1135
1136 test_24q() {
1137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1138
1139         test_mkdir $DIR/R13a
1140         test_mkdir $DIR/R13b
1141         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1142         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1143         MULTIPID=$!
1144
1145         trap cleanup_multiop_pause EXIT
1146         mrename $DIR/R13a $DIR/R13b
1147         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1148         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1149         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1150         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1151         cleanup_multiop_pause
1152         wait $MULTIPID || error "multiop close failed"
1153 }
1154 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1155
1156 test_24r() { #bug 3789
1157         test_mkdir $DIR/R14a
1158         test_mkdir $DIR/R14a/b
1159         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1160         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1161         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1162 }
1163 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1164
1165 test_24s() {
1166         test_mkdir $DIR/R15a
1167         test_mkdir $DIR/R15a/b
1168         test_mkdir $DIR/R15a/b/c
1169         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1170         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1171         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1172 }
1173 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1174 test_24t() {
1175         test_mkdir $DIR/R16a
1176         test_mkdir $DIR/R16a/b
1177         test_mkdir $DIR/R16a/b/c
1178         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1179         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1180         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1181 }
1182 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1183
1184 test_24u() { # bug12192
1185         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1186         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1187 }
1188 run_test 24u "create stripe file"
1189
1190 simple_cleanup_common() {
1191         local createmany=$1
1192         local rc=0
1193
1194         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1195
1196         local start=$SECONDS
1197
1198         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1199         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1200         rc=$?
1201         wait_delete_completed
1202         echo "cleanup time $((SECONDS - start))"
1203         return $rc
1204 }
1205
1206 max_pages_per_rpc() {
1207         local mdtname="$(printf "MDT%04x" ${1:-0})"
1208         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1209 }
1210
1211 test_24v() {
1212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1213
1214         local nrfiles=${COUNT:-100000}
1215         local fname="$DIR/$tdir/$tfile"
1216
1217         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1218         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1219
1220         test_mkdir "$(dirname $fname)"
1221         # assume MDT0000 has the fewest inodes
1222         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1223         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1224         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1225
1226         stack_trap "simple_cleanup_common $nrfiles"
1227
1228         createmany -m "$fname" $nrfiles
1229
1230         cancel_lru_locks mdc
1231         lctl set_param mdc.*.stats clear
1232
1233         # was previously test_24D: LU-6101
1234         # readdir() returns correct number of entries after cursor reload
1235         local num_ls=$(ls $DIR/$tdir | wc -l)
1236         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1237         local num_all=$(ls -a $DIR/$tdir | wc -l)
1238         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1239                 [ $num_all -ne $((nrfiles + 2)) ]; then
1240                         error "Expected $nrfiles files, got $num_ls " \
1241                                 "($num_uniq unique $num_all .&..)"
1242         fi
1243         # LU-5 large readdir
1244         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1245         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1246         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1247         # take into account of overhead in lu_dirpage header and end mark in
1248         # each page, plus one in rpc_num calculation.
1249         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1250         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1251         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1252         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1253         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1254         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1255         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1256         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1257                 error "large readdir doesn't take effect: " \
1258                       "$mds_readpage should be about $rpc_max"
1259 }
1260 run_test 24v "list large directory (test hash collision, b=17560)"
1261
1262 test_24w() { # bug21506
1263         SZ1=234852
1264         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1265         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1266         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1267         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1268         [[ "$SZ1" -eq "$SZ2" ]] ||
1269                 error "Error reading at the end of the file $tfile"
1270 }
1271 run_test 24w "Reading a file larger than 4Gb"
1272
1273 test_24x() {
1274         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1276         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1277                 skip "Need MDS version at least 2.7.56"
1278
1279         local MDTIDX=1
1280         local remote_dir=$DIR/$tdir/remote_dir
1281
1282         test_mkdir $DIR/$tdir
1283         $LFS mkdir -i $MDTIDX $remote_dir ||
1284                 error "create remote directory failed"
1285
1286         test_mkdir $DIR/$tdir/src_dir
1287         touch $DIR/$tdir/src_file
1288         test_mkdir $remote_dir/tgt_dir
1289         touch $remote_dir/tgt_file
1290
1291         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1292                 error "rename dir cross MDT failed!"
1293
1294         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1295                 error "rename file cross MDT failed!"
1296
1297         touch $DIR/$tdir/ln_file
1298         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1299                 error "ln file cross MDT failed"
1300
1301         rm -rf $DIR/$tdir || error "Can not delete directories"
1302 }
1303 run_test 24x "cross MDT rename/link"
1304
1305 test_24y() {
1306         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1308
1309         local remote_dir=$DIR/$tdir/remote_dir
1310         local mdtidx=1
1311
1312         test_mkdir $DIR/$tdir
1313         $LFS mkdir -i $mdtidx $remote_dir ||
1314                 error "create remote directory failed"
1315
1316         test_mkdir $remote_dir/src_dir
1317         touch $remote_dir/src_file
1318         test_mkdir $remote_dir/tgt_dir
1319         touch $remote_dir/tgt_file
1320
1321         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1322                 error "rename subdir in the same remote dir failed!"
1323
1324         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1325                 error "rename files in the same remote dir failed!"
1326
1327         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1328                 error "link files in the same remote dir failed!"
1329
1330         rm -rf $DIR/$tdir || error "Can not delete directories"
1331 }
1332 run_test 24y "rename/link on the same dir should succeed"
1333
1334 test_24z() {
1335         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1336         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1337                 skip "Need MDS version at least 2.12.51"
1338
1339         local index
1340
1341         for index in 0 1; do
1342                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1343                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1344         done
1345
1346         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1347
1348         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1349         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1350
1351         local mdts=$(comma_list $(mdts_nodes))
1352
1353         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1354         stack_trap "do_nodes $mdts $LCTL \
1355                 set_param mdt.*.enable_remote_rename=1" EXIT
1356
1357         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1358
1359         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1360         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1361 }
1362 run_test 24z "cross-MDT rename is done as cp"
1363
1364 test_24A() { # LU-3182
1365         local NFILES=5000
1366
1367         test_mkdir $DIR/$tdir
1368         stack_trap "simple_cleanup_common $NFILES"
1369         createmany -m $DIR/$tdir/$tfile $NFILES
1370         local t=$(ls $DIR/$tdir | wc -l)
1371         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1372         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1373
1374         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1375                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1376 }
1377 run_test 24A "readdir() returns correct number of entries."
1378
1379 test_24B() { # LU-4805
1380         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1381
1382         local count
1383
1384         test_mkdir $DIR/$tdir
1385         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1386                 error "create striped dir failed"
1387
1388         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1389         [ $count -eq 2 ] || error "Expected 2, got $count"
1390
1391         touch $DIR/$tdir/striped_dir/a
1392
1393         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1394         [ $count -eq 3 ] || error "Expected 3, got $count"
1395
1396         touch $DIR/$tdir/striped_dir/.f
1397
1398         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1399         [ $count -eq 4 ] || error "Expected 4, got $count"
1400
1401         rm -rf $DIR/$tdir || error "Can not delete directories"
1402 }
1403 run_test 24B "readdir for striped dir return correct number of entries"
1404
1405 test_24C() {
1406         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1407
1408         mkdir $DIR/$tdir
1409         mkdir $DIR/$tdir/d0
1410         mkdir $DIR/$tdir/d1
1411
1412         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1413                 error "create striped dir failed"
1414
1415         cd $DIR/$tdir/d0/striped_dir
1416
1417         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1418         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1419         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1420
1421         [ "$d0_ino" = "$parent_ino" ] ||
1422                 error ".. wrong, expect $d0_ino, get $parent_ino"
1423
1424         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1425                 error "mv striped dir failed"
1426
1427         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1428
1429         [ "$d1_ino" = "$parent_ino" ] ||
1430                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1431 }
1432 run_test 24C "check .. in striped dir"
1433
1434 test_24E() {
1435         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1437
1438         mkdir -p $DIR/$tdir
1439         mkdir $DIR/$tdir/src_dir
1440         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1441                 error "create remote source failed"
1442
1443         touch $DIR/$tdir/src_dir/src_child/a
1444
1445         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1446                 error "create remote target dir failed"
1447
1448         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1449                 error "create remote target child failed"
1450
1451         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1452                 error "rename dir cross MDT failed!"
1453
1454         find $DIR/$tdir
1455
1456         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1457                 error "src_child still exists after rename"
1458
1459         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1460                 error "missing file(a) after rename"
1461
1462         rm -rf $DIR/$tdir || error "Can not delete directories"
1463 }
1464 run_test 24E "cross MDT rename/link"
1465
1466 test_24F () {
1467         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1468
1469         local repeats=1000
1470         [ "$SLOW" = "no" ] && repeats=100
1471
1472         mkdir -p $DIR/$tdir
1473
1474         echo "$repeats repeats"
1475         for ((i = 0; i < repeats; i++)); do
1476                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1477                 touch $DIR/$tdir/test/a || error "touch fails"
1478                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1479                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1480         done
1481
1482         true
1483 }
1484 run_test 24F "hash order vs readdir (LU-11330)"
1485
1486 test_24G () {
1487         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1488
1489         local ino1
1490         local ino2
1491
1492         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1493         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1494         touch $DIR/$tdir-0/f1 || error "touch f1"
1495         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1496         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1497         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1498         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1499         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1500 }
1501 run_test 24G "migrate symlink in rename"
1502
1503 test_24H() {
1504         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1505         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1506                 skip "MDT1 should be on another node"
1507
1508         test_mkdir -i 1 -c 1 $DIR/$tdir
1509 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1510         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1511         touch $DIR/$tdir/$tfile || error "touch failed"
1512 }
1513 run_test 24H "repeat FLD_QUERY rpc"
1514
1515 test_25a() {
1516         echo '== symlink sanity ============================================='
1517
1518         test_mkdir $DIR/d25
1519         ln -s d25 $DIR/s25
1520         touch $DIR/s25/foo ||
1521                 error "File creation in symlinked directory failed"
1522 }
1523 run_test 25a "create file in symlinked directory ==============="
1524
1525 test_25b() {
1526         [ ! -d $DIR/d25 ] && test_25a
1527         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1528 }
1529 run_test 25b "lookup file in symlinked directory ==============="
1530
1531 test_26a() {
1532         test_mkdir $DIR/d26
1533         test_mkdir $DIR/d26/d26-2
1534         ln -s d26/d26-2 $DIR/s26
1535         touch $DIR/s26/foo || error "File creation failed"
1536 }
1537 run_test 26a "multiple component symlink ======================="
1538
1539 test_26b() {
1540         test_mkdir -p $DIR/$tdir/d26-2
1541         ln -s $tdir/d26-2/foo $DIR/s26-2
1542         touch $DIR/s26-2 || error "File creation failed"
1543 }
1544 run_test 26b "multiple component symlink at end of lookup ======"
1545
1546 test_26c() {
1547         test_mkdir $DIR/d26.2
1548         touch $DIR/d26.2/foo
1549         ln -s d26.2 $DIR/s26.2-1
1550         ln -s s26.2-1 $DIR/s26.2-2
1551         ln -s s26.2-2 $DIR/s26.2-3
1552         chmod 0666 $DIR/s26.2-3/foo
1553 }
1554 run_test 26c "chain of symlinks"
1555
1556 # recursive symlinks (bug 439)
1557 test_26d() {
1558         ln -s d26-3/foo $DIR/d26-3
1559 }
1560 run_test 26d "create multiple component recursive symlink"
1561
1562 test_26e() {
1563         [ ! -h $DIR/d26-3 ] && test_26d
1564         rm $DIR/d26-3
1565 }
1566 run_test 26e "unlink multiple component recursive symlink"
1567
1568 # recursive symlinks (bug 7022)
1569 test_26f() {
1570         test_mkdir $DIR/$tdir
1571         test_mkdir $DIR/$tdir/$tfile
1572         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1573         test_mkdir -p lndir/bar1
1574         test_mkdir $DIR/$tdir/$tfile/$tfile
1575         cd $tfile                || error "cd $tfile failed"
1576         ln -s .. dotdot          || error "ln dotdot failed"
1577         ln -s dotdot/lndir lndir || error "ln lndir failed"
1578         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1579         output=`ls $tfile/$tfile/lndir/bar1`
1580         [ "$output" = bar1 ] && error "unexpected output"
1581         rm -r $tfile             || error "rm $tfile failed"
1582         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1583 }
1584 run_test 26f "rm -r of a directory which has recursive symlink"
1585
1586 test_27a() {
1587         test_mkdir $DIR/$tdir
1588         $LFS getstripe $DIR/$tdir
1589         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1590         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1591         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1592 }
1593 run_test 27a "one stripe file"
1594
1595 test_27b() {
1596         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1597
1598         test_mkdir $DIR/$tdir
1599         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1600         $LFS getstripe -c $DIR/$tdir/$tfile
1601         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1602                 error "two-stripe file doesn't have two stripes"
1603
1604         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1605 }
1606 run_test 27b "create and write to two stripe file"
1607
1608 # 27c family tests specific striping, setstripe -o
1609 test_27ca() {
1610         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1611         test_mkdir -p $DIR/$tdir
1612         local osts="1"
1613
1614         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1615         $LFS getstripe -i $DIR/$tdir/$tfile
1616         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1617                 error "stripe not on specified OST"
1618
1619         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1620 }
1621 run_test 27ca "one stripe on specified OST"
1622
1623 test_27cb() {
1624         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1625         test_mkdir -p $DIR/$tdir
1626         local osts="1,0"
1627         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1628         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1629         echo "$getstripe"
1630
1631         # Strip getstripe output to a space separated list of OSTs
1632         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1633                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1634         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1635                 error "stripes not on specified OSTs"
1636
1637         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1638 }
1639 run_test 27cb "two stripes on specified OSTs"
1640
1641 test_27cc() {
1642         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1643         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1644                 skip "server does not support overstriping"
1645
1646         test_mkdir -p $DIR/$tdir
1647         local osts="0,0"
1648         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1649         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1650         echo "$getstripe"
1651
1652         # Strip getstripe output to a space separated list of OSTs
1653         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1654                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1655         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1656                 error "stripes not on specified OSTs"
1657
1658         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1659 }
1660 run_test 27cc "two stripes on the same OST"
1661
1662 test_27cd() {
1663         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1664         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1665                 skip "server does not support overstriping"
1666         test_mkdir -p $DIR/$tdir
1667         local osts="0,1,1,0"
1668         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1669         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1670         echo "$getstripe"
1671
1672         # Strip getstripe output to a space separated list of OSTs
1673         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1674                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1675         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1676                 error "stripes not on specified OSTs"
1677
1678         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1679 }
1680 run_test 27cd "four stripes on two OSTs"
1681
1682 test_27ce() {
1683         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1684                 skip_env "too many osts, skipping"
1685         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1686                 skip "server does not support overstriping"
1687         # We do one more stripe than we have OSTs
1688         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1689                 skip_env "ea_inode feature disabled"
1690
1691         test_mkdir -p $DIR/$tdir
1692         local osts=""
1693         for i in $(seq 0 $OSTCOUNT);
1694         do
1695                 osts=$osts"0"
1696                 if [ $i -ne $OSTCOUNT ]; then
1697                         osts=$osts","
1698                 fi
1699         done
1700         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1701         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1702         echo "$getstripe"
1703
1704         # Strip getstripe output to a space separated list of OSTs
1705         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1706                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1707         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1708                 error "stripes not on specified OSTs"
1709
1710         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1711 }
1712 run_test 27ce "more stripes than OSTs with -o"
1713
1714 test_27cf() {
1715         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1716         local pid=0
1717
1718         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1719         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1720         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1721         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1722                 error "failed to set $osp_proc=0"
1723
1724         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1725         pid=$!
1726         sleep 1
1727         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1728         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1729                 error "failed to set $osp_proc=1"
1730         wait $pid
1731         [[ $pid -ne 0 ]] ||
1732                 error "should return error due to $osp_proc=0"
1733 }
1734 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1735
1736 test_27d() {
1737         test_mkdir $DIR/$tdir
1738         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1739                 error "setstripe failed"
1740         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1741         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1742 }
1743 run_test 27d "create file with default settings"
1744
1745 test_27e() {
1746         # LU-5839 adds check for existed layout before setting it
1747         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1748                 skip "Need MDS version at least 2.7.56"
1749
1750         test_mkdir $DIR/$tdir
1751         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1752         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1753         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1754 }
1755 run_test 27e "setstripe existing file (should return error)"
1756
1757 test_27f() {
1758         test_mkdir $DIR/$tdir
1759         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1760                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1761         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1762                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1763         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1764         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1765 }
1766 run_test 27f "setstripe with bad stripe size (should return error)"
1767
1768 test_27g() {
1769         test_mkdir $DIR/$tdir
1770         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1771         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1772                 error "$DIR/$tdir/$tfile has object"
1773 }
1774 run_test 27g "$LFS getstripe with no objects"
1775
1776 test_27ga() {
1777         test_mkdir $DIR/$tdir
1778         touch $DIR/$tdir/$tfile || error "touch failed"
1779         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1780         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1781         local rc=$?
1782         (( rc == 2 )) || error "getstripe did not return ENOENT"
1783 }
1784 run_test 27ga "$LFS getstripe with missing file (should return error)"
1785
1786 test_27i() {
1787         test_mkdir $DIR/$tdir
1788         touch $DIR/$tdir/$tfile || error "touch failed"
1789         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1790                 error "missing objects"
1791 }
1792 run_test 27i "$LFS getstripe with some objects"
1793
1794 test_27j() {
1795         test_mkdir $DIR/$tdir
1796         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1797                 error "setstripe failed" || true
1798 }
1799 run_test 27j "setstripe with bad stripe offset (should return error)"
1800
1801 test_27k() { # bug 2844
1802         test_mkdir $DIR/$tdir
1803         local file=$DIR/$tdir/$tfile
1804         local ll_max_blksize=$((4 * 1024 * 1024))
1805         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1806         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1807         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1808         dd if=/dev/zero of=$file bs=4k count=1
1809         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1810         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1811 }
1812 run_test 27k "limit i_blksize for broken user apps"
1813
1814 test_27l() {
1815         mcreate $DIR/$tfile || error "creating file"
1816         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1817                 error "setstripe should have failed" || true
1818 }
1819 run_test 27l "check setstripe permissions (should return error)"
1820
1821 test_27m() {
1822         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1823
1824         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1825                 skip_env "multiple clients -- skipping"
1826
1827         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1828                    head -n1)
1829         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1830                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1831         fi
1832         stack_trap simple_cleanup_common
1833         test_mkdir $DIR/$tdir
1834         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1835         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1836                 error "dd should fill OST0"
1837         i=2
1838         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1839                 i=$((i + 1))
1840                 [ $i -gt 256 ] && break
1841         done
1842         i=$((i + 1))
1843         touch $DIR/$tdir/$tfile.$i
1844         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1845             awk '{print $1}'| grep -w "0") ] &&
1846                 error "OST0 was full but new created file still use it"
1847         i=$((i + 1))
1848         touch $DIR/$tdir/$tfile.$i
1849         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1850             awk '{print $1}'| grep -w "0") ] &&
1851                 error "OST0 was full but new created file still use it" || true
1852 }
1853 run_test 27m "create file while OST0 was full"
1854
1855 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1856 # if the OST isn't full anymore.
1857 reset_enospc() {
1858         local ostidx=${1:-""}
1859         local delay
1860         local ready
1861         local get_prealloc
1862
1863         local list=$(comma_list $(osts_nodes))
1864         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1865
1866         do_nodes $list lctl set_param fail_loc=0
1867         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1868         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1869                 awk '{print $1 * 2;exit;}')
1870         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1871                         grep -v \"^0$\""
1872         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1873 }
1874
1875 test_27n() {
1876         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1878         remote_mds_nodsh && skip "remote MDS with nodsh"
1879         remote_ost_nodsh && skip "remote OST with nodsh"
1880
1881         reset_enospc
1882         rm -f $DIR/$tdir/$tfile
1883         exhaust_precreations 0 0x80000215
1884         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1885         touch $DIR/$tdir/$tfile || error "touch failed"
1886         $LFS getstripe $DIR/$tdir/$tfile
1887         reset_enospc
1888 }
1889 run_test 27n "create file with some full OSTs"
1890
1891 test_27o() {
1892         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1894         remote_mds_nodsh && skip "remote MDS with nodsh"
1895         remote_ost_nodsh && skip "remote OST with nodsh"
1896
1897         reset_enospc
1898         rm -f $DIR/$tdir/$tfile
1899         exhaust_all_precreations 0x215
1900
1901         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1902
1903         reset_enospc
1904         rm -rf $DIR/$tdir/*
1905 }
1906 run_test 27o "create file with all full OSTs (should error)"
1907
1908 function create_and_checktime() {
1909         local fname=$1
1910         local loops=$2
1911         local i
1912
1913         for ((i=0; i < $loops; i++)); do
1914                 local start=$SECONDS
1915                 multiop $fname-$i Oc
1916                 ((SECONDS-start < TIMEOUT)) ||
1917                         error "creation took " $((SECONDS-$start)) && return 1
1918         done
1919 }
1920
1921 test_27oo() {
1922         local mdts=$(comma_list $(mdts_nodes))
1923
1924         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1925                 skip "Need MDS version at least 2.13.57"
1926
1927         local f0=$DIR/${tfile}-0
1928         local f1=$DIR/${tfile}-1
1929
1930         wait_delete_completed
1931
1932         # refill precreated objects
1933         $LFS setstripe -i0 -c1 $f0
1934
1935         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1936         # force QoS allocation policy
1937         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1938         stack_trap "do_nodes $mdts $LCTL set_param \
1939                 lov.*.qos_threshold_rr=$saved" EXIT
1940         sleep_maxage
1941
1942         # one OST is unavailable, but still have few objects preallocated
1943         stop ost1
1944         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1945                 rm -rf $f1 $DIR/$tdir*" EXIT
1946
1947         for ((i=0; i < 7; i++)); do
1948                 mkdir $DIR/$tdir$i || error "can't create dir"
1949                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1950                         error "can't set striping"
1951         done
1952         for ((i=0; i < 7; i++)); do
1953                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1954         done
1955         wait
1956 }
1957 run_test 27oo "don't let few threads to reserve too many objects"
1958
1959 test_27p() {
1960         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1962         remote_mds_nodsh && skip "remote MDS with nodsh"
1963         remote_ost_nodsh && skip "remote OST with nodsh"
1964
1965         reset_enospc
1966         rm -f $DIR/$tdir/$tfile
1967         test_mkdir $DIR/$tdir
1968
1969         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1970         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1971         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1972
1973         exhaust_precreations 0 0x80000215
1974         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1975         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1976         $LFS getstripe $DIR/$tdir/$tfile
1977
1978         reset_enospc
1979 }
1980 run_test 27p "append to a truncated file with some full OSTs"
1981
1982 test_27q() {
1983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1985         remote_mds_nodsh && skip "remote MDS with nodsh"
1986         remote_ost_nodsh && skip "remote OST with nodsh"
1987
1988         reset_enospc
1989         rm -f $DIR/$tdir/$tfile
1990
1991         mkdir_on_mdt0 $DIR/$tdir
1992         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1993         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1994                 error "truncate $DIR/$tdir/$tfile failed"
1995         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1996
1997         exhaust_all_precreations 0x215
1998
1999         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2000         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2001
2002         reset_enospc
2003 }
2004 run_test 27q "append to truncated file with all OSTs full (should error)"
2005
2006 test_27r() {
2007         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2009         remote_mds_nodsh && skip "remote MDS with nodsh"
2010         remote_ost_nodsh && skip "remote OST with nodsh"
2011
2012         reset_enospc
2013         rm -f $DIR/$tdir/$tfile
2014         exhaust_precreations 0 0x80000215
2015
2016         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2017
2018         reset_enospc
2019 }
2020 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2021
2022 test_27s() { # bug 10725
2023         test_mkdir $DIR/$tdir
2024         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2025         local stripe_count=0
2026         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2027         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2028                 error "stripe width >= 2^32 succeeded" || true
2029
2030 }
2031 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2032
2033 test_27t() { # bug 10864
2034         WDIR=$(pwd)
2035         WLFS=$(which lfs)
2036         cd $DIR
2037         touch $tfile
2038         $WLFS getstripe $tfile
2039         cd $WDIR
2040 }
2041 run_test 27t "check that utils parse path correctly"
2042
2043 test_27u() { # bug 4900
2044         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2045         remote_mds_nodsh && skip "remote MDS with nodsh"
2046
2047         local index
2048         local list=$(comma_list $(mdts_nodes))
2049
2050 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2051         do_nodes $list $LCTL set_param fail_loc=0x139
2052         test_mkdir -p $DIR/$tdir
2053         stack_trap "simple_cleanup_common 1000"
2054         createmany -o $DIR/$tdir/$tfile 1000
2055         do_nodes $list $LCTL set_param fail_loc=0
2056
2057         TLOG=$TMP/$tfile.getstripe
2058         $LFS getstripe $DIR/$tdir > $TLOG
2059         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2060         [[ $OBJS -gt 0 ]] &&
2061                 error "$OBJS objects created on OST-0. See $TLOG" ||
2062                 rm -f $TLOG
2063 }
2064 run_test 27u "skip object creation on OSC w/o objects"
2065
2066 test_27v() { # bug 4900
2067         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2069         remote_mds_nodsh && skip "remote MDS with nodsh"
2070         remote_ost_nodsh && skip "remote OST with nodsh"
2071
2072         exhaust_all_precreations 0x215
2073         reset_enospc
2074
2075         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2076
2077         touch $DIR/$tdir/$tfile
2078         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2079         # all except ost1
2080         for (( i=1; i < OSTCOUNT; i++ )); do
2081                 do_facet ost$i lctl set_param fail_loc=0x705
2082         done
2083         local START=`date +%s`
2084         createmany -o $DIR/$tdir/$tfile 32
2085
2086         local FINISH=`date +%s`
2087         local TIMEOUT=`lctl get_param -n timeout`
2088         local PROCESS=$((FINISH - START))
2089         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2090                error "$FINISH - $START >= $TIMEOUT / 2"
2091         sleep $((TIMEOUT / 2 - PROCESS))
2092         reset_enospc
2093 }
2094 run_test 27v "skip object creation on slow OST"
2095
2096 test_27w() { # bug 10997
2097         test_mkdir $DIR/$tdir
2098         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2099         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2100                 error "stripe size $size != 65536" || true
2101         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2102                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2103 }
2104 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2105
2106 test_27wa() {
2107         [[ $OSTCOUNT -lt 2 ]] &&
2108                 skip_env "skipping multiple stripe count/offset test"
2109
2110         test_mkdir $DIR/$tdir
2111         for i in $(seq 1 $OSTCOUNT); do
2112                 offset=$((i - 1))
2113                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2114                         error "setstripe -c $i -i $offset failed"
2115                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2116                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2117                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2118                 [ $index -ne $offset ] &&
2119                         error "stripe offset $index != $offset" || true
2120         done
2121 }
2122 run_test 27wa "check $LFS setstripe -c -i options"
2123
2124 test_27x() {
2125         remote_ost_nodsh && skip "remote OST with nodsh"
2126         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2128
2129         OFFSET=$(($OSTCOUNT - 1))
2130         OSTIDX=0
2131         local OST=$(ostname_from_index $OSTIDX)
2132
2133         test_mkdir $DIR/$tdir
2134         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2135         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2136         sleep_maxage
2137         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2138         for i in $(seq 0 $OFFSET); do
2139                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2140                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2141                 error "OST0 was degraded but new created file still use it"
2142         done
2143         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2144 }
2145 run_test 27x "create files while OST0 is degraded"
2146
2147 test_27y() {
2148         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2149         remote_mds_nodsh && skip "remote MDS with nodsh"
2150         remote_ost_nodsh && skip "remote OST with nodsh"
2151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2152
2153         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2154         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2155                 osp.$mdtosc.prealloc_last_id)
2156         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2157                 osp.$mdtosc.prealloc_next_id)
2158         local fcount=$((last_id - next_id))
2159         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2160         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2161
2162         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2163                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2164         local OST_DEACTIVE_IDX=-1
2165         local OSC
2166         local OSTIDX
2167         local OST
2168
2169         for OSC in $MDS_OSCS; do
2170                 OST=$(osc_to_ost $OSC)
2171                 OSTIDX=$(index_from_ostuuid $OST)
2172                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2173                         OST_DEACTIVE_IDX=$OSTIDX
2174                 fi
2175                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2176                         echo $OSC "is Deactivated:"
2177                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2178                 fi
2179         done
2180
2181         OSTIDX=$(index_from_ostuuid $OST)
2182         test_mkdir $DIR/$tdir
2183         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2184
2185         for OSC in $MDS_OSCS; do
2186                 OST=$(osc_to_ost $OSC)
2187                 OSTIDX=$(index_from_ostuuid $OST)
2188                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2189                         echo $OST "is degraded:"
2190                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2191                                                 obdfilter.$OST.degraded=1
2192                 fi
2193         done
2194
2195         sleep_maxage
2196         createmany -o $DIR/$tdir/$tfile $fcount
2197
2198         for OSC in $MDS_OSCS; do
2199                 OST=$(osc_to_ost $OSC)
2200                 OSTIDX=$(index_from_ostuuid $OST)
2201                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2202                         echo $OST "is recovered from degraded:"
2203                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2204                                                 obdfilter.$OST.degraded=0
2205                 else
2206                         do_facet $SINGLEMDS lctl --device %$OSC activate
2207                 fi
2208         done
2209
2210         # all osp devices get activated, hence -1 stripe count restored
2211         local stripe_count=0
2212
2213         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2214         # devices get activated.
2215         sleep_maxage
2216         $LFS setstripe -c -1 $DIR/$tfile
2217         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2218         rm -f $DIR/$tfile
2219         [ $stripe_count -ne $OSTCOUNT ] &&
2220                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2221         return 0
2222 }
2223 run_test 27y "create files while OST0 is degraded and the rest inactive"
2224
2225 check_seq_oid()
2226 {
2227         log "check file $1"
2228
2229         lmm_count=$($LFS getstripe -c $1)
2230         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2231         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2232
2233         local old_ifs="$IFS"
2234         IFS=$'[:]'
2235         fid=($($LFS path2fid $1))
2236         IFS="$old_ifs"
2237
2238         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2239         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2240
2241         # compare lmm_seq and lu_fid->f_seq
2242         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2243         # compare lmm_object_id and lu_fid->oid
2244         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2245
2246         # check the trusted.fid attribute of the OST objects of the file
2247         local have_obdidx=false
2248         local stripe_nr=0
2249         $LFS getstripe $1 | while read obdidx oid hex seq; do
2250                 # skip lines up to and including "obdidx"
2251                 [ -z "$obdidx" ] && break
2252                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2253                 $have_obdidx || continue
2254
2255                 local ost=$((obdidx + 1))
2256                 local dev=$(ostdevname $ost)
2257                 local oid_hex
2258
2259                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2260
2261                 seq=$(echo $seq | sed -e "s/^0x//g")
2262                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2263                         oid_hex=$(echo $oid)
2264                 else
2265                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2266                 fi
2267                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2268
2269                 local ff=""
2270                 #
2271                 # Don't unmount/remount the OSTs if we don't need to do that.
2272                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2273                 # update too, until that use mount/ll_decode_filter_fid/mount.
2274                 # Re-enable when debugfs will understand new filter_fid.
2275                 #
2276                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2277                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2278                                 $dev 2>/dev/null" | grep "parent=")
2279                 fi
2280                 if [ -z "$ff" ]; then
2281                         stop ost$ost
2282                         mount_fstype ost$ost
2283                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2284                                 $(facet_mntpt ost$ost)/$obj_file)
2285                         unmount_fstype ost$ost
2286                         start ost$ost $dev $OST_MOUNT_OPTS
2287                         clients_up
2288                 fi
2289
2290                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2291
2292                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2293
2294                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2295                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2296                 #
2297                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2298                 #       stripe_size=1048576 component_id=1 component_start=0 \
2299                 #       component_end=33554432
2300                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2301                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2302                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2303                 local ff_pstripe
2304                 if grep -q 'stripe=' <<<$ff; then
2305                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2306                 else
2307                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2308                         # into f_ver in this case.  See comment on ff_parent.
2309                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2310                 fi
2311
2312                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2313                 [ $ff_pseq = $lmm_seq ] ||
2314                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2315                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2316                 [ $ff_poid = $lmm_oid ] ||
2317                         error "FF parent OID $ff_poid != $lmm_oid"
2318                 (($ff_pstripe == $stripe_nr)) ||
2319                         error "FF stripe $ff_pstripe != $stripe_nr"
2320
2321                 stripe_nr=$((stripe_nr + 1))
2322                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2323                         continue
2324                 if grep -q 'stripe_count=' <<<$ff; then
2325                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2326                                             -e 's/ .*//' <<<$ff)
2327                         [ $lmm_count = $ff_scnt ] ||
2328                                 error "FF stripe count $lmm_count != $ff_scnt"
2329                 fi
2330         done
2331 }
2332
2333 test_27z() {
2334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2335         remote_ost_nodsh && skip "remote OST with nodsh"
2336
2337         test_mkdir $DIR/$tdir
2338         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2339                 { error "setstripe -c -1 failed"; return 1; }
2340         # We need to send a write to every object to get parent FID info set.
2341         # This _should_ also work for setattr, but does not currently.
2342         # touch $DIR/$tdir/$tfile-1 ||
2343         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2344                 { error "dd $tfile-1 failed"; return 2; }
2345         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2346                 { error "setstripe -c -1 failed"; return 3; }
2347         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2348                 { error "dd $tfile-2 failed"; return 4; }
2349
2350         # make sure write RPCs have been sent to OSTs
2351         sync; sleep 5; sync
2352
2353         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2354         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2355 }
2356 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2357
2358 test_27A() { # b=19102
2359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2360
2361         save_layout_restore_at_exit $MOUNT
2362         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2363         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2364                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2365         local default_size=$($LFS getstripe -S $MOUNT)
2366         local default_offset=$($LFS getstripe -i $MOUNT)
2367         local dsize=$(do_facet $SINGLEMDS \
2368                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2369         [ $default_size -eq $dsize ] ||
2370                 error "stripe size $default_size != $dsize"
2371         [ $default_offset -eq -1 ] ||
2372                 error "stripe offset $default_offset != -1"
2373 }
2374 run_test 27A "check filesystem-wide default LOV EA values"
2375
2376 test_27B() { # LU-2523
2377         test_mkdir $DIR/$tdir
2378         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2379         touch $DIR/$tdir/f0
2380         # open f1 with O_LOV_DELAY_CREATE
2381         # rename f0 onto f1
2382         # call setstripe ioctl on open file descriptor for f1
2383         # close
2384         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2385                 $DIR/$tdir/f0
2386
2387         rm -f $DIR/$tdir/f1
2388         # open f1 with O_LOV_DELAY_CREATE
2389         # unlink f1
2390         # call setstripe ioctl on open file descriptor for f1
2391         # close
2392         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2393
2394         # Allow multiop to fail in imitation of NFS's busted semantics.
2395         true
2396 }
2397 run_test 27B "call setstripe on open unlinked file/rename victim"
2398
2399 # 27C family tests full striping and overstriping
2400 test_27Ca() { #LU-2871
2401         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2402
2403         declare -a ost_idx
2404         local index
2405         local found
2406         local i
2407         local j
2408
2409         test_mkdir $DIR/$tdir
2410         cd $DIR/$tdir
2411         for i in $(seq 0 $((OSTCOUNT - 1))); do
2412                 # set stripe across all OSTs starting from OST$i
2413                 $LFS setstripe -i $i -c -1 $tfile$i
2414                 # get striping information
2415                 ost_idx=($($LFS getstripe $tfile$i |
2416                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2417                 echo ${ost_idx[@]}
2418
2419                 # check the layout
2420                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2421                         error "${#ost_idx[@]} != $OSTCOUNT"
2422
2423                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2424                         found=0
2425                         for j in $(echo ${ost_idx[@]}); do
2426                                 if [ $index -eq $j ]; then
2427                                         found=1
2428                                         break
2429                                 fi
2430                         done
2431                         [ $found = 1 ] ||
2432                                 error "Can not find $index in ${ost_idx[@]}"
2433                 done
2434         done
2435 }
2436 run_test 27Ca "check full striping across all OSTs"
2437
2438 test_27Cb() {
2439         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2440                 skip "server does not support overstriping"
2441         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2442                 skip_env "too many osts, skipping"
2443
2444         test_mkdir -p $DIR/$tdir
2445         local setcount=$(($OSTCOUNT * 2))
2446         [ $setcount -lt 160 ] || large_xattr_enabled ||
2447                 skip_env "ea_inode feature disabled"
2448
2449         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2450                 error "setstripe failed"
2451
2452         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2453         [ $count -eq $setcount ] ||
2454                 error "stripe count $count, should be $setcount"
2455
2456         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2457                 error "overstriped should be set in pattern"
2458
2459         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2460                 error "dd failed"
2461 }
2462 run_test 27Cb "more stripes than OSTs with -C"
2463
2464 test_27Cc() {
2465         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2466                 skip "server does not support overstriping"
2467         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2468
2469         test_mkdir -p $DIR/$tdir
2470         local setcount=$(($OSTCOUNT - 1))
2471
2472         [ $setcount -lt 160 ] || large_xattr_enabled ||
2473                 skip_env "ea_inode feature disabled"
2474
2475         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2476                 error "setstripe failed"
2477
2478         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2479         [ $count -eq $setcount ] ||
2480                 error "stripe count $count, should be $setcount"
2481
2482         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2483                 error "overstriped should not be set in pattern"
2484
2485         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2486                 error "dd failed"
2487 }
2488 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2489
2490 test_27Cd() {
2491         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2492                 skip "server does not support overstriping"
2493         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2494         large_xattr_enabled || skip_env "ea_inode feature disabled"
2495
2496         test_mkdir -p $DIR/$tdir
2497         local setcount=$LOV_MAX_STRIPE_COUNT
2498
2499         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2500                 error "setstripe failed"
2501
2502         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2503         [ $count -eq $setcount ] ||
2504                 error "stripe count $count, should be $setcount"
2505
2506         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2507                 error "overstriped should be set in pattern"
2508
2509         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2510                 error "dd failed"
2511
2512         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2513 }
2514 run_test 27Cd "test maximum stripe count"
2515
2516 test_27Ce() {
2517         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2518                 skip "server does not support overstriping"
2519         test_mkdir -p $DIR/$tdir
2520
2521         pool_add $TESTNAME || error "Pool creation failed"
2522         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2523
2524         local setcount=8
2525
2526         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2527                 error "setstripe failed"
2528
2529         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2530         [ $count -eq $setcount ] ||
2531                 error "stripe count $count, should be $setcount"
2532
2533         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2534                 error "overstriped should be set in pattern"
2535
2536         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2537                 error "dd failed"
2538
2539         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2540 }
2541 run_test 27Ce "test pool with overstriping"
2542
2543 test_27Cf() {
2544         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2545                 skip "server does not support overstriping"
2546         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2547                 skip_env "too many osts, skipping"
2548
2549         test_mkdir -p $DIR/$tdir
2550
2551         local setcount=$(($OSTCOUNT * 2))
2552         [ $setcount -lt 160 ] || large_xattr_enabled ||
2553                 skip_env "ea_inode feature disabled"
2554
2555         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2556                 error "setstripe failed"
2557
2558         echo 1 > $DIR/$tdir/$tfile
2559
2560         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2561         [ $count -eq $setcount ] ||
2562                 error "stripe count $count, should be $setcount"
2563
2564         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2565                 error "overstriped should be set in pattern"
2566
2567         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2568                 error "dd failed"
2569
2570         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2571 }
2572 run_test 27Cf "test default inheritance with overstriping"
2573
2574 test_27D() {
2575         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2576         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2577         remote_mds_nodsh && skip "remote MDS with nodsh"
2578
2579         local POOL=${POOL:-testpool}
2580         local first_ost=0
2581         local last_ost=$(($OSTCOUNT - 1))
2582         local ost_step=1
2583         local ost_list=$(seq $first_ost $ost_step $last_ost)
2584         local ost_range="$first_ost $last_ost $ost_step"
2585
2586         test_mkdir $DIR/$tdir
2587         pool_add $POOL || error "pool_add failed"
2588         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2589
2590         local skip27D
2591         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2592                 skip27D+="-s 29"
2593         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2594                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2595                         skip27D+=" -s 30,31"
2596         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2597           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2598                 skip27D+=" -s 32,33"
2599         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2600                 skip27D+=" -s 34"
2601         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2602                 error "llapi_layout_test failed"
2603
2604         destroy_test_pools || error "destroy test pools failed"
2605 }
2606 run_test 27D "validate llapi_layout API"
2607
2608 # Verify that default_easize is increased from its initial value after
2609 # accessing a widely striped file.
2610 test_27E() {
2611         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2612         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2613                 skip "client does not have LU-3338 fix"
2614
2615         # 72 bytes is the minimum space required to store striping
2616         # information for a file striped across one OST:
2617         # (sizeof(struct lov_user_md_v3) +
2618         #  sizeof(struct lov_user_ost_data_v1))
2619         local min_easize=72
2620         $LCTL set_param -n llite.*.default_easize $min_easize ||
2621                 error "lctl set_param failed"
2622         local easize=$($LCTL get_param -n llite.*.default_easize)
2623
2624         [ $easize -eq $min_easize ] ||
2625                 error "failed to set default_easize"
2626
2627         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2628                 error "setstripe failed"
2629         # In order to ensure stat() call actually talks to MDS we need to
2630         # do something drastic to this file to shake off all lock, e.g.
2631         # rename it (kills lookup lock forcing cache cleaning)
2632         mv $DIR/$tfile $DIR/${tfile}-1
2633         ls -l $DIR/${tfile}-1
2634         rm $DIR/${tfile}-1
2635
2636         easize=$($LCTL get_param -n llite.*.default_easize)
2637
2638         [ $easize -gt $min_easize ] ||
2639                 error "default_easize not updated"
2640 }
2641 run_test 27E "check that default extended attribute size properly increases"
2642
2643 test_27F() { # LU-5346/LU-7975
2644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2645         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2646         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2647                 skip "Need MDS version at least 2.8.51"
2648         remote_ost_nodsh && skip "remote OST with nodsh"
2649
2650         test_mkdir $DIR/$tdir
2651         rm -f $DIR/$tdir/f0
2652         $LFS setstripe -c 2 $DIR/$tdir
2653
2654         # stop all OSTs to reproduce situation for LU-7975 ticket
2655         for num in $(seq $OSTCOUNT); do
2656                 stop ost$num
2657         done
2658
2659         # open/create f0 with O_LOV_DELAY_CREATE
2660         # truncate f0 to a non-0 size
2661         # close
2662         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2663
2664         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2665         # open/write it again to force delayed layout creation
2666         cat /etc/hosts > $DIR/$tdir/f0 &
2667         catpid=$!
2668
2669         # restart OSTs
2670         for num in $(seq $OSTCOUNT); do
2671                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2672                         error "ost$num failed to start"
2673         done
2674
2675         wait $catpid || error "cat failed"
2676
2677         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2678         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2679                 error "wrong stripecount"
2680
2681 }
2682 run_test 27F "Client resend delayed layout creation with non-zero size"
2683
2684 test_27G() { #LU-10629
2685         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2686                 skip "Need MDS version at least 2.11.51"
2687         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2688         remote_mds_nodsh && skip "remote MDS with nodsh"
2689         local POOL=${POOL:-testpool}
2690         local ostrange="0 0 1"
2691
2692         test_mkdir $DIR/$tdir
2693         touch $DIR/$tdir/$tfile.nopool
2694         pool_add $POOL || error "pool_add failed"
2695         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2696         $LFS setstripe -p $POOL $DIR/$tdir
2697
2698         local pool=$($LFS getstripe -p $DIR/$tdir)
2699
2700         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2701         touch $DIR/$tdir/$tfile.default
2702         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2703         $LFS find $DIR/$tdir -type f --pool $POOL
2704         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2705         [[ "$found" == "2" ]] ||
2706                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2707
2708         $LFS setstripe -d $DIR/$tdir
2709
2710         pool=$($LFS getstripe -p -d $DIR/$tdir)
2711
2712         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2713 }
2714 run_test 27G "Clear OST pool from stripe"
2715
2716 test_27H() {
2717         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2718                 skip "Need MDS version newer than 2.11.54"
2719         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2720         test_mkdir $DIR/$tdir
2721         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2722         touch $DIR/$tdir/$tfile
2723         $LFS getstripe -c $DIR/$tdir/$tfile
2724         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2725                 error "two-stripe file doesn't have two stripes"
2726
2727         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2728         $LFS getstripe -y $DIR/$tdir/$tfile
2729         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2730              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2731                 error "expected l_ost_idx: [02]$ not matched"
2732
2733         # make sure ost list has been cleared
2734         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2735         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2736                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2737         touch $DIR/$tdir/f3
2738         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2739 }
2740 run_test 27H "Set specific OSTs stripe"
2741
2742 test_27I() {
2743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2744         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2745         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2746                 skip "Need MDS version newer than 2.12.52"
2747         local pool=$TESTNAME
2748         local ostrange="1 1 1"
2749
2750         save_layout_restore_at_exit $MOUNT
2751         $LFS setstripe -c 2 -i 0 $MOUNT
2752         pool_add $pool || error "pool_add failed"
2753         pool_add_targets $pool $ostrange ||
2754                 error "pool_add_targets failed"
2755         test_mkdir $DIR/$tdir
2756         $LFS setstripe -p $pool $DIR/$tdir
2757         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2758         $LFS getstripe $DIR/$tdir/$tfile
2759 }
2760 run_test 27I "check that root dir striping does not break parent dir one"
2761
2762 test_27J() {
2763         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2764                 skip "Need MDS version newer than 2.12.51"
2765
2766         test_mkdir $DIR/$tdir
2767         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2768         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2769
2770         # create foreign file (raw way)
2771         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2772                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2773
2774         ! $LFS setstripe --foreign --flags foo \
2775                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2776                         error "creating $tfile with '--flags foo' should fail"
2777
2778         ! $LFS setstripe --foreign --flags 0xffffffff \
2779                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2780                         error "creating $tfile w/ 0xffffffff flags should fail"
2781
2782         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2783                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2784
2785         # verify foreign file (raw way)
2786         parse_foreign_file -f $DIR/$tdir/$tfile |
2787                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2788                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2789         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2790                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2791         parse_foreign_file -f $DIR/$tdir/$tfile |
2792                 grep "lov_foreign_size: 73" ||
2793                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2794         parse_foreign_file -f $DIR/$tdir/$tfile |
2795                 grep "lov_foreign_type: 1" ||
2796                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2797         parse_foreign_file -f $DIR/$tdir/$tfile |
2798                 grep "lov_foreign_flags: 0x0000DA08" ||
2799                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2800         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2801                 grep "lov_foreign_value: 0x" |
2802                 sed -e 's/lov_foreign_value: 0x//')
2803         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2804         [[ $lov = ${lov2// /} ]] ||
2805                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2806
2807         # create foreign file (lfs + API)
2808         $LFS setstripe --foreign=none --flags 0xda08 \
2809                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2810                 error "$DIR/$tdir/${tfile}2: create failed"
2811
2812         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2813                 grep "lfm_magic:.*0x0BD70BD0" ||
2814                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2815         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2816         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2817                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2818         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2819                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2820         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2821                 grep "lfm_flags:.*0x0000DA08" ||
2822                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2823         $LFS getstripe $DIR/$tdir/${tfile}2 |
2824                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2825                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2826
2827         # modify striping should fail
2828         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2829                 error "$DIR/$tdir/$tfile: setstripe should fail"
2830         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2831                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2832
2833         # R/W should fail
2834         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2835         cat $DIR/$tdir/${tfile}2 &&
2836                 error "$DIR/$tdir/${tfile}2: read should fail"
2837         cat /etc/passwd > $DIR/$tdir/$tfile &&
2838                 error "$DIR/$tdir/$tfile: write should fail"
2839         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2840                 error "$DIR/$tdir/${tfile}2: write should fail"
2841
2842         # chmod should work
2843         chmod 222 $DIR/$tdir/$tfile ||
2844                 error "$DIR/$tdir/$tfile: chmod failed"
2845         chmod 222 $DIR/$tdir/${tfile}2 ||
2846                 error "$DIR/$tdir/${tfile}2: chmod failed"
2847
2848         # chown should work
2849         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2850                 error "$DIR/$tdir/$tfile: chown failed"
2851         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2852                 error "$DIR/$tdir/${tfile}2: chown failed"
2853
2854         # rename should work
2855         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2856                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2857         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2858                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2859
2860         #remove foreign file
2861         rm $DIR/$tdir/${tfile}.new ||
2862                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2863         rm $DIR/$tdir/${tfile}2.new ||
2864                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2865 }
2866 run_test 27J "basic ops on file with foreign LOV"
2867
2868 test_27K() {
2869         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2870                 skip "Need MDS version newer than 2.12.49"
2871
2872         test_mkdir $DIR/$tdir
2873         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2874         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2875
2876         # create foreign dir (raw way)
2877         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2878                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2879
2880         ! $LFS setdirstripe --foreign --flags foo \
2881                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2882                         error "creating $tdir with '--flags foo' should fail"
2883
2884         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2885                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2886                         error "creating $tdir w/ 0xffffffff flags should fail"
2887
2888         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2889                 error "create_foreign_dir FAILED"
2890
2891         # verify foreign dir (raw way)
2892         parse_foreign_dir -d $DIR/$tdir/$tdir |
2893                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2894                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2895         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2896                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2897         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2898                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2899         parse_foreign_dir -d $DIR/$tdir/$tdir |
2900                 grep "lmv_foreign_flags: 55813$" ||
2901                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2902         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2903                 grep "lmv_foreign_value: 0x" |
2904                 sed 's/lmv_foreign_value: 0x//')
2905         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2906                 sed 's/ //g')
2907         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2908
2909         # create foreign dir (lfs + API)
2910         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2911                 $DIR/$tdir/${tdir}2 ||
2912                 error "$DIR/$tdir/${tdir}2: create failed"
2913
2914         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2915                 grep "lfm_magic:.*0x0CD50CD0" ||
2916                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2917         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2918         # - sizeof(lfm_type) - sizeof(lfm_flags)
2919         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2920                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2921         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2922                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2923         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2924                 grep "lfm_flags:.*0x0000DA05" ||
2925                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2926         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2927                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2928                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2929
2930         # file create in dir should fail
2931         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2932         touch $DIR/$tdir/${tdir}2/$tfile &&
2933                 error "$DIR/${tdir}2: file create should fail"
2934
2935         # chmod should work
2936         chmod 777 $DIR/$tdir/$tdir ||
2937                 error "$DIR/$tdir: chmod failed"
2938         chmod 777 $DIR/$tdir/${tdir}2 ||
2939                 error "$DIR/${tdir}2: chmod failed"
2940
2941         # chown should work
2942         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2943                 error "$DIR/$tdir: chown failed"
2944         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2945                 error "$DIR/${tdir}2: chown failed"
2946
2947         # rename should work
2948         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2949                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2950         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2951                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2952
2953         #remove foreign dir
2954         rmdir $DIR/$tdir/${tdir}.new ||
2955                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2956         rmdir $DIR/$tdir/${tdir}2.new ||
2957                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2958 }
2959 run_test 27K "basic ops on dir with foreign LMV"
2960
2961 test_27L() {
2962         remote_mds_nodsh && skip "remote MDS with nodsh"
2963
2964         local POOL=${POOL:-$TESTNAME}
2965
2966         pool_add $POOL || error "pool_add failed"
2967
2968         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2969                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2970                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2971 }
2972 run_test 27L "lfs pool_list gives correct pool name"
2973
2974 test_27M() {
2975         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2976                 skip "Need MDS version >= than 2.12.57"
2977         remote_mds_nodsh && skip "remote MDS with nodsh"
2978         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2979
2980         test_mkdir $DIR/$tdir
2981
2982         # Set default striping on directory
2983         local setcount=4
2984         local stripe_opt
2985
2986         # if we run against a 2.12 server which lacks overstring support
2987         # then the connect_flag will not report overstriping, even if client
2988         # is 2.14+
2989         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2990                 stripe_opt="-C $setcount"
2991         elif (( $OSTCOUNT >= $setcount )); then
2992                 stripe_opt="-c $setcount"
2993         else
2994                 skip "server does not support overstriping"
2995         fi
2996         $LFS setstripe $stripe_opt $DIR/$tdir
2997
2998         echo 1 > $DIR/$tdir/${tfile}.1
2999         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3000         [ $count -eq $setcount ] ||
3001                 error "(1) stripe count $count, should be $setcount"
3002
3003         # Capture existing append_stripe_count setting for restore
3004         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3005         local mdts=$(comma_list $(mdts_nodes))
3006         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
3007
3008         local appendcount=$orig_count
3009         echo 1 >> $DIR/$tdir/${tfile}.2_append
3010         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3011         [ $count -eq $appendcount ] ||
3012                 error "(2)stripe count $count, should be $appendcount for append"
3013
3014         # Disable O_APPEND striping, verify it works
3015         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3016
3017         # Should now get the default striping, which is 4
3018         setcount=4
3019         echo 1 >> $DIR/$tdir/${tfile}.3_append
3020         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3021         [ $count -eq $setcount ] ||
3022                 error "(3) stripe count $count, should be $setcount"
3023
3024         # Try changing the stripe count for append files
3025         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3026
3027         # Append striping is now 2 (directory default is still 4)
3028         appendcount=2
3029         echo 1 >> $DIR/$tdir/${tfile}.4_append
3030         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3031         [ $count -eq $appendcount ] ||
3032                 error "(4) stripe count $count, should be $appendcount for append"
3033
3034         # Test append stripe count of -1
3035         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3036         appendcount=$OSTCOUNT
3037         echo 1 >> $DIR/$tdir/${tfile}.5
3038         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3039         [ $count -eq $appendcount ] ||
3040                 error "(5) stripe count $count, should be $appendcount for append"
3041
3042         # Set append striping back to default of 1
3043         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3044
3045         # Try a new default striping, PFL + DOM
3046         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3047
3048         # Create normal DOM file, DOM returns stripe count == 0
3049         setcount=0
3050         touch $DIR/$tdir/${tfile}.6
3051         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3052         [ $count -eq $setcount ] ||
3053                 error "(6) stripe count $count, should be $setcount"
3054
3055         # Show
3056         appendcount=1
3057         echo 1 >> $DIR/$tdir/${tfile}.7_append
3058         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3059         [ $count -eq $appendcount ] ||
3060                 error "(7) stripe count $count, should be $appendcount for append"
3061
3062         # Clean up DOM layout
3063         $LFS setstripe -d $DIR/$tdir
3064
3065         save_layout_restore_at_exit $MOUNT
3066         # Now test that append striping works when layout is from root
3067         $LFS setstripe -c 2 $MOUNT
3068         # Make a special directory for this
3069         mkdir $DIR/${tdir}/${tdir}.2
3070
3071         # Verify for normal file
3072         setcount=2
3073         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3074         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3075         [ $count -eq $setcount ] ||
3076                 error "(8) stripe count $count, should be $setcount"
3077
3078         appendcount=1
3079         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3080         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3081         [ $count -eq $appendcount ] ||
3082                 error "(9) stripe count $count, should be $appendcount for append"
3083
3084         # Now test O_APPEND striping with pools
3085         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3086         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3087
3088         # Create the pool
3089         pool_add $TESTNAME || error "pool creation failed"
3090         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3091
3092         echo 1 >> $DIR/$tdir/${tfile}.10_append
3093
3094         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3095         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3096
3097         # Check that count is still correct
3098         appendcount=1
3099         echo 1 >> $DIR/$tdir/${tfile}.11_append
3100         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3101         [ $count -eq $appendcount ] ||
3102                 error "(11) stripe count $count, should be $appendcount for append"
3103
3104         # Disable O_APPEND stripe count, verify pool works separately
3105         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3106
3107         echo 1 >> $DIR/$tdir/${tfile}.12_append
3108
3109         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3110         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3111
3112         # Remove pool setting, verify it's not applied
3113         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3114
3115         echo 1 >> $DIR/$tdir/${tfile}.13_append
3116
3117         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3118         [ "$pool" = "" ] || error "(13) pool found: $pool"
3119 }
3120 run_test 27M "test O_APPEND striping"
3121
3122 test_27N() {
3123         combined_mgs_mds && skip "needs separate MGS/MDT"
3124
3125         pool_add $TESTNAME || error "pool_add failed"
3126         do_facet mgs "$LCTL pool_list $FSNAME" |
3127                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3128                 error "lctl pool_list on MGS failed"
3129 }
3130 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3131
3132 clean_foreign_symlink() {
3133         trap 0
3134         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3135         for i in $DIR/$tdir/* ; do
3136                 $LFS unlink_foreign $i || true
3137         done
3138 }
3139
3140 test_27O() {
3141         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3142                 skip "Need MDS version newer than 2.12.51"
3143
3144         test_mkdir $DIR/$tdir
3145         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3146         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3147
3148         trap clean_foreign_symlink EXIT
3149
3150         # enable foreign_symlink behaviour
3151         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3152
3153         # foreign symlink LOV format is a partial path by default
3154
3155         # create foreign file (lfs + API)
3156         $LFS setstripe --foreign=symlink --flags 0xda05 \
3157                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3158                 error "$DIR/$tdir/${tfile}: create failed"
3159
3160         $LFS getstripe -v $DIR/$tdir/${tfile} |
3161                 grep "lfm_magic:.*0x0BD70BD0" ||
3162                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3163         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3164                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3165         $LFS getstripe -v $DIR/$tdir/${tfile} |
3166                 grep "lfm_flags:.*0x0000DA05" ||
3167                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3168         $LFS getstripe $DIR/$tdir/${tfile} |
3169                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3170                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3171
3172         # modify striping should fail
3173         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3174                 error "$DIR/$tdir/$tfile: setstripe should fail"
3175
3176         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3177         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3178         cat /etc/passwd > $DIR/$tdir/$tfile &&
3179                 error "$DIR/$tdir/$tfile: write should fail"
3180
3181         # rename should succeed
3182         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3183                 error "$DIR/$tdir/$tfile: rename has failed"
3184
3185         #remove foreign_symlink file should fail
3186         rm $DIR/$tdir/${tfile}.new &&
3187                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3188
3189         #test fake symlink
3190         mkdir /tmp/${uuid1} ||
3191                 error "/tmp/${uuid1}: mkdir has failed"
3192         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3193                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3194         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3195         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3197         #read should succeed now
3198         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3199                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3200         #write should succeed now
3201         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3202                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3203         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3204                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3205         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3206                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3207
3208         #check that getstripe still works
3209         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3210                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3211
3212         # chmod should still succeed
3213         chmod 644 $DIR/$tdir/${tfile}.new ||
3214                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3215
3216         # chown should still succeed
3217         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3218                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3219
3220         # rename should still succeed
3221         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3222                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3223
3224         #remove foreign_symlink file should still fail
3225         rm $DIR/$tdir/${tfile} &&
3226                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3227
3228         #use special ioctl() to unlink foreign_symlink file
3229         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3230                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3231
3232 }
3233 run_test 27O "basic ops on foreign file of symlink type"
3234
3235 test_27P() {
3236         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3237                 skip "Need MDS version newer than 2.12.49"
3238
3239         test_mkdir $DIR/$tdir
3240         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3241         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3242
3243         trap clean_foreign_symlink EXIT
3244
3245         # enable foreign_symlink behaviour
3246         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3247
3248         # foreign symlink LMV format is a partial path by default
3249
3250         # create foreign dir (lfs + API)
3251         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3252                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3253                 error "$DIR/$tdir/${tdir}: create failed"
3254
3255         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3256                 grep "lfm_magic:.*0x0CD50CD0" ||
3257                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3258         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3259                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3260         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3261                 grep "lfm_flags:.*0x0000DA05" ||
3262                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3263         $LFS getdirstripe $DIR/$tdir/${tdir} |
3264                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3265                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3266
3267         # file create in dir should fail
3268         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3269         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3270
3271         # rename should succeed
3272         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3273                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3274
3275         #remove foreign_symlink dir should fail
3276         rmdir $DIR/$tdir/${tdir}.new &&
3277                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3278
3279         #test fake symlink
3280         mkdir -p /tmp/${uuid1}/${uuid2} ||
3281                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3282         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3283                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3284         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3285         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3286                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3287         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3288                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3289
3290         #check that getstripe fails now that foreign_symlink enabled
3291         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3292                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3293
3294         # file create in dir should work now
3295         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3296                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3297         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3298                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3299         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3300                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3301
3302         # chmod should still succeed
3303         chmod 755 $DIR/$tdir/${tdir}.new ||
3304                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3305
3306         # chown should still succeed
3307         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3308                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3309
3310         # rename should still succeed
3311         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3312                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3313
3314         #remove foreign_symlink dir should still fail
3315         rmdir $DIR/$tdir/${tdir} &&
3316                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3317
3318         #use special ioctl() to unlink foreign_symlink file
3319         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3320                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3321
3322         #created file should still exist
3323         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3324                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3325         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3326                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3327 }
3328 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3329
3330 test_27Q() {
3331         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3332         stack_trap "rm -f $TMP/$tfile*"
3333
3334         test_mkdir $DIR/$tdir-1
3335         test_mkdir $DIR/$tdir-2
3336
3337         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3338         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3339
3340         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3341         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3342
3343         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3344         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3345
3346         # Create some bad symlinks and ensure that we don't loop
3347         # forever or something. These should return ELOOP (40) and
3348         # ENOENT (2) but I don't want to test for that because there's
3349         # always some weirdo architecture that needs to ruin
3350         # everything by defining these error numbers differently.
3351
3352         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3353         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3354
3355         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3356         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3357
3358         return 0
3359 }
3360 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3361
3362 test_27R() {
3363         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3364                 skip "need MDS 2.14.55 or later"
3365         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3366
3367         local testdir="$DIR/$tdir"
3368         test_mkdir -p $testdir
3369         stack_trap "rm -rf $testdir"
3370         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3371
3372         local f1="$testdir/f1"
3373         touch $f1 || error "failed to touch $f1"
3374         local count=$($LFS getstripe -c $f1)
3375         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3376
3377         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3378         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3379
3380         local maxcount=$(($OSTCOUNT - 1))
3381         local mdts=$(comma_list $(mdts_nodes))
3382         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3383         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3384
3385         local f2="$testdir/f2"
3386         touch $f2 || error "failed to touch $f2"
3387         local count=$($LFS getstripe -c $f2)
3388         (( $count == $maxcount )) || error "wrong stripe count"
3389 }
3390 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3391
3392 test_27S() {
3393         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
3394                 skip "Need MDS version at least 2.14.54"
3395         [[ "$(facet_host mds1)" != "$(facet_host ost1)" ]] ||
3396                 skip "needs different host for mdt1 ost1"
3397
3398         local count=$(precreated_ost_obj_count 0 0)
3399
3400         echo "precreate count $count"
3401         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
3402         $LFS setstripe -i 0 -c 1 $DIR/$tdir || error "setstripe $tdir failed"
3403         #define OBD_FAIL_OSP_GET_LAST_FID       0x2109
3404         do_facet mds1 $LCTL set_param fail_loc=0x2109
3405         #define OBD_FAIL_OST_GET_LAST_FID       0x252
3406         do_facet ost1 $LCTL set_param fail_loc=0x252
3407         createmany -o $DIR/$tdir/f $count &
3408         pid=$!
3409         echo "precreate count $(precreated_ost_obj_count 0 0)"
3410         do_facet mds1 $LCTL set_param fail_loc=0
3411         do_facet ost1 $LCTL set_param fail_loc=0
3412         wait $pid || error "createmany failed"
3413         echo "precreate count $(precreated_ost_obj_count 0 0)"
3414 }
3415 run_test 27S "don't deactivate OSP on network issue"
3416
3417 test_27T() {
3418         [ $(facet_host client) == $(facet_host ost1) ] &&
3419                 skip "need ost1 and client on different nodes"
3420
3421 #define OBD_FAIL_OSC_NO_GRANT            0x411
3422         $LCTL set_param fail_loc=0x20000411 fail_val=1
3423 #define OBD_FAIL_OST_ENOSPC              0x215
3424         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3425         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3426         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3427                 error "multiop failed"
3428 }
3429 run_test 27T "no eio on close on partial write due to enosp"
3430
3431 # createtest also checks that device nodes are created and
3432 # then visible correctly (#2091)
3433 test_28() { # bug 2091
3434         test_mkdir $DIR/d28
3435         $CREATETEST $DIR/d28/ct || error "createtest failed"
3436 }
3437 run_test 28 "create/mknod/mkdir with bad file types ============"
3438
3439 test_29() {
3440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3441
3442         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3443                 disable_opencache
3444                 stack_trap "restore_opencache"
3445         }
3446
3447         sync; sleep 1; sync # flush out any dirty pages from previous tests
3448         cancel_lru_locks
3449         test_mkdir $DIR/d29
3450         touch $DIR/d29/foo
3451         log 'first d29'
3452         ls -l $DIR/d29
3453
3454         declare -i LOCKCOUNTORIG=0
3455         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3456                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3457         done
3458         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3459
3460         declare -i LOCKUNUSEDCOUNTORIG=0
3461         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3462                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3463         done
3464
3465         log 'second d29'
3466         ls -l $DIR/d29
3467         log 'done'
3468
3469         declare -i LOCKCOUNTCURRENT=0
3470         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3471                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3472         done
3473
3474         declare -i LOCKUNUSEDCOUNTCURRENT=0
3475         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3476                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3477         done
3478
3479         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3480                 $LCTL set_param -n ldlm.dump_namespaces ""
3481                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3482                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3483                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3484                 return 2
3485         fi
3486         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3487                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3488                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3489                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3490                 return 3
3491         fi
3492 }
3493 run_test 29 "IT_GETATTR regression  ============================"
3494
3495 test_30a() { # was test_30
3496         cp $(which ls) $DIR || cp /bin/ls $DIR
3497         $DIR/ls / || error "Can't execute binary from lustre"
3498         rm $DIR/ls
3499 }
3500 run_test 30a "execute binary from Lustre (execve) =============="
3501
3502 test_30b() {
3503         cp `which ls` $DIR || cp /bin/ls $DIR
3504         chmod go+rx $DIR/ls
3505         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3506         rm $DIR/ls
3507 }
3508 run_test 30b "execute binary from Lustre as non-root ==========="
3509
3510 test_30c() { # b=22376
3511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3512
3513         cp $(which ls) $DIR || cp /bin/ls $DIR
3514         chmod a-rw $DIR/ls
3515         cancel_lru_locks mdc
3516         cancel_lru_locks osc
3517         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3518         rm -f $DIR/ls
3519 }
3520 run_test 30c "execute binary from Lustre without read perms ===="
3521
3522 test_30d() {
3523         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3524
3525         for i in {1..10}; do
3526                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3527                 local PID=$!
3528                 sleep 1
3529                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3530                 wait $PID || error "executing dd from Lustre failed"
3531                 rm -f $DIR/$tfile
3532         done
3533
3534         rm -f $DIR/dd
3535 }
3536 run_test 30d "execute binary from Lustre while clear locks"
3537
3538 test_31a() {
3539         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3540         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3541 }
3542 run_test 31a "open-unlink file =================================="
3543
3544 test_31b() {
3545         touch $DIR/f31 || error "touch $DIR/f31 failed"
3546         ln $DIR/f31 $DIR/f31b || error "ln failed"
3547         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3548         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3549 }
3550 run_test 31b "unlink file with multiple links while open ======="
3551
3552 test_31c() {
3553         touch $DIR/f31 || error "touch $DIR/f31 failed"
3554         ln $DIR/f31 $DIR/f31c || error "ln failed"
3555         multiop_bg_pause $DIR/f31 O_uc ||
3556                 error "multiop_bg_pause for $DIR/f31 failed"
3557         MULTIPID=$!
3558         $MULTIOP $DIR/f31c Ouc
3559         kill -USR1 $MULTIPID
3560         wait $MULTIPID
3561 }
3562 run_test 31c "open-unlink file with multiple links ============="
3563
3564 test_31d() {
3565         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3566         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3567 }
3568 run_test 31d "remove of open directory ========================="
3569
3570 test_31e() { # bug 2904
3571         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3572 }
3573 run_test 31e "remove of open non-empty directory ==============="
3574
3575 test_31f() { # bug 4554
3576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3577
3578         set -vx
3579         test_mkdir $DIR/d31f
3580         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3581         cp /etc/hosts $DIR/d31f
3582         ls -l $DIR/d31f
3583         $LFS getstripe $DIR/d31f/hosts
3584         multiop_bg_pause $DIR/d31f D_c || return 1
3585         MULTIPID=$!
3586
3587         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3588         test_mkdir $DIR/d31f
3589         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3590         cp /etc/hosts $DIR/d31f
3591         ls -l $DIR/d31f
3592         $LFS getstripe $DIR/d31f/hosts
3593         multiop_bg_pause $DIR/d31f D_c || return 1
3594         MULTIPID2=$!
3595
3596         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3597         wait $MULTIPID || error "first opendir $MULTIPID failed"
3598
3599         sleep 6
3600
3601         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3602         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3603         set +vx
3604 }
3605 run_test 31f "remove of open directory with open-unlink file ==="
3606
3607 test_31g() {
3608         echo "-- cross directory link --"
3609         test_mkdir -c1 $DIR/${tdir}ga
3610         test_mkdir -c1 $DIR/${tdir}gb
3611         touch $DIR/${tdir}ga/f
3612         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3613         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3614         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3615         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3616         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3617 }
3618 run_test 31g "cross directory link==============="
3619
3620 test_31h() {
3621         echo "-- cross directory link --"
3622         test_mkdir -c1 $DIR/${tdir}
3623         test_mkdir -c1 $DIR/${tdir}/dir
3624         touch $DIR/${tdir}/f
3625         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3626         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3627         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3628         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3629         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3630 }
3631 run_test 31h "cross directory link under child==============="
3632
3633 test_31i() {
3634         echo "-- cross directory link --"
3635         test_mkdir -c1 $DIR/$tdir
3636         test_mkdir -c1 $DIR/$tdir/dir
3637         touch $DIR/$tdir/dir/f
3638         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3639         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3640         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3641         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3642         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3643 }
3644 run_test 31i "cross directory link under parent==============="
3645
3646 test_31j() {
3647         test_mkdir -c1 -p $DIR/$tdir
3648         test_mkdir -c1 -p $DIR/$tdir/dir1
3649         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3650         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3651         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3652         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3653         return 0
3654 }
3655 run_test 31j "link for directory==============="
3656
3657 test_31k() {
3658         test_mkdir -c1 -p $DIR/$tdir
3659         touch $DIR/$tdir/s
3660         touch $DIR/$tdir/exist
3661         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3662         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3663         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3664         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3665         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3666         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3667         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3668         return 0
3669 }
3670 run_test 31k "link to file: the same, non-existing, dir==============="
3671
3672 test_31m() {
3673         mkdir $DIR/d31m
3674         touch $DIR/d31m/s
3675         mkdir $DIR/d31m2
3676         touch $DIR/d31m2/exist
3677         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3678         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3679         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3680         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3681         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3682         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3683         return 0
3684 }
3685 run_test 31m "link to file: the same, non-existing, dir==============="
3686
3687 test_31n() {
3688         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3689         nlink=$(stat --format=%h $DIR/$tfile)
3690         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3691         local fd=$(free_fd)
3692         local cmd="exec $fd<$DIR/$tfile"
3693         eval $cmd
3694         cmd="exec $fd<&-"
3695         trap "eval $cmd" EXIT
3696         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3697         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3698         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3699         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3700         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3701         eval $cmd
3702 }
3703 run_test 31n "check link count of unlinked file"
3704
3705 link_one() {
3706         local tempfile=$(mktemp $1_XXXXXX)
3707         mlink $tempfile $1 2> /dev/null &&
3708                 echo "$BASHPID: link $tempfile to $1 succeeded"
3709         munlink $tempfile
3710 }
3711
3712 test_31o() { # LU-2901
3713         test_mkdir $DIR/$tdir
3714         for LOOP in $(seq 100); do
3715                 rm -f $DIR/$tdir/$tfile*
3716                 for THREAD in $(seq 8); do
3717                         link_one $DIR/$tdir/$tfile.$LOOP &
3718                 done
3719                 wait
3720                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3721                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3722                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3723                         break || true
3724         done
3725 }
3726 run_test 31o "duplicate hard links with same filename"
3727
3728 test_31p() {
3729         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3730
3731         test_mkdir $DIR/$tdir
3732         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3733         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3734
3735         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3736                 error "open unlink test1 failed"
3737         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3738                 error "open unlink test2 failed"
3739
3740         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3741                 error "test1 still exists"
3742         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3743                 error "test2 still exists"
3744 }
3745 run_test 31p "remove of open striped directory"
3746
3747 test_31q() {
3748         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3749
3750         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3751         index=$($LFS getdirstripe -i $DIR/$tdir)
3752         [ $index -eq 3 ] || error "first stripe index $index != 3"
3753         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3754         [ $index -eq 1 ] || error "second stripe index $index != 1"
3755
3756         # when "-c <stripe_count>" is set, the number of MDTs specified after
3757         # "-i" should equal to the stripe count
3758         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3759 }
3760 run_test 31q "create striped directory on specific MDTs"
3761
3762 #LU-14949
3763 test_31r() {
3764         touch $DIR/$tfile.target
3765         touch $DIR/$tfile.source
3766
3767         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3768         $LCTL set_param fail_loc=0x1419 fail_val=3
3769         cat $DIR/$tfile.target &
3770         CATPID=$!
3771
3772         # Guarantee open is waiting before we get here
3773         sleep 1
3774         mv $DIR/$tfile.source $DIR/$tfile.target
3775
3776         wait $CATPID
3777         RC=$?
3778         if [[ $RC -ne 0 ]]; then
3779                 error "open with cat failed, rc=$RC"
3780         fi
3781 }
3782 run_test 31r "open-rename(replace) race"
3783
3784 cleanup_test32_mount() {
3785         local rc=0
3786         trap 0
3787         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3788         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3789         losetup -d $loopdev || true
3790         rm -rf $DIR/$tdir
3791         return $rc
3792 }
3793
3794 test_32a() {
3795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3796
3797         echo "== more mountpoints and symlinks ================="
3798         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3799         trap cleanup_test32_mount EXIT
3800         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3801         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3802                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3803         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3804                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3805         cleanup_test32_mount
3806 }
3807 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3808
3809 test_32b() {
3810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3811
3812         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3813         trap cleanup_test32_mount EXIT
3814         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3815         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3816                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3817         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3818                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3819         cleanup_test32_mount
3820 }
3821 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3822
3823 test_32c() {
3824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3825
3826         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3827         trap cleanup_test32_mount EXIT
3828         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3829         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3830                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3831         test_mkdir -p $DIR/$tdir/d2/test_dir
3832         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3833                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3834         cleanup_test32_mount
3835 }
3836 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3837
3838 test_32d() {
3839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3840
3841         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3842         trap cleanup_test32_mount EXIT
3843         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3844         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3845                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3846         test_mkdir -p $DIR/$tdir/d2/test_dir
3847         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3848                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3849         cleanup_test32_mount
3850 }
3851 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3852
3853 test_32e() {
3854         rm -fr $DIR/$tdir
3855         test_mkdir -p $DIR/$tdir/tmp
3856         local tmp_dir=$DIR/$tdir/tmp
3857         ln -s $DIR/$tdir $tmp_dir/symlink11
3858         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3859         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3860         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3861 }
3862 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3863
3864 test_32f() {
3865         rm -fr $DIR/$tdir
3866         test_mkdir -p $DIR/$tdir/tmp
3867         local tmp_dir=$DIR/$tdir/tmp
3868         ln -s $DIR/$tdir $tmp_dir/symlink11
3869         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3870         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3871         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3872 }
3873 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3874
3875 test_32g() {
3876         local tmp_dir=$DIR/$tdir/tmp
3877         test_mkdir -p $tmp_dir
3878         test_mkdir $DIR/${tdir}2
3879         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3880         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3881         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3882         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3883         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3884         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3885 }
3886 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3887
3888 test_32h() {
3889         rm -fr $DIR/$tdir $DIR/${tdir}2
3890         tmp_dir=$DIR/$tdir/tmp
3891         test_mkdir -p $tmp_dir
3892         test_mkdir $DIR/${tdir}2
3893         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3894         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3895         ls $tmp_dir/symlink12 || error "listing symlink12"
3896         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3897 }
3898 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3899
3900 test_32i() {
3901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3902
3903         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3904         trap cleanup_test32_mount EXIT
3905         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3906         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3907                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3908         touch $DIR/$tdir/test_file
3909         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3910                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3911         cleanup_test32_mount
3912 }
3913 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3914
3915 test_32j() {
3916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3917
3918         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3919         trap cleanup_test32_mount EXIT
3920         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3921         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3922                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3923         touch $DIR/$tdir/test_file
3924         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3925                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3926         cleanup_test32_mount
3927 }
3928 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3929
3930 test_32k() {
3931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3932
3933         rm -fr $DIR/$tdir
3934         trap cleanup_test32_mount EXIT
3935         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3936         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3937                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3938         test_mkdir -p $DIR/$tdir/d2
3939         touch $DIR/$tdir/d2/test_file || error "touch failed"
3940         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3941                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3942         cleanup_test32_mount
3943 }
3944 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3945
3946 test_32l() {
3947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3948
3949         rm -fr $DIR/$tdir
3950         trap cleanup_test32_mount EXIT
3951         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3952         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3953                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3954         test_mkdir -p $DIR/$tdir/d2
3955         touch $DIR/$tdir/d2/test_file || error "touch failed"
3956         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3957                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3958         cleanup_test32_mount
3959 }
3960 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3961
3962 test_32m() {
3963         rm -fr $DIR/d32m
3964         test_mkdir -p $DIR/d32m/tmp
3965         TMP_DIR=$DIR/d32m/tmp
3966         ln -s $DIR $TMP_DIR/symlink11
3967         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3968         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3969                 error "symlink11 not a link"
3970         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3971                 error "symlink01 not a link"
3972 }
3973 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3974
3975 test_32n() {
3976         rm -fr $DIR/d32n
3977         test_mkdir -p $DIR/d32n/tmp
3978         TMP_DIR=$DIR/d32n/tmp
3979         ln -s $DIR $TMP_DIR/symlink11
3980         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3981         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3982         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3983 }
3984 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3985
3986 test_32o() {
3987         touch $DIR/$tfile
3988         test_mkdir -p $DIR/d32o/tmp
3989         TMP_DIR=$DIR/d32o/tmp
3990         ln -s $DIR/$tfile $TMP_DIR/symlink12
3991         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3992         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3993                 error "symlink12 not a link"
3994         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3995         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3996                 error "$DIR/d32o/tmp/symlink12 not file type"
3997         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3998                 error "$DIR/d32o/symlink02 not file type"
3999 }
4000 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4001
4002 test_32p() {
4003         log 32p_1
4004         rm -fr $DIR/d32p
4005         log 32p_2
4006         rm -f $DIR/$tfile
4007         log 32p_3
4008         touch $DIR/$tfile
4009         log 32p_4
4010         test_mkdir -p $DIR/d32p/tmp
4011         log 32p_5
4012         TMP_DIR=$DIR/d32p/tmp
4013         log 32p_6
4014         ln -s $DIR/$tfile $TMP_DIR/symlink12
4015         log 32p_7
4016         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4017         log 32p_8
4018         cat $DIR/d32p/tmp/symlink12 ||
4019                 error "Can't open $DIR/d32p/tmp/symlink12"
4020         log 32p_9
4021         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4022         log 32p_10
4023 }
4024 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4025
4026 test_32q() {
4027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4028
4029         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4030         trap cleanup_test32_mount EXIT
4031         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4032         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4033         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4034                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4035         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4036         cleanup_test32_mount
4037 }
4038 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4039
4040 test_32r() {
4041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4042
4043         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4044         trap cleanup_test32_mount EXIT
4045         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4046         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4047         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4048                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4049         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4050         cleanup_test32_mount
4051 }
4052 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4053
4054 test_33aa() {
4055         rm -f $DIR/$tfile
4056         touch $DIR/$tfile
4057         chmod 444 $DIR/$tfile
4058         chown $RUNAS_ID $DIR/$tfile
4059         log 33_1
4060         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4061         log 33_2
4062 }
4063 run_test 33aa "write file with mode 444 (should return error)"
4064
4065 test_33a() {
4066         rm -fr $DIR/$tdir
4067         test_mkdir $DIR/$tdir
4068         chown $RUNAS_ID $DIR/$tdir
4069         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4070                 error "$RUNAS create $tdir/$tfile failed"
4071         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4072                 error "open RDWR" || true
4073 }
4074 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4075
4076 test_33b() {
4077         rm -fr $DIR/$tdir
4078         test_mkdir $DIR/$tdir
4079         chown $RUNAS_ID $DIR/$tdir
4080         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4081 }
4082 run_test 33b "test open file with malformed flags (No panic)"
4083
4084 test_33c() {
4085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4086         remote_ost_nodsh && skip "remote OST with nodsh"
4087
4088         local ostnum
4089         local ostname
4090         local write_bytes
4091         local all_zeros
4092
4093         all_zeros=true
4094         test_mkdir $DIR/$tdir
4095         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4096
4097         sync
4098         for ostnum in $(seq $OSTCOUNT); do
4099                 # test-framework's OST numbering is one-based, while Lustre's
4100                 # is zero-based
4101                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4102                 # check if at least some write_bytes stats are counted
4103                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4104                               obdfilter.$ostname.stats |
4105                               awk '/^write_bytes/ {print $7}' )
4106                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4107                 if (( ${write_bytes:-0} > 0 )); then
4108                         all_zeros=false
4109                         break
4110                 fi
4111         done
4112
4113         $all_zeros || return 0
4114
4115         # Write four bytes
4116         echo foo > $DIR/$tdir/bar
4117         # Really write them
4118         sync
4119
4120         # Total up write_bytes after writing.  We'd better find non-zeros.
4121         for ostnum in $(seq $OSTCOUNT); do
4122                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4123                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4124                               obdfilter/$ostname/stats |
4125                               awk '/^write_bytes/ {print $7}' )
4126                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4127                 if (( ${write_bytes:-0} > 0 )); then
4128                         all_zeros=false
4129                         break
4130                 fi
4131         done
4132
4133         if $all_zeros; then
4134                 for ostnum in $(seq $OSTCOUNT); do
4135                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4136                         echo "Check write_bytes is in obdfilter.*.stats:"
4137                         do_facet ost$ostnum lctl get_param -n \
4138                                 obdfilter.$ostname.stats
4139                 done
4140                 error "OST not keeping write_bytes stats (b=22312)"
4141         fi
4142 }
4143 run_test 33c "test write_bytes stats"
4144
4145 test_33d() {
4146         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4148
4149         local MDTIDX=1
4150         local remote_dir=$DIR/$tdir/remote_dir
4151
4152         test_mkdir $DIR/$tdir
4153         $LFS mkdir -i $MDTIDX $remote_dir ||
4154                 error "create remote directory failed"
4155
4156         touch $remote_dir/$tfile
4157         chmod 444 $remote_dir/$tfile
4158         chown $RUNAS_ID $remote_dir/$tfile
4159
4160         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4161
4162         chown $RUNAS_ID $remote_dir
4163         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4164                                         error "create" || true
4165         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4166                                     error "open RDWR" || true
4167         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4168 }
4169 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4170
4171 test_33e() {
4172         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4173
4174         mkdir $DIR/$tdir
4175
4176         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4177         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4178         mkdir $DIR/$tdir/local_dir
4179
4180         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4181         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4182         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4183
4184         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4185                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4186
4187         rmdir $DIR/$tdir/* || error "rmdir failed"
4188
4189         umask 777
4190         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4191         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4192         mkdir $DIR/$tdir/local_dir
4193
4194         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4195         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4196         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4197
4198         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4199                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4200
4201         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4202
4203         umask 000
4204         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4205         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4206         mkdir $DIR/$tdir/local_dir
4207
4208         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4209         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4210         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4211
4212         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4213                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4214 }
4215 run_test 33e "mkdir and striped directory should have same mode"
4216
4217 cleanup_33f() {
4218         trap 0
4219         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4220 }
4221
4222 test_33f() {
4223         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4224         remote_mds_nodsh && skip "remote MDS with nodsh"
4225
4226         mkdir $DIR/$tdir
4227         chmod go+rwx $DIR/$tdir
4228         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4229         trap cleanup_33f EXIT
4230
4231         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4232                 error "cannot create striped directory"
4233
4234         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4235                 error "cannot create files in striped directory"
4236
4237         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4238                 error "cannot remove files in striped directory"
4239
4240         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4241                 error "cannot remove striped directory"
4242
4243         cleanup_33f
4244 }
4245 run_test 33f "nonroot user can create, access, and remove a striped directory"
4246
4247 test_33g() {
4248         mkdir -p $DIR/$tdir/dir2
4249
4250         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4251         echo $err
4252         [[ $err =~ "exists" ]] || error "Not exists error"
4253 }
4254 run_test 33g "nonroot user create already existing root created file"
4255
4256 test_33h() {
4257         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4258         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4259                 skip "Need MDS version at least 2.13.50"
4260
4261         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4262                 error "mkdir $tdir failed"
4263         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4264
4265         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4266         local index2
4267
4268         for fname in $DIR/$tdir/$tfile.bak \
4269                      $DIR/$tdir/$tfile.SAV \
4270                      $DIR/$tdir/$tfile.orig \
4271                      $DIR/$tdir/$tfile~; do
4272                 touch $fname  || error "touch $fname failed"
4273                 index2=$($LFS getstripe -m $fname)
4274                 [ $index -eq $index2 ] ||
4275                         error "$fname MDT index mismatch $index != $index2"
4276         done
4277
4278         local failed=0
4279         for i in {1..250}; do
4280                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4281                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4282                         touch $fname  || error "touch $fname failed"
4283                         index2=$($LFS getstripe -m $fname)
4284                         if [[ $index != $index2 ]]; then
4285                                 failed=$((failed + 1))
4286                                 echo "$fname MDT index mismatch $index != $index2"
4287                         fi
4288                 done
4289         done
4290         echo "$failed MDT index mismatches"
4291         (( failed < 20 )) || error "MDT index mismatch $failed times"
4292
4293 }
4294 run_test 33h "temp file is located on the same MDT as target"
4295
4296 test_33i()
4297 {
4298         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4299
4300         local FNAME=$(str_repeat 'f' 250)
4301
4302         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4303         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4304
4305         local count
4306         local total
4307
4308         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4309
4310         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4311
4312         lctl --device %$MDC deactivate
4313         stack_trap "lctl --device %$MDC activate"
4314         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4315         total=$(\ls -l $DIR/$tdir | wc -l)
4316         # "ls -l" will list total in the first line
4317         total=$((total - 1))
4318         (( total + count == 1000 )) ||
4319                 error "ls list $total files, $count files on MDT1"
4320 }
4321 run_test 33i "striped directory can be accessed when one MDT is down"
4322
4323 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4324 test_34a() {
4325         rm -f $DIR/f34
4326         $MCREATE $DIR/f34 || error "mcreate failed"
4327         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4328                 error "getstripe failed"
4329         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4330         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4331                 error "getstripe failed"
4332         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4333                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4334 }
4335 run_test 34a "truncate file that has not been opened ==========="
4336
4337 test_34b() {
4338         [ ! -f $DIR/f34 ] && test_34a
4339         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4340                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4341         $OPENFILE -f O_RDONLY $DIR/f34
4342         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4343                 error "getstripe failed"
4344         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4345                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4346 }
4347 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4348
4349 test_34c() {
4350         [ ! -f $DIR/f34 ] && test_34a
4351         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4352                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4353         $OPENFILE -f O_RDWR $DIR/f34
4354         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4355                 error "$LFS getstripe failed"
4356         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4357                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4358 }
4359 run_test 34c "O_RDWR opening file-with-size works =============="
4360
4361 test_34d() {
4362         [ ! -f $DIR/f34 ] && test_34a
4363         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4364                 error "dd failed"
4365         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4366                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4367         rm $DIR/f34
4368 }
4369 run_test 34d "write to sparse file ============================="
4370
4371 test_34e() {
4372         rm -f $DIR/f34e
4373         $MCREATE $DIR/f34e || error "mcreate failed"
4374         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4375         $CHECKSTAT -s 1000 $DIR/f34e ||
4376                 error "Size of $DIR/f34e not equal to 1000 bytes"
4377         $OPENFILE -f O_RDWR $DIR/f34e
4378         $CHECKSTAT -s 1000 $DIR/f34e ||
4379                 error "Size of $DIR/f34e not equal to 1000 bytes"
4380 }
4381 run_test 34e "create objects, some with size and some without =="
4382
4383 test_34f() { # bug 6242, 6243
4384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4385
4386         SIZE34F=48000
4387         rm -f $DIR/f34f
4388         $MCREATE $DIR/f34f || error "mcreate failed"
4389         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4390         dd if=$DIR/f34f of=$TMP/f34f
4391         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4392         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4393         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4394         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4395         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4396 }
4397 run_test 34f "read from a file with no objects until EOF ======="
4398
4399 test_34g() {
4400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4401
4402         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4403                 error "dd failed"
4404         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4405         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4406                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4407         cancel_lru_locks osc
4408         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4409                 error "wrong size after lock cancel"
4410
4411         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4412         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4413                 error "expanding truncate failed"
4414         cancel_lru_locks osc
4415         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4416                 error "wrong expanded size after lock cancel"
4417 }
4418 run_test 34g "truncate long file ==============================="
4419
4420 test_34h() {
4421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4422
4423         local gid=10
4424         local sz=1000
4425
4426         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4427         sync # Flush the cache so that multiop below does not block on cache
4428              # flush when getting the group lock
4429         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4430         MULTIPID=$!
4431
4432         # Since just timed wait is not good enough, let's do a sync write
4433         # that way we are sure enough time for a roundtrip + processing
4434         # passed + 2 seconds of extra margin.
4435         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4436         rm $DIR/${tfile}-1
4437         sleep 2
4438
4439         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4440                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4441                 kill -9 $MULTIPID
4442         fi
4443         wait $MULTIPID
4444         local nsz=`stat -c %s $DIR/$tfile`
4445         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4446 }
4447 run_test 34h "ftruncate file under grouplock should not block"
4448
4449 test_35a() {
4450         cp /bin/sh $DIR/f35a
4451         chmod 444 $DIR/f35a
4452         chown $RUNAS_ID $DIR/f35a
4453         $RUNAS $DIR/f35a && error || true
4454         rm $DIR/f35a
4455 }
4456 run_test 35a "exec file with mode 444 (should return and not leak)"
4457
4458 test_36a() {
4459         rm -f $DIR/f36
4460         utime $DIR/f36 || error "utime failed for MDS"
4461 }
4462 run_test 36a "MDS utime check (mknod, utime)"
4463
4464 test_36b() {
4465         echo "" > $DIR/f36
4466         utime $DIR/f36 || error "utime failed for OST"
4467 }
4468 run_test 36b "OST utime check (open, utime)"
4469
4470 test_36c() {
4471         rm -f $DIR/d36/f36
4472         test_mkdir $DIR/d36
4473         chown $RUNAS_ID $DIR/d36
4474         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4475 }
4476 run_test 36c "non-root MDS utime check (mknod, utime)"
4477
4478 test_36d() {
4479         [ ! -d $DIR/d36 ] && test_36c
4480         echo "" > $DIR/d36/f36
4481         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4482 }
4483 run_test 36d "non-root OST utime check (open, utime)"
4484
4485 test_36e() {
4486         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4487
4488         test_mkdir $DIR/$tdir
4489         touch $DIR/$tdir/$tfile
4490         $RUNAS utime $DIR/$tdir/$tfile &&
4491                 error "utime worked, expected failure" || true
4492 }
4493 run_test 36e "utime on non-owned file (should return error)"
4494
4495 subr_36fh() {
4496         local fl="$1"
4497         local LANG_SAVE=$LANG
4498         local LC_LANG_SAVE=$LC_LANG
4499         export LANG=C LC_LANG=C # for date language
4500
4501         DATESTR="Dec 20  2000"
4502         test_mkdir $DIR/$tdir
4503         lctl set_param fail_loc=$fl
4504         date; date +%s
4505         cp /etc/hosts $DIR/$tdir/$tfile
4506         sync & # write RPC generated with "current" inode timestamp, but delayed
4507         sleep 1
4508         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4509         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4510         cancel_lru_locks $OSC
4511         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4512         date; date +%s
4513         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4514                 echo "BEFORE: $LS_BEFORE" && \
4515                 echo "AFTER : $LS_AFTER" && \
4516                 echo "WANT  : $DATESTR" && \
4517                 error "$DIR/$tdir/$tfile timestamps changed" || true
4518
4519         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4520 }
4521
4522 test_36f() {
4523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4524
4525         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4526         subr_36fh "0x80000214"
4527 }
4528 run_test 36f "utime on file racing with OST BRW write =========="
4529
4530 test_36g() {
4531         remote_ost_nodsh && skip "remote OST with nodsh"
4532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4533         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4534                 skip "Need MDS version at least 2.12.51"
4535
4536         local fmd_max_age
4537         local fmd
4538         local facet="ost1"
4539         local tgt="obdfilter"
4540
4541         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4542
4543         test_mkdir $DIR/$tdir
4544         fmd_max_age=$(do_facet $facet \
4545                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4546                 head -n 1")
4547
4548         echo "FMD max age: ${fmd_max_age}s"
4549         touch $DIR/$tdir/$tfile
4550         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4551                 gawk '{cnt=cnt+$1}  END{print cnt}')
4552         echo "FMD before: $fmd"
4553         [[ $fmd == 0 ]] &&
4554                 error "FMD wasn't create by touch"
4555         sleep $((fmd_max_age + 12))
4556         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4557                 gawk '{cnt=cnt+$1}  END{print cnt}')
4558         echo "FMD after: $fmd"
4559         [[ $fmd == 0 ]] ||
4560                 error "FMD wasn't expired by ping"
4561 }
4562 run_test 36g "FMD cache expiry ====================="
4563
4564 test_36h() {
4565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4566
4567         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4568         subr_36fh "0x80000227"
4569 }
4570 run_test 36h "utime on file racing with OST BRW write =========="
4571
4572 test_36i() {
4573         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4574
4575         test_mkdir $DIR/$tdir
4576         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4577
4578         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4579         local new_mtime=$((mtime + 200))
4580
4581         #change Modify time of striped dir
4582         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4583                         error "change mtime failed"
4584
4585         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4586
4587         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4588 }
4589 run_test 36i "change mtime on striped directory"
4590
4591 # test_37 - duplicate with tests 32q 32r
4592
4593 test_38() {
4594         local file=$DIR/$tfile
4595         touch $file
4596         openfile -f O_DIRECTORY $file
4597         local RC=$?
4598         local ENOTDIR=20
4599         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4600         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4601 }
4602 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4603
4604 test_39a() { # was test_39
4605         touch $DIR/$tfile
4606         touch $DIR/${tfile}2
4607 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4608 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4609 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4610         sleep 2
4611         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4612         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4613                 echo "mtime"
4614                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4615                 echo "atime"
4616                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4617                 echo "ctime"
4618                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4619                 error "O_TRUNC didn't change timestamps"
4620         fi
4621 }
4622 run_test 39a "mtime changed on create"
4623
4624 test_39b() {
4625         test_mkdir -c1 $DIR/$tdir
4626         cp -p /etc/passwd $DIR/$tdir/fopen
4627         cp -p /etc/passwd $DIR/$tdir/flink
4628         cp -p /etc/passwd $DIR/$tdir/funlink
4629         cp -p /etc/passwd $DIR/$tdir/frename
4630         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4631
4632         sleep 1
4633         echo "aaaaaa" >> $DIR/$tdir/fopen
4634         echo "aaaaaa" >> $DIR/$tdir/flink
4635         echo "aaaaaa" >> $DIR/$tdir/funlink
4636         echo "aaaaaa" >> $DIR/$tdir/frename
4637
4638         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4639         local link_new=`stat -c %Y $DIR/$tdir/flink`
4640         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4641         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4642
4643         cat $DIR/$tdir/fopen > /dev/null
4644         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4645         rm -f $DIR/$tdir/funlink2
4646         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4647
4648         for (( i=0; i < 2; i++ )) ; do
4649                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4650                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4651                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4652                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4653
4654                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4655                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4656                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4657                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4658
4659                 cancel_lru_locks $OSC
4660                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4661         done
4662 }
4663 run_test 39b "mtime change on open, link, unlink, rename  ======"
4664
4665 # this should be set to past
4666 TEST_39_MTIME=`date -d "1 year ago" +%s`
4667
4668 # bug 11063
4669 test_39c() {
4670         touch $DIR1/$tfile
4671         sleep 2
4672         local mtime0=`stat -c %Y $DIR1/$tfile`
4673
4674         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4675         local mtime1=`stat -c %Y $DIR1/$tfile`
4676         [ "$mtime1" = $TEST_39_MTIME ] || \
4677                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4678
4679         local d1=`date +%s`
4680         echo hello >> $DIR1/$tfile
4681         local d2=`date +%s`
4682         local mtime2=`stat -c %Y $DIR1/$tfile`
4683         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4684                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4685
4686         mv $DIR1/$tfile $DIR1/$tfile-1
4687
4688         for (( i=0; i < 2; i++ )) ; do
4689                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4690                 [ "$mtime2" = "$mtime3" ] || \
4691                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4692
4693                 cancel_lru_locks $OSC
4694                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4695         done
4696 }
4697 run_test 39c "mtime change on rename ==========================="
4698
4699 # bug 21114
4700 test_39d() {
4701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4702
4703         touch $DIR1/$tfile
4704         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4705
4706         for (( i=0; i < 2; i++ )) ; do
4707                 local mtime=`stat -c %Y $DIR1/$tfile`
4708                 [ $mtime = $TEST_39_MTIME ] || \
4709                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4710
4711                 cancel_lru_locks $OSC
4712                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4713         done
4714 }
4715 run_test 39d "create, utime, stat =============================="
4716
4717 # bug 21114
4718 test_39e() {
4719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4720
4721         touch $DIR1/$tfile
4722         local mtime1=`stat -c %Y $DIR1/$tfile`
4723
4724         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4725
4726         for (( i=0; i < 2; i++ )) ; do
4727                 local mtime2=`stat -c %Y $DIR1/$tfile`
4728                 [ $mtime2 = $TEST_39_MTIME ] || \
4729                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4730
4731                 cancel_lru_locks $OSC
4732                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4733         done
4734 }
4735 run_test 39e "create, stat, utime, stat ========================"
4736
4737 # bug 21114
4738 test_39f() {
4739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4740
4741         touch $DIR1/$tfile
4742         mtime1=`stat -c %Y $DIR1/$tfile`
4743
4744         sleep 2
4745         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4746
4747         for (( i=0; i < 2; i++ )) ; do
4748                 local mtime2=`stat -c %Y $DIR1/$tfile`
4749                 [ $mtime2 = $TEST_39_MTIME ] || \
4750                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4751
4752                 cancel_lru_locks $OSC
4753                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4754         done
4755 }
4756 run_test 39f "create, stat, sleep, utime, stat ================="
4757
4758 # bug 11063
4759 test_39g() {
4760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4761
4762         echo hello >> $DIR1/$tfile
4763         local mtime1=`stat -c %Y $DIR1/$tfile`
4764
4765         sleep 2
4766         chmod o+r $DIR1/$tfile
4767
4768         for (( i=0; i < 2; i++ )) ; do
4769                 local mtime2=`stat -c %Y $DIR1/$tfile`
4770                 [ "$mtime1" = "$mtime2" ] || \
4771                         error "lost mtime: $mtime2, should be $mtime1"
4772
4773                 cancel_lru_locks $OSC
4774                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4775         done
4776 }
4777 run_test 39g "write, chmod, stat ==============================="
4778
4779 # bug 11063
4780 test_39h() {
4781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4782
4783         touch $DIR1/$tfile
4784         sleep 1
4785
4786         local d1=`date`
4787         echo hello >> $DIR1/$tfile
4788         local mtime1=`stat -c %Y $DIR1/$tfile`
4789
4790         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4791         local d2=`date`
4792         if [ "$d1" != "$d2" ]; then
4793                 echo "write and touch not within one second"
4794         else
4795                 for (( i=0; i < 2; i++ )) ; do
4796                         local mtime2=`stat -c %Y $DIR1/$tfile`
4797                         [ "$mtime2" = $TEST_39_MTIME ] || \
4798                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4799
4800                         cancel_lru_locks $OSC
4801                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4802                 done
4803         fi
4804 }
4805 run_test 39h "write, utime within one second, stat ============="
4806
4807 test_39i() {
4808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4809
4810         touch $DIR1/$tfile
4811         sleep 1
4812
4813         echo hello >> $DIR1/$tfile
4814         local mtime1=`stat -c %Y $DIR1/$tfile`
4815
4816         mv $DIR1/$tfile $DIR1/$tfile-1
4817
4818         for (( i=0; i < 2; i++ )) ; do
4819                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4820
4821                 [ "$mtime1" = "$mtime2" ] || \
4822                         error "lost mtime: $mtime2, should be $mtime1"
4823
4824                 cancel_lru_locks $OSC
4825                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4826         done
4827 }
4828 run_test 39i "write, rename, stat =============================="
4829
4830 test_39j() {
4831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4832
4833         start_full_debug_logging
4834         touch $DIR1/$tfile
4835         sleep 1
4836
4837         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4838         lctl set_param fail_loc=0x80000412
4839         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4840                 error "multiop failed"
4841         local multipid=$!
4842         local mtime1=`stat -c %Y $DIR1/$tfile`
4843
4844         mv $DIR1/$tfile $DIR1/$tfile-1
4845
4846         kill -USR1 $multipid
4847         wait $multipid || error "multiop close failed"
4848
4849         for (( i=0; i < 2; i++ )) ; do
4850                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4851                 [ "$mtime1" = "$mtime2" ] ||
4852                         error "mtime is lost on close: $mtime2, " \
4853                               "should be $mtime1"
4854
4855                 cancel_lru_locks
4856                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4857         done
4858         lctl set_param fail_loc=0
4859         stop_full_debug_logging
4860 }
4861 run_test 39j "write, rename, close, stat ======================="
4862
4863 test_39k() {
4864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4865
4866         touch $DIR1/$tfile
4867         sleep 1
4868
4869         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4870         local multipid=$!
4871         local mtime1=`stat -c %Y $DIR1/$tfile`
4872
4873         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4874
4875         kill -USR1 $multipid
4876         wait $multipid || error "multiop close failed"
4877
4878         for (( i=0; i < 2; i++ )) ; do
4879                 local mtime2=`stat -c %Y $DIR1/$tfile`
4880
4881                 [ "$mtime2" = $TEST_39_MTIME ] || \
4882                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4883
4884                 cancel_lru_locks
4885                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4886         done
4887 }
4888 run_test 39k "write, utime, close, stat ========================"
4889
4890 # this should be set to future
4891 TEST_39_ATIME=`date -d "1 year" +%s`
4892
4893 test_39l() {
4894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4895         remote_mds_nodsh && skip "remote MDS with nodsh"
4896
4897         local atime_diff=$(do_facet $SINGLEMDS \
4898                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4899         rm -rf $DIR/$tdir
4900         mkdir_on_mdt0 $DIR/$tdir
4901
4902         # test setting directory atime to future
4903         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4904         local atime=$(stat -c %X $DIR/$tdir)
4905         [ "$atime" = $TEST_39_ATIME ] ||
4906                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4907
4908         # test setting directory atime from future to now
4909         local now=$(date +%s)
4910         touch -a -d @$now $DIR/$tdir
4911
4912         atime=$(stat -c %X $DIR/$tdir)
4913         [ "$atime" -eq "$now"  ] ||
4914                 error "atime is not updated from future: $atime, $now"
4915
4916         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4917         sleep 3
4918
4919         # test setting directory atime when now > dir atime + atime_diff
4920         local d1=$(date +%s)
4921         ls $DIR/$tdir
4922         local d2=$(date +%s)
4923         cancel_lru_locks mdc
4924         atime=$(stat -c %X $DIR/$tdir)
4925         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4926                 error "atime is not updated  : $atime, should be $d2"
4927
4928         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4929         sleep 3
4930
4931         # test not setting directory atime when now < dir atime + atime_diff
4932         ls $DIR/$tdir
4933         cancel_lru_locks mdc
4934         atime=$(stat -c %X $DIR/$tdir)
4935         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4936                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4937
4938         do_facet $SINGLEMDS \
4939                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4940 }
4941 run_test 39l "directory atime update ==========================="
4942
4943 test_39m() {
4944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4945
4946         touch $DIR1/$tfile
4947         sleep 2
4948         local far_past_mtime=$(date -d "May 29 1953" +%s)
4949         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4950
4951         touch -m -d @$far_past_mtime $DIR1/$tfile
4952         touch -a -d @$far_past_atime $DIR1/$tfile
4953
4954         for (( i=0; i < 2; i++ )) ; do
4955                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4956                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4957                         error "atime or mtime set incorrectly"
4958
4959                 cancel_lru_locks $OSC
4960                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4961         done
4962 }
4963 run_test 39m "test atime and mtime before 1970"
4964
4965 test_39n() { # LU-3832
4966         remote_mds_nodsh && skip "remote MDS with nodsh"
4967
4968         local atime_diff=$(do_facet $SINGLEMDS \
4969                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4970         local atime0
4971         local atime1
4972         local atime2
4973
4974         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4975
4976         rm -rf $DIR/$tfile
4977         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4978         atime0=$(stat -c %X $DIR/$tfile)
4979
4980         sleep 5
4981         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4982         atime1=$(stat -c %X $DIR/$tfile)
4983
4984         sleep 5
4985         cancel_lru_locks mdc
4986         cancel_lru_locks osc
4987         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4988         atime2=$(stat -c %X $DIR/$tfile)
4989
4990         do_facet $SINGLEMDS \
4991                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4992
4993         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4994         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4995 }
4996 run_test 39n "check that O_NOATIME is honored"
4997
4998 test_39o() {
4999         TESTDIR=$DIR/$tdir/$tfile
5000         [ -e $TESTDIR ] && rm -rf $TESTDIR
5001         mkdir -p $TESTDIR
5002         cd $TESTDIR
5003         links1=2
5004         ls
5005         mkdir a b
5006         ls
5007         links2=$(stat -c %h .)
5008         [ $(($links1 + 2)) != $links2 ] &&
5009                 error "wrong links count $(($links1 + 2)) != $links2"
5010         rmdir b
5011         links3=$(stat -c %h .)
5012         [ $(($links1 + 1)) != $links3 ] &&
5013                 error "wrong links count $links1 != $links3"
5014         return 0
5015 }
5016 run_test 39o "directory cached attributes updated after create"
5017
5018 test_39p() {
5019         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5020
5021         local MDTIDX=1
5022         TESTDIR=$DIR/$tdir/$tdir
5023         [ -e $TESTDIR ] && rm -rf $TESTDIR
5024         test_mkdir -p $TESTDIR
5025         cd $TESTDIR
5026         links1=2
5027         ls
5028         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5029         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5030         ls
5031         links2=$(stat -c %h .)
5032         [ $(($links1 + 2)) != $links2 ] &&
5033                 error "wrong links count $(($links1 + 2)) != $links2"
5034         rmdir remote_dir2
5035         links3=$(stat -c %h .)
5036         [ $(($links1 + 1)) != $links3 ] &&
5037                 error "wrong links count $links1 != $links3"
5038         return 0
5039 }
5040 run_test 39p "remote directory cached attributes updated after create ========"
5041
5042 test_39r() {
5043         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5044                 skip "no atime update on old OST"
5045         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5046                 skip_env "ldiskfs only test"
5047         fi
5048
5049         local saved_adiff
5050         saved_adiff=$(do_facet ost1 \
5051                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5052         stack_trap "do_facet ost1 \
5053                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5054
5055         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5056
5057         $LFS setstripe -i 0 $DIR/$tfile
5058         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5059                 error "can't write initial file"
5060         cancel_lru_locks osc
5061
5062         # exceed atime_diff and access file
5063         sleep 6
5064         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5065                 error "can't udpate atime"
5066
5067         local atime_cli=$(stat -c %X $DIR/$tfile)
5068         echo "client atime: $atime_cli"
5069         # allow atime update to be written to device
5070         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5071         sleep 5
5072
5073         local ostdev=$(ostdevname 1)
5074         local fid=($(lfs getstripe -y $DIR/$tfile |
5075                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5076         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5077         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5078
5079         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5080         local atime_ost=$(do_facet ost1 "$cmd" |&
5081                           awk -F'[: ]' '/atime:/ { print $4 }')
5082         (( atime_cli == atime_ost )) ||
5083                 error "atime on client $atime_cli != ost $atime_ost"
5084 }
5085 run_test 39r "lazy atime update on OST"
5086
5087 test_39q() { # LU-8041
5088         local testdir=$DIR/$tdir
5089         mkdir -p $testdir
5090         multiop_bg_pause $testdir D_c || error "multiop failed"
5091         local multipid=$!
5092         cancel_lru_locks mdc
5093         kill -USR1 $multipid
5094         local atime=$(stat -c %X $testdir)
5095         [ "$atime" -ne 0 ] || error "atime is zero"
5096 }
5097 run_test 39q "close won't zero out atime"
5098
5099 test_40() {
5100         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5101         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5102                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5103         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5104                 error "$tfile is not 4096 bytes in size"
5105 }
5106 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5107
5108 test_41() {
5109         # bug 1553
5110         small_write $DIR/f41 18
5111 }
5112 run_test 41 "test small file write + fstat ====================="
5113
5114 count_ost_writes() {
5115         lctl get_param -n ${OSC}.*.stats |
5116                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5117                         END { printf("%0.0f", writes) }'
5118 }
5119
5120 # decent default
5121 WRITEBACK_SAVE=500
5122 DIRTY_RATIO_SAVE=40
5123 MAX_DIRTY_RATIO=50
5124 BG_DIRTY_RATIO_SAVE=10
5125 MAX_BG_DIRTY_RATIO=25
5126
5127 start_writeback() {
5128         trap 0
5129         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5130         # dirty_ratio, dirty_background_ratio
5131         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5132                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5133                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5134                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5135         else
5136                 # if file not here, we are a 2.4 kernel
5137                 kill -CONT `pidof kupdated`
5138         fi
5139 }
5140
5141 stop_writeback() {
5142         # setup the trap first, so someone cannot exit the test at the
5143         # exact wrong time and mess up a machine
5144         trap start_writeback EXIT
5145         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5146         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5147                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5148                 sysctl -w vm.dirty_writeback_centisecs=0
5149                 sysctl -w vm.dirty_writeback_centisecs=0
5150                 # save and increase /proc/sys/vm/dirty_ratio
5151                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5152                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5153                 # save and increase /proc/sys/vm/dirty_background_ratio
5154                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5155                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5156         else
5157                 # if file not here, we are a 2.4 kernel
5158                 kill -STOP `pidof kupdated`
5159         fi
5160 }
5161
5162 # ensure that all stripes have some grant before we test client-side cache
5163 setup_test42() {
5164         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5165                 dd if=/dev/zero of=$i bs=4k count=1
5166                 rm $i
5167         done
5168 }
5169
5170 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5171 # file truncation, and file removal.
5172 test_42a() {
5173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5174
5175         setup_test42
5176         cancel_lru_locks $OSC
5177         stop_writeback
5178         sync; sleep 1; sync # just to be safe
5179         BEFOREWRITES=`count_ost_writes`
5180         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5181         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5182         AFTERWRITES=`count_ost_writes`
5183         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5184                 error "$BEFOREWRITES < $AFTERWRITES"
5185         start_writeback
5186 }
5187 run_test 42a "ensure that we don't flush on close"
5188
5189 test_42b() {
5190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5191
5192         setup_test42
5193         cancel_lru_locks $OSC
5194         stop_writeback
5195         sync
5196         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5197         BEFOREWRITES=$(count_ost_writes)
5198         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5199         AFTERWRITES=$(count_ost_writes)
5200         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5201                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5202         fi
5203         BEFOREWRITES=$(count_ost_writes)
5204         sync || error "sync: $?"
5205         AFTERWRITES=$(count_ost_writes)
5206         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5207                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5208         fi
5209         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5210         start_writeback
5211         return 0
5212 }
5213 run_test 42b "test destroy of file with cached dirty data ======"
5214
5215 # if these tests just want to test the effect of truncation,
5216 # they have to be very careful.  consider:
5217 # - the first open gets a {0,EOF}PR lock
5218 # - the first write conflicts and gets a {0, count-1}PW
5219 # - the rest of the writes are under {count,EOF}PW
5220 # - the open for truncate tries to match a {0,EOF}PR
5221 #   for the filesize and cancels the PWs.
5222 # any number of fixes (don't get {0,EOF} on open, match
5223 # composite locks, do smarter file size management) fix
5224 # this, but for now we want these tests to verify that
5225 # the cancellation with truncate intent works, so we
5226 # start the file with a full-file pw lock to match against
5227 # until the truncate.
5228 trunc_test() {
5229         test=$1
5230         file=$DIR/$test
5231         offset=$2
5232         cancel_lru_locks $OSC
5233         stop_writeback
5234         # prime the file with 0,EOF PW to match
5235         touch $file
5236         $TRUNCATE $file 0
5237         sync; sync
5238         # now the real test..
5239         dd if=/dev/zero of=$file bs=1024 count=100
5240         BEFOREWRITES=`count_ost_writes`
5241         $TRUNCATE $file $offset
5242         cancel_lru_locks $OSC
5243         AFTERWRITES=`count_ost_writes`
5244         start_writeback
5245 }
5246
5247 test_42c() {
5248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5249
5250         trunc_test 42c 1024
5251         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5252                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5253         rm $file
5254 }
5255 run_test 42c "test partial truncate of file with cached dirty data"
5256
5257 test_42d() {
5258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5259
5260         trunc_test 42d 0
5261         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5262                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5263         rm $file
5264 }
5265 run_test 42d "test complete truncate of file with cached dirty data"
5266
5267 test_42e() { # bug22074
5268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5269
5270         local TDIR=$DIR/${tdir}e
5271         local pages=16 # hardcoded 16 pages, don't change it.
5272         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5273         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5274         local max_dirty_mb
5275         local warmup_files
5276
5277         test_mkdir $DIR/${tdir}e
5278         $LFS setstripe -c 1 $TDIR
5279         createmany -o $TDIR/f $files
5280
5281         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5282
5283         # we assume that with $OSTCOUNT files, at least one of them will
5284         # be allocated on OST0.
5285         warmup_files=$((OSTCOUNT * max_dirty_mb))
5286         createmany -o $TDIR/w $warmup_files
5287
5288         # write a large amount of data into one file and sync, to get good
5289         # avail_grant number from OST.
5290         for ((i=0; i<$warmup_files; i++)); do
5291                 idx=$($LFS getstripe -i $TDIR/w$i)
5292                 [ $idx -ne 0 ] && continue
5293                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5294                 break
5295         done
5296         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5297         sync
5298         $LCTL get_param $proc_osc0/cur_dirty_bytes
5299         $LCTL get_param $proc_osc0/cur_grant_bytes
5300
5301         # create as much dirty pages as we can while not to trigger the actual
5302         # RPCs directly. but depends on the env, VFS may trigger flush during this
5303         # period, hopefully we are good.
5304         for ((i=0; i<$warmup_files; i++)); do
5305                 idx=$($LFS getstripe -i $TDIR/w$i)
5306                 [ $idx -ne 0 ] && continue
5307                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5308         done
5309         $LCTL get_param $proc_osc0/cur_dirty_bytes
5310         $LCTL get_param $proc_osc0/cur_grant_bytes
5311
5312         # perform the real test
5313         $LCTL set_param $proc_osc0/rpc_stats 0
5314         for ((;i<$files; i++)); do
5315                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5316                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5317         done
5318         sync
5319         $LCTL get_param $proc_osc0/rpc_stats
5320
5321         local percent=0
5322         local have_ppr=false
5323         $LCTL get_param $proc_osc0/rpc_stats |
5324                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5325                         # skip lines until we are at the RPC histogram data
5326                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5327                         $have_ppr || continue
5328
5329                         # we only want the percent stat for < 16 pages
5330                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5331
5332                         percent=$((percent + WPCT))
5333                         if [[ $percent -gt 15 ]]; then
5334                                 error "less than 16-pages write RPCs" \
5335                                       "$percent% > 15%"
5336                                 break
5337                         fi
5338                 done
5339         rm -rf $TDIR
5340 }
5341 run_test 42e "verify sub-RPC writes are not done synchronously"
5342
5343 test_43A() { # was test_43
5344         test_mkdir $DIR/$tdir
5345         cp -p /bin/ls $DIR/$tdir/$tfile
5346         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5347         pid=$!
5348         # give multiop a chance to open
5349         sleep 1
5350
5351         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5352         kill -USR1 $pid
5353         # Wait for multiop to exit
5354         wait $pid
5355 }
5356 run_test 43A "execution of file opened for write should return -ETXTBSY"
5357
5358 test_43a() {
5359         test_mkdir $DIR/$tdir
5360         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5361         $DIR/$tdir/sleep 60 &
5362         SLEEP_PID=$!
5363         # Make sure exec of $tdir/sleep wins race with truncate
5364         sleep 1
5365         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5366         kill $SLEEP_PID
5367 }
5368 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5369
5370 test_43b() {
5371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5372
5373         test_mkdir $DIR/$tdir
5374         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5375         $DIR/$tdir/sleep 60 &
5376         SLEEP_PID=$!
5377         # Make sure exec of $tdir/sleep wins race with truncate
5378         sleep 1
5379         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5380         kill $SLEEP_PID
5381 }
5382 run_test 43b "truncate of file being executed should return -ETXTBSY"
5383
5384 test_43c() {
5385         local testdir="$DIR/$tdir"
5386         test_mkdir $testdir
5387         cp $SHELL $testdir/
5388         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5389                 ( cd $testdir && md5sum -c )
5390 }
5391 run_test 43c "md5sum of copy into lustre"
5392
5393 test_44A() { # was test_44
5394         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5395
5396         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5397         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5398 }
5399 run_test 44A "zero length read from a sparse stripe"
5400
5401 test_44a() {
5402         local nstripe=$($LFS getstripe -c -d $DIR)
5403         [ -z "$nstripe" ] && skip "can't get stripe info"
5404         [[ $nstripe -gt $OSTCOUNT ]] &&
5405                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5406
5407         local stride=$($LFS getstripe -S -d $DIR)
5408         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5409                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5410         fi
5411
5412         OFFSETS="0 $((stride/2)) $((stride-1))"
5413         for offset in $OFFSETS; do
5414                 for i in $(seq 0 $((nstripe-1))); do
5415                         local GLOBALOFFSETS=""
5416                         # size in Bytes
5417                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5418                         local myfn=$DIR/d44a-$size
5419                         echo "--------writing $myfn at $size"
5420                         ll_sparseness_write $myfn $size ||
5421                                 error "ll_sparseness_write"
5422                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5423                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5424                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5425
5426                         for j in $(seq 0 $((nstripe-1))); do
5427                                 # size in Bytes
5428                                 size=$((((j + $nstripe )*$stride + $offset)))
5429                                 ll_sparseness_write $myfn $size ||
5430                                         error "ll_sparseness_write"
5431                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5432                         done
5433                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5434                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5435                         rm -f $myfn
5436                 done
5437         done
5438 }
5439 run_test 44a "test sparse pwrite ==============================="
5440
5441 dirty_osc_total() {
5442         tot=0
5443         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5444                 tot=$(($tot + $d))
5445         done
5446         echo $tot
5447 }
5448 do_dirty_record() {
5449         before=`dirty_osc_total`
5450         echo executing "\"$*\""
5451         eval $*
5452         after=`dirty_osc_total`
5453         echo before $before, after $after
5454 }
5455 test_45() {
5456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5457
5458         f="$DIR/f45"
5459         # Obtain grants from OST if it supports it
5460         echo blah > ${f}_grant
5461         stop_writeback
5462         sync
5463         do_dirty_record "echo blah > $f"
5464         [[ $before -eq $after ]] && error "write wasn't cached"
5465         do_dirty_record "> $f"
5466         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5467         do_dirty_record "echo blah > $f"
5468         [[ $before -eq $after ]] && error "write wasn't cached"
5469         do_dirty_record "sync"
5470         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5471         do_dirty_record "echo blah > $f"
5472         [[ $before -eq $after ]] && error "write wasn't cached"
5473         do_dirty_record "cancel_lru_locks osc"
5474         [[ $before -gt $after ]] ||
5475                 error "lock cancellation didn't lower dirty count"
5476         start_writeback
5477 }
5478 run_test 45 "osc io page accounting ============================"
5479
5480 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5481 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5482 # objects offset and an assert hit when an rpc was built with 1023's mapped
5483 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5484 test_46() {
5485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5486
5487         f="$DIR/f46"
5488         stop_writeback
5489         sync
5490         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5491         sync
5492         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5493         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5494         sync
5495         start_writeback
5496 }
5497 run_test 46 "dirtying a previously written page ================"
5498
5499 # test_47 is removed "Device nodes check" is moved to test_28
5500
5501 test_48a() { # bug 2399
5502         [ "$mds1_FSTYPE" = "zfs" ] &&
5503         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5504                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5505
5506         test_mkdir $DIR/$tdir
5507         cd $DIR/$tdir
5508         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5509         test_mkdir $DIR/$tdir
5510         touch foo || error "'touch foo' failed after recreating cwd"
5511         test_mkdir bar
5512         touch .foo || error "'touch .foo' failed after recreating cwd"
5513         test_mkdir .bar
5514         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5515         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5516         cd . || error "'cd .' failed after recreating cwd"
5517         mkdir . && error "'mkdir .' worked after recreating cwd"
5518         rmdir . && error "'rmdir .' worked after recreating cwd"
5519         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5520         cd .. || error "'cd ..' failed after recreating cwd"
5521 }
5522 run_test 48a "Access renamed working dir (should return errors)="
5523
5524 test_48b() { # bug 2399
5525         rm -rf $DIR/$tdir
5526         test_mkdir $DIR/$tdir
5527         cd $DIR/$tdir
5528         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5529         touch foo && error "'touch foo' worked after removing cwd"
5530         mkdir foo && error "'mkdir foo' worked after removing cwd"
5531         touch .foo && error "'touch .foo' worked after removing cwd"
5532         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5533         ls . > /dev/null && error "'ls .' worked after removing cwd"
5534         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5535         mkdir . && error "'mkdir .' worked after removing cwd"
5536         rmdir . && error "'rmdir .' worked after removing cwd"
5537         ln -s . foo && error "'ln -s .' worked after removing cwd"
5538         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5539 }
5540 run_test 48b "Access removed working dir (should return errors)="
5541
5542 test_48c() { # bug 2350
5543         #lctl set_param debug=-1
5544         #set -vx
5545         rm -rf $DIR/$tdir
5546         test_mkdir -p $DIR/$tdir/dir
5547         cd $DIR/$tdir/dir
5548         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5549         $TRACE touch foo && error "touch foo worked after removing cwd"
5550         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5551         touch .foo && error "touch .foo worked after removing cwd"
5552         mkdir .foo && error "mkdir .foo worked after removing cwd"
5553         $TRACE ls . && error "'ls .' worked after removing cwd"
5554         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5555         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5556         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5557         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5558         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5559 }
5560 run_test 48c "Access removed working subdir (should return errors)"
5561
5562 test_48d() { # bug 2350
5563         #lctl set_param debug=-1
5564         #set -vx
5565         rm -rf $DIR/$tdir
5566         test_mkdir -p $DIR/$tdir/dir
5567         cd $DIR/$tdir/dir
5568         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5569         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5570         $TRACE touch foo && error "'touch foo' worked after removing parent"
5571         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5572         touch .foo && error "'touch .foo' worked after removing parent"
5573         mkdir .foo && error "mkdir .foo worked after removing parent"
5574         $TRACE ls . && error "'ls .' worked after removing parent"
5575         $TRACE ls .. && error "'ls ..' worked after removing parent"
5576         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5577         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5578         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5579         true
5580 }
5581 run_test 48d "Access removed parent subdir (should return errors)"
5582
5583 test_48e() { # bug 4134
5584         #lctl set_param debug=-1
5585         #set -vx
5586         rm -rf $DIR/$tdir
5587         test_mkdir -p $DIR/$tdir/dir
5588         cd $DIR/$tdir/dir
5589         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5590         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5591         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5592         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5593         # On a buggy kernel addition of "touch foo" after cd .. will
5594         # produce kernel oops in lookup_hash_it
5595         touch ../foo && error "'cd ..' worked after recreate parent"
5596         cd $DIR
5597         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5598 }
5599 run_test 48e "Access to recreated parent subdir (should return errors)"
5600
5601 test_48f() {
5602         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5603                 skip "need MDS >= 2.13.55"
5604         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5605         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5606                 skip "needs different host for mdt1 mdt2"
5607         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5608
5609         $LFS mkdir -i0 $DIR/$tdir
5610         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5611
5612         for d in sub1 sub2 sub3; do
5613                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5614                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5615                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5616         done
5617
5618         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5619 }
5620 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5621
5622 test_49() { # LU-1030
5623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5624         remote_ost_nodsh && skip "remote OST with nodsh"
5625
5626         # get ost1 size - $FSNAME-OST0000
5627         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5628                 awk '{ print $4 }')
5629         # write 800M at maximum
5630         [[ $ost1_size -lt 2 ]] && ost1_size=2
5631         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5632
5633         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5634         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5635         local dd_pid=$!
5636
5637         # change max_pages_per_rpc while writing the file
5638         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5639         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5640         # loop until dd process exits
5641         while ps ax -opid | grep -wq $dd_pid; do
5642                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5643                 sleep $((RANDOM % 5 + 1))
5644         done
5645         # restore original max_pages_per_rpc
5646         $LCTL set_param $osc1_mppc=$orig_mppc
5647         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5648 }
5649 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5650
5651 test_50() {
5652         # bug 1485
5653         test_mkdir $DIR/$tdir
5654         cd $DIR/$tdir
5655         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5656 }
5657 run_test 50 "special situations: /proc symlinks  ==============="
5658
5659 test_51a() {    # was test_51
5660         # bug 1516 - create an empty entry right after ".." then split dir
5661         test_mkdir -c1 $DIR/$tdir
5662         touch $DIR/$tdir/foo
5663         $MCREATE $DIR/$tdir/bar
5664         rm $DIR/$tdir/foo
5665         createmany -m $DIR/$tdir/longfile 201
5666         FNUM=202
5667         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5668                 $MCREATE $DIR/$tdir/longfile$FNUM
5669                 FNUM=$(($FNUM + 1))
5670                 echo -n "+"
5671         done
5672         echo
5673         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5674 }
5675 run_test 51a "special situations: split htree with empty entry =="
5676
5677 cleanup_print_lfs_df () {
5678         trap 0
5679         $LFS df
5680         $LFS df -i
5681 }
5682
5683 test_51b() {
5684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5685
5686         local dir=$DIR/$tdir
5687         local nrdirs=$((65536 + 100))
5688
5689         # cleanup the directory
5690         rm -fr $dir
5691
5692         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5693
5694         $LFS df
5695         $LFS df -i
5696         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5697         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5698         [[ $numfree -lt $nrdirs ]] &&
5699                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5700
5701         # need to check free space for the directories as well
5702         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5703         numfree=$(( blkfree / $(fs_inode_ksize) ))
5704         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5705
5706         trap cleanup_print_lfs_df EXIT
5707
5708         # create files
5709         createmany -d $dir/d $nrdirs || {
5710                 unlinkmany $dir/d $nrdirs
5711                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5712         }
5713
5714         # really created :
5715         nrdirs=$(ls -U $dir | wc -l)
5716
5717         # unlink all but 100 subdirectories, then check it still works
5718         local left=100
5719         local delete=$((nrdirs - left))
5720
5721         $LFS df
5722         $LFS df -i
5723
5724         # for ldiskfs the nlink count should be 1, but this is OSD specific
5725         # and so this is listed for informational purposes only
5726         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5727         unlinkmany -d $dir/d $delete ||
5728                 error "unlink of first $delete subdirs failed"
5729
5730         echo "nlink between: $(stat -c %h $dir)"
5731         local found=$(ls -U $dir | wc -l)
5732         [ $found -ne $left ] &&
5733                 error "can't find subdirs: found only $found, expected $left"
5734
5735         unlinkmany -d $dir/d $delete $left ||
5736                 error "unlink of second $left subdirs failed"
5737         # regardless of whether the backing filesystem tracks nlink accurately
5738         # or not, the nlink count shouldn't be more than "." and ".." here
5739         local after=$(stat -c %h $dir)
5740         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5741                 echo "nlink after: $after"
5742
5743         cleanup_print_lfs_df
5744 }
5745 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5746
5747 test_51d() {
5748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5749         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5750         local qos_old
5751
5752         test_mkdir $DIR/$tdir
5753         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5754
5755         qos_old=$(do_facet mds1 \
5756                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5757         do_nodes $(comma_list $(mdts_nodes)) \
5758                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5759         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5760                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5761
5762         createmany -o $DIR/$tdir/t- 1000
5763         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5764         for ((n = 0; n < $OSTCOUNT; n++)); do
5765                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5766                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5767                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5768                             '($1 == '$n') { objs += 1 } \
5769                             END { printf("%0.0f", objs) }')
5770                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5771         done
5772         unlinkmany $DIR/$tdir/t- 1000
5773
5774         nlast=0
5775         for ((n = 0; n < $OSTCOUNT; n++)); do
5776                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5777                         { $LFS df && $LFS df -i &&
5778                         error "OST $n has fewer objects vs. OST $nlast" \
5779                               " (${objs[$n]} < ${objs[$nlast]}"; }
5780                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5781                         { $LFS df && $LFS df -i &&
5782                         error "OST $n has fewer objects vs. OST $nlast" \
5783                               " (${objs[$n]} < ${objs[$nlast]}"; }
5784
5785                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5786                         { $LFS df && $LFS df -i &&
5787                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5788                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5789                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5790                         { $LFS df && $LFS df -i &&
5791                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5792                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5793                 nlast=$n
5794         done
5795 }
5796 run_test 51d "check object distribution"
5797
5798 test_51e() {
5799         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5800                 skip_env "ldiskfs only test"
5801         fi
5802
5803         test_mkdir -c1 $DIR/$tdir
5804         test_mkdir -c1 $DIR/$tdir/d0
5805
5806         touch $DIR/$tdir/d0/foo
5807         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5808                 error "file exceed 65000 nlink limit!"
5809         unlinkmany $DIR/$tdir/d0/f- 65001
5810         return 0
5811 }
5812 run_test 51e "check file nlink limit"
5813
5814 test_51f() {
5815         test_mkdir $DIR/$tdir
5816
5817         local max=100000
5818         local ulimit_old=$(ulimit -n)
5819         local spare=20 # number of spare fd's for scripts/libraries, etc.
5820         local mdt=$($LFS getstripe -m $DIR/$tdir)
5821         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5822
5823         echo "MDT$mdt numfree=$numfree, max=$max"
5824         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5825         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5826                 while ! ulimit -n $((numfree + spare)); do
5827                         numfree=$((numfree * 3 / 4))
5828                 done
5829                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5830         else
5831                 echo "left ulimit at $ulimit_old"
5832         fi
5833
5834         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5835                 unlinkmany $DIR/$tdir/f $numfree
5836                 error "create+open $numfree files in $DIR/$tdir failed"
5837         }
5838         ulimit -n $ulimit_old
5839
5840         # if createmany exits at 120s there will be fewer than $numfree files
5841         unlinkmany $DIR/$tdir/f $numfree || true
5842 }
5843 run_test 51f "check many open files limit"
5844
5845 test_52a() {
5846         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5847         test_mkdir $DIR/$tdir
5848         touch $DIR/$tdir/foo
5849         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5850         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5851         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5852         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5853         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5854                                         error "link worked"
5855         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5856         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5857         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5858                                                      error "lsattr"
5859         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5860         cp -r $DIR/$tdir $TMP/
5861         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5862 }
5863 run_test 52a "append-only flag test (should return errors)"
5864
5865 test_52b() {
5866         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5867         test_mkdir $DIR/$tdir
5868         touch $DIR/$tdir/foo
5869         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5870         cat test > $DIR/$tdir/foo && error "cat test worked"
5871         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5872         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5873         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5874                                         error "link worked"
5875         echo foo >> $DIR/$tdir/foo && error "echo worked"
5876         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5877         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5878         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5879         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5880                                                         error "lsattr"
5881         chattr -i $DIR/$tdir/foo || error "chattr failed"
5882
5883         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5884 }
5885 run_test 52b "immutable flag test (should return errors) ======="
5886
5887 test_53() {
5888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5889         remote_mds_nodsh && skip "remote MDS with nodsh"
5890         remote_ost_nodsh && skip "remote OST with nodsh"
5891
5892         local param
5893         local param_seq
5894         local ostname
5895         local mds_last
5896         local mds_last_seq
5897         local ost_last
5898         local ost_last_seq
5899         local ost_last_id
5900         local ostnum
5901         local node
5902         local found=false
5903         local support_last_seq=true
5904
5905         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5906                 support_last_seq=false
5907
5908         # only test MDT0000
5909         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5910         local value
5911         for value in $(do_facet $SINGLEMDS \
5912                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5913                 param=$(echo ${value[0]} | cut -d "=" -f1)
5914                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5915
5916                 if $support_last_seq; then
5917                         param_seq=$(echo $param |
5918                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5919                         mds_last_seq=$(do_facet $SINGLEMDS \
5920                                        $LCTL get_param -n $param_seq)
5921                 fi
5922                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5923
5924                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5925                 node=$(facet_active_host ost$((ostnum+1)))
5926                 param="obdfilter.$ostname.last_id"
5927                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5928                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5929                         ost_last_id=$ost_last
5930
5931                         if $support_last_seq; then
5932                                 ost_last_id=$(echo $ost_last |
5933                                               awk -F':' '{print $2}' |
5934                                               sed -e "s/^0x//g")
5935                                 ost_last_seq=$(echo $ost_last |
5936                                                awk -F':' '{print $1}')
5937                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5938                         fi
5939
5940                         if [[ $ost_last_id != $mds_last ]]; then
5941                                 error "$ost_last_id != $mds_last"
5942                         else
5943                                 found=true
5944                                 break
5945                         fi
5946                 done
5947         done
5948         $found || error "can not match last_seq/last_id for $mdtosc"
5949         return 0
5950 }
5951 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5952
5953 test_54a() {
5954         perl -MSocket -e ';' || skip "no Socket perl module installed"
5955
5956         $SOCKETSERVER $DIR/socket ||
5957                 error "$SOCKETSERVER $DIR/socket failed: $?"
5958         $SOCKETCLIENT $DIR/socket ||
5959                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5960         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5961 }
5962 run_test 54a "unix domain socket test =========================="
5963
5964 test_54b() {
5965         f="$DIR/f54b"
5966         mknod $f c 1 3
5967         chmod 0666 $f
5968         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5969 }
5970 run_test 54b "char device works in lustre ======================"
5971
5972 find_loop_dev() {
5973         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5974         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5975         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5976
5977         for i in $(seq 3 7); do
5978                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5979                 LOOPDEV=$LOOPBASE$i
5980                 LOOPNUM=$i
5981                 break
5982         done
5983 }
5984
5985 cleanup_54c() {
5986         local rc=0
5987         loopdev="$DIR/loop54c"
5988
5989         trap 0
5990         $UMOUNT $DIR/$tdir || rc=$?
5991         losetup -d $loopdev || true
5992         losetup -d $LOOPDEV || true
5993         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5994         return $rc
5995 }
5996
5997 test_54c() {
5998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5999
6000         loopdev="$DIR/loop54c"
6001
6002         find_loop_dev
6003         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6004         trap cleanup_54c EXIT
6005         mknod $loopdev b 7 $LOOPNUM
6006         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6007         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6008         losetup $loopdev $DIR/$tfile ||
6009                 error "can't set up $loopdev for $DIR/$tfile"
6010         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6011         test_mkdir $DIR/$tdir
6012         mount -t ext2 $loopdev $DIR/$tdir ||
6013                 error "error mounting $loopdev on $DIR/$tdir"
6014         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6015                 error "dd write"
6016         df $DIR/$tdir
6017         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6018                 error "dd read"
6019         cleanup_54c
6020 }
6021 run_test 54c "block device works in lustre ====================="
6022
6023 test_54d() {
6024         f="$DIR/f54d"
6025         string="aaaaaa"
6026         mknod $f p
6027         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
6028 }
6029 run_test 54d "fifo device works in lustre ======================"
6030
6031 test_54e() {
6032         f="$DIR/f54e"
6033         string="aaaaaa"
6034         cp -aL /dev/console $f
6035         echo $string > $f || error "echo $string to $f failed"
6036 }
6037 run_test 54e "console/tty device works in lustre ======================"
6038
6039 test_56a() {
6040         local numfiles=3
6041         local numdirs=2
6042         local dir=$DIR/$tdir
6043
6044         rm -rf $dir
6045         test_mkdir -p $dir/dir
6046         for i in $(seq $numfiles); do
6047                 touch $dir/file$i
6048                 touch $dir/dir/file$i
6049         done
6050
6051         local numcomp=$($LFS getstripe --component-count $dir)
6052
6053         [[ $numcomp == 0 ]] && numcomp=1
6054
6055         # test lfs getstripe with --recursive
6056         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6057
6058         [[ $filenum -eq $((numfiles * 2)) ]] ||
6059                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6060         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6061         [[ $filenum -eq $numfiles ]] ||
6062                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6063         echo "$LFS getstripe showed obdidx or l_ost_idx"
6064
6065         # test lfs getstripe with file instead of dir
6066         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6067         [[ $filenum -eq 1 ]] ||
6068                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6069         echo "$LFS getstripe file1 passed"
6070
6071         #test lfs getstripe with --verbose
6072         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6073         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6074                 error "$LFS getstripe --verbose $dir: "\
6075                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6076         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6077                 error "$LFS getstripe $dir: showed lmm_magic"
6078
6079         #test lfs getstripe with -v prints lmm_fid
6080         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6081         local countfids=$((numdirs + numfiles * numcomp))
6082         [[ $filenum -eq $countfids ]] ||
6083                 error "$LFS getstripe -v $dir: "\
6084                       "got $filenum want $countfids lmm_fid"
6085         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6086                 error "$LFS getstripe $dir: showed lmm_fid by default"
6087         echo "$LFS getstripe --verbose passed"
6088
6089         #check for FID information
6090         local fid1=$($LFS getstripe --fid $dir/file1)
6091         local fid2=$($LFS getstripe --verbose $dir/file1 |
6092                      awk '/lmm_fid: / { print $2; exit; }')
6093         local fid3=$($LFS path2fid $dir/file1)
6094
6095         [ "$fid1" != "$fid2" ] &&
6096                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6097         [ "$fid1" != "$fid3" ] &&
6098                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6099         echo "$LFS getstripe --fid passed"
6100
6101         #test lfs getstripe with --obd
6102         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6103                 error "$LFS getstripe --obd wrong_uuid: should return error"
6104
6105         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6106
6107         local ostidx=1
6108         local obduuid=$(ostuuid_from_index $ostidx)
6109         local found=$($LFS getstripe -r --obd $obduuid $dir |
6110                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6111
6112         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6113         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6114                 ((filenum--))
6115         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6116                 ((filenum--))
6117
6118         [[ $found -eq $filenum ]] ||
6119                 error "$LFS getstripe --obd: found $found expect $filenum"
6120         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6121                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6122                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6123                 error "$LFS getstripe --obd: should not show file on other obd"
6124         echo "$LFS getstripe --obd passed"
6125 }
6126 run_test 56a "check $LFS getstripe"
6127
6128 test_56b() {
6129         local dir=$DIR/$tdir
6130         local numdirs=3
6131
6132         test_mkdir $dir
6133         for i in $(seq $numdirs); do
6134                 test_mkdir $dir/dir$i
6135         done
6136
6137         # test lfs getdirstripe default mode is non-recursion, which is
6138         # different from lfs getstripe
6139         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6140
6141         [[ $dircnt -eq 1 ]] ||
6142                 error "$LFS getdirstripe: found $dircnt, not 1"
6143         dircnt=$($LFS getdirstripe --recursive $dir |
6144                 grep -c lmv_stripe_count)
6145         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6146                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6147 }
6148 run_test 56b "check $LFS getdirstripe"
6149
6150 test_56c() {
6151         remote_ost_nodsh && skip "remote OST with nodsh"
6152
6153         local ost_idx=0
6154         local ost_name=$(ostname_from_index $ost_idx)
6155         local old_status=$(ost_dev_status $ost_idx)
6156         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6157
6158         [[ -z "$old_status" ]] ||
6159                 skip_env "OST $ost_name is in $old_status status"
6160
6161         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6162         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6163                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6164         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6165                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6166                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6167         fi
6168
6169         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6170                 error "$LFS df -v showing inactive devices"
6171         sleep_maxage
6172
6173         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6174
6175         [[ "$new_status" =~ "D" ]] ||
6176                 error "$ost_name status is '$new_status', missing 'D'"
6177         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6178                 [[ "$new_status" =~ "N" ]] ||
6179                         error "$ost_name status is '$new_status', missing 'N'"
6180         fi
6181         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6182                 [[ "$new_status" =~ "f" ]] ||
6183                         error "$ost_name status is '$new_status', missing 'f'"
6184         fi
6185
6186         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6187         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6188                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6189         [[ -z "$p" ]] && restore_lustre_params < $p || true
6190         sleep_maxage
6191
6192         new_status=$(ost_dev_status $ost_idx)
6193         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6194                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6195         # can't check 'f' as devices may actually be on flash
6196 }
6197 run_test 56c "check 'lfs df' showing device status"
6198
6199 test_56d() {
6200         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6201         local osts=$($LFS df -v $MOUNT | grep -c OST)
6202
6203         $LFS df $MOUNT
6204
6205         (( mdts == MDSCOUNT )) ||
6206                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6207         (( osts == OSTCOUNT )) ||
6208                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6209 }
6210 run_test 56d "'lfs df -v' prints only configured devices"
6211
6212 test_56e() {
6213         err_enoent=2 # No such file or directory
6214         err_eopnotsupp=95 # Operation not supported
6215
6216         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6217         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6218
6219         # Check for handling of path not exists
6220         output=$($LFS df $enoent_mnt 2>&1)
6221         ret=$?
6222
6223         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6224         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6225                 error "expect failure $err_enoent, not $ret"
6226
6227         # Check for handling of non-Lustre FS
6228         output=$($LFS df $notsup_mnt)
6229         ret=$?
6230
6231         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6232         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6233                 error "expect success $err_eopnotsupp, not $ret"
6234
6235         # Check for multiple LustreFS argument
6236         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6237         ret=$?
6238
6239         [[ $output -eq 3 && $ret -eq 0 ]] ||
6240                 error "expect success 3, not $output, rc = $ret"
6241
6242         # Check for correct non-Lustre FS handling among multiple
6243         # LustreFS argument
6244         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6245                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6246         ret=$?
6247
6248         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6249                 error "expect success 2, not $output, rc = $ret"
6250 }
6251 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6252
6253 NUMFILES=3
6254 NUMDIRS=3
6255 setup_56() {
6256         local local_tdir="$1"
6257         local local_numfiles="$2"
6258         local local_numdirs="$3"
6259         local dir_params="$4"
6260         local dir_stripe_params="$5"
6261
6262         if [ ! -d "$local_tdir" ] ; then
6263                 test_mkdir -p $dir_stripe_params $local_tdir
6264                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6265                 for i in $(seq $local_numfiles) ; do
6266                         touch $local_tdir/file$i
6267                 done
6268                 for i in $(seq $local_numdirs) ; do
6269                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6270                         for j in $(seq $local_numfiles) ; do
6271                                 touch $local_tdir/dir$i/file$j
6272                         done
6273                 done
6274         fi
6275 }
6276
6277 setup_56_special() {
6278         local local_tdir=$1
6279         local local_numfiles=$2
6280         local local_numdirs=$3
6281
6282         setup_56 $local_tdir $local_numfiles $local_numdirs
6283
6284         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6285                 for i in $(seq $local_numfiles) ; do
6286                         mknod $local_tdir/loop${i}b b 7 $i
6287                         mknod $local_tdir/null${i}c c 1 3
6288                         ln -s $local_tdir/file1 $local_tdir/link${i}
6289                 done
6290                 for i in $(seq $local_numdirs) ; do
6291                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6292                         mknod $local_tdir/dir$i/null${i}c c 1 3
6293                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6294                 done
6295         fi
6296 }
6297
6298 test_56g() {
6299         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6300         local expected=$(($NUMDIRS + 2))
6301
6302         setup_56 $dir $NUMFILES $NUMDIRS
6303
6304         # test lfs find with -name
6305         for i in $(seq $NUMFILES) ; do
6306                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6307
6308                 [ $nums -eq $expected ] ||
6309                         error "lfs find -name '*$i' $dir wrong: "\
6310                               "found $nums, expected $expected"
6311         done
6312 }
6313 run_test 56g "check lfs find -name"
6314
6315 test_56h() {
6316         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6317         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6318
6319         setup_56 $dir $NUMFILES $NUMDIRS
6320
6321         # test lfs find with ! -name
6322         for i in $(seq $NUMFILES) ; do
6323                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6324
6325                 [ $nums -eq $expected ] ||
6326                         error "lfs find ! -name '*$i' $dir wrong: "\
6327                               "found $nums, expected $expected"
6328         done
6329 }
6330 run_test 56h "check lfs find ! -name"
6331
6332 test_56i() {
6333         local dir=$DIR/$tdir
6334
6335         test_mkdir $dir
6336
6337         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6338         local out=$($cmd)
6339
6340         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6341 }
6342 run_test 56i "check 'lfs find -ost UUID' skips directories"
6343
6344 test_56j() {
6345         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6346
6347         setup_56_special $dir $NUMFILES $NUMDIRS
6348
6349         local expected=$((NUMDIRS + 1))
6350         local cmd="$LFS find -type d $dir"
6351         local nums=$($cmd | wc -l)
6352
6353         [ $nums -eq $expected ] ||
6354                 error "'$cmd' wrong: found $nums, expected $expected"
6355 }
6356 run_test 56j "check lfs find -type d"
6357
6358 test_56k() {
6359         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6360
6361         setup_56_special $dir $NUMFILES $NUMDIRS
6362
6363         local expected=$(((NUMDIRS + 1) * NUMFILES))
6364         local cmd="$LFS find -type f $dir"
6365         local nums=$($cmd | wc -l)
6366
6367         [ $nums -eq $expected ] ||
6368                 error "'$cmd' wrong: found $nums, expected $expected"
6369 }
6370 run_test 56k "check lfs find -type f"
6371
6372 test_56l() {
6373         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6374
6375         setup_56_special $dir $NUMFILES $NUMDIRS
6376
6377         local expected=$((NUMDIRS + NUMFILES))
6378         local cmd="$LFS find -type b $dir"
6379         local nums=$($cmd | wc -l)
6380
6381         [ $nums -eq $expected ] ||
6382                 error "'$cmd' wrong: found $nums, expected $expected"
6383 }
6384 run_test 56l "check lfs find -type b"
6385
6386 test_56m() {
6387         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6388
6389         setup_56_special $dir $NUMFILES $NUMDIRS
6390
6391         local expected=$((NUMDIRS + NUMFILES))
6392         local cmd="$LFS find -type c $dir"
6393         local nums=$($cmd | wc -l)
6394         [ $nums -eq $expected ] ||
6395                 error "'$cmd' wrong: found $nums, expected $expected"
6396 }
6397 run_test 56m "check lfs find -type c"
6398
6399 test_56n() {
6400         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6401         setup_56_special $dir $NUMFILES $NUMDIRS
6402
6403         local expected=$((NUMDIRS + NUMFILES))
6404         local cmd="$LFS find -type l $dir"
6405         local nums=$($cmd | wc -l)
6406
6407         [ $nums -eq $expected ] ||
6408                 error "'$cmd' wrong: found $nums, expected $expected"
6409 }
6410 run_test 56n "check lfs find -type l"
6411
6412 test_56o() {
6413         local dir=$DIR/$tdir
6414
6415         setup_56 $dir $NUMFILES $NUMDIRS
6416         utime $dir/file1 > /dev/null || error "utime (1)"
6417         utime $dir/file2 > /dev/null || error "utime (2)"
6418         utime $dir/dir1 > /dev/null || error "utime (3)"
6419         utime $dir/dir2 > /dev/null || error "utime (4)"
6420         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6421         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6422
6423         local expected=4
6424         local nums=$($LFS find -mtime +0 $dir | wc -l)
6425
6426         [ $nums -eq $expected ] ||
6427                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6428
6429         expected=12
6430         cmd="$LFS find -mtime 0 $dir"
6431         nums=$($cmd | wc -l)
6432         [ $nums -eq $expected ] ||
6433                 error "'$cmd' wrong: found $nums, expected $expected"
6434 }
6435 run_test 56o "check lfs find -mtime for old files"
6436
6437 test_56ob() {
6438         local dir=$DIR/$tdir
6439         local expected=1
6440         local count=0
6441
6442         # just to make sure there is something that won't be found
6443         test_mkdir $dir
6444         touch $dir/$tfile.now
6445
6446         for age in year week day hour min; do
6447                 count=$((count + 1))
6448
6449                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6450                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6451                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6452
6453                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6454                 local nums=$($cmd | wc -l)
6455                 [ $nums -eq $expected ] ||
6456                         error "'$cmd' wrong: found $nums, expected $expected"
6457
6458                 cmd="$LFS find $dir -atime $count${age:0:1}"
6459                 nums=$($cmd | wc -l)
6460                 [ $nums -eq $expected ] ||
6461                         error "'$cmd' wrong: found $nums, expected $expected"
6462         done
6463
6464         sleep 2
6465         cmd="$LFS find $dir -ctime +1s -type f"
6466         nums=$($cmd | wc -l)
6467         (( $nums == $count * 2 + 1)) ||
6468                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6469 }
6470 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6471
6472 test_newerXY_base() {
6473         local x=$1
6474         local y=$2
6475         local dir=$DIR/$tdir
6476         local ref
6477         local negref
6478
6479         if [ $y == "t" ]; then
6480                 if [ $x == "b" ]; then
6481                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6482                 else
6483                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6484                 fi
6485         else
6486                 ref=$DIR/$tfile.newer.$x$y
6487                 touch $ref || error "touch $ref failed"
6488         fi
6489
6490         echo "before = $ref"
6491         sleep 2
6492         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6493         sleep 2
6494         if [ $y == "t" ]; then
6495                 if [ $x == "b" ]; then
6496                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6497                 else
6498                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6499                 fi
6500         else
6501                 negref=$DIR/$tfile.negnewer.$x$y
6502                 touch $negref || error "touch $negref failed"
6503         fi
6504
6505         echo "after = $negref"
6506         local cmd="$LFS find $dir -newer$x$y $ref"
6507         local nums=$(eval $cmd | wc -l)
6508         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6509
6510         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6511                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6512
6513         cmd="$LFS find $dir ! -newer$x$y $negref"
6514         nums=$(eval $cmd | wc -l)
6515         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6516                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6517
6518         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6519         nums=$(eval $cmd | wc -l)
6520         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6521                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6522
6523         rm -rf $DIR/*
6524 }
6525
6526 test_56oc() {
6527         test_newerXY_base "a" "a"
6528         test_newerXY_base "a" "m"
6529         test_newerXY_base "a" "c"
6530         test_newerXY_base "m" "a"
6531         test_newerXY_base "m" "m"
6532         test_newerXY_base "m" "c"
6533         test_newerXY_base "c" "a"
6534         test_newerXY_base "c" "m"
6535         test_newerXY_base "c" "c"
6536
6537         [[ -n "$sles_version" ]] &&
6538                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6539
6540         test_newerXY_base "a" "t"
6541         test_newerXY_base "m" "t"
6542         test_newerXY_base "c" "t"
6543
6544         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6545            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6546                 ! btime_supported && echo "btime unsupported" && return 0
6547
6548         test_newerXY_base "b" "b"
6549         test_newerXY_base "b" "t"
6550 }
6551 run_test 56oc "check lfs find -newerXY work"
6552
6553 btime_supported() {
6554         local dir=$DIR/$tdir
6555         local rc
6556
6557         mkdir -p $dir
6558         touch $dir/$tfile
6559         $LFS find $dir -btime -1d -type f
6560         rc=$?
6561         rm -rf $dir
6562         return $rc
6563 }
6564
6565 test_56od() {
6566         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6567                 ! btime_supported && skip "btime unsupported on MDS"
6568
6569         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6570                 ! btime_supported && skip "btime unsupported on clients"
6571
6572         local dir=$DIR/$tdir
6573         local ref=$DIR/$tfile.ref
6574         local negref=$DIR/$tfile.negref
6575
6576         mkdir $dir || error "mkdir $dir failed"
6577         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6578         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6579         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6580         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6581         touch $ref || error "touch $ref failed"
6582         # sleep 3 seconds at least
6583         sleep 3
6584
6585         local before=$(do_facet mds1 date +%s)
6586         local skew=$(($(date +%s) - before + 1))
6587
6588         if (( skew < 0 && skew > -5 )); then
6589                 sleep $((0 - skew + 1))
6590                 skew=0
6591         fi
6592
6593         # Set the dir stripe params to limit files all on MDT0,
6594         # otherwise we need to calc the max clock skew between
6595         # the client and MDTs.
6596         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6597         sleep 2
6598         touch $negref || error "touch $negref failed"
6599
6600         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6601         local nums=$($cmd | wc -l)
6602         local expected=$(((NUMFILES + 1) * NUMDIRS))
6603
6604         [ $nums -eq $expected ] ||
6605                 error "'$cmd' wrong: found $nums, expected $expected"
6606
6607         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6608         nums=$($cmd | wc -l)
6609         expected=$((NUMFILES + 1))
6610         [ $nums -eq $expected ] ||
6611                 error "'$cmd' wrong: found $nums, expected $expected"
6612
6613         [ $skew -lt 0 ] && return
6614
6615         local after=$(do_facet mds1 date +%s)
6616         local age=$((after - before + 1 + skew))
6617
6618         cmd="$LFS find $dir -btime -${age}s -type f"
6619         nums=$($cmd | wc -l)
6620         expected=$(((NUMFILES + 1) * NUMDIRS))
6621
6622         echo "Clock skew between client and server: $skew, age:$age"
6623         [ $nums -eq $expected ] ||
6624                 error "'$cmd' wrong: found $nums, expected $expected"
6625
6626         expected=$(($NUMDIRS + 1))
6627         cmd="$LFS find $dir -btime -${age}s -type d"
6628         nums=$($cmd | wc -l)
6629         [ $nums -eq $expected ] ||
6630                 error "'$cmd' wrong: found $nums, expected $expected"
6631         rm -f $ref $negref || error "Failed to remove $ref $negref"
6632 }
6633 run_test 56od "check lfs find -btime with units"
6634
6635 test_56p() {
6636         [ $RUNAS_ID -eq $UID ] &&
6637                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6638
6639         local dir=$DIR/$tdir
6640
6641         setup_56 $dir $NUMFILES $NUMDIRS
6642         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6643
6644         local expected=$NUMFILES
6645         local cmd="$LFS find -uid $RUNAS_ID $dir"
6646         local nums=$($cmd | wc -l)
6647
6648         [ $nums -eq $expected ] ||
6649                 error "'$cmd' wrong: found $nums, expected $expected"
6650
6651         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6652         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6653         nums=$($cmd | wc -l)
6654         [ $nums -eq $expected ] ||
6655                 error "'$cmd' wrong: found $nums, expected $expected"
6656 }
6657 run_test 56p "check lfs find -uid and ! -uid"
6658
6659 test_56q() {
6660         [ $RUNAS_ID -eq $UID ] &&
6661                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6662
6663         local dir=$DIR/$tdir
6664
6665         setup_56 $dir $NUMFILES $NUMDIRS
6666         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6667
6668         local expected=$NUMFILES
6669         local cmd="$LFS find -gid $RUNAS_GID $dir"
6670         local nums=$($cmd | wc -l)
6671
6672         [ $nums -eq $expected ] ||
6673                 error "'$cmd' wrong: found $nums, expected $expected"
6674
6675         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6676         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6677         nums=$($cmd | wc -l)
6678         [ $nums -eq $expected ] ||
6679                 error "'$cmd' wrong: found $nums, expected $expected"
6680 }
6681 run_test 56q "check lfs find -gid and ! -gid"
6682
6683 test_56r() {
6684         local dir=$DIR/$tdir
6685
6686         setup_56 $dir $NUMFILES $NUMDIRS
6687
6688         local expected=12
6689         local cmd="$LFS find -size 0 -type f -lazy $dir"
6690         local nums=$($cmd | wc -l)
6691
6692         [ $nums -eq $expected ] ||
6693                 error "'$cmd' wrong: found $nums, expected $expected"
6694         cmd="$LFS find -size 0 -type f $dir"
6695         nums=$($cmd | wc -l)
6696         [ $nums -eq $expected ] ||
6697                 error "'$cmd' wrong: found $nums, expected $expected"
6698
6699         expected=0
6700         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6701         nums=$($cmd | wc -l)
6702         [ $nums -eq $expected ] ||
6703                 error "'$cmd' wrong: found $nums, expected $expected"
6704         cmd="$LFS find ! -size 0 -type f $dir"
6705         nums=$($cmd | wc -l)
6706         [ $nums -eq $expected ] ||
6707                 error "'$cmd' wrong: found $nums, expected $expected"
6708
6709         echo "test" > $dir/$tfile
6710         echo "test2" > $dir/$tfile.2 && sync
6711         expected=1
6712         cmd="$LFS find -size 5 -type f -lazy $dir"
6713         nums=$($cmd | wc -l)
6714         [ $nums -eq $expected ] ||
6715                 error "'$cmd' wrong: found $nums, expected $expected"
6716         cmd="$LFS find -size 5 -type f $dir"
6717         nums=$($cmd | wc -l)
6718         [ $nums -eq $expected ] ||
6719                 error "'$cmd' wrong: found $nums, expected $expected"
6720
6721         expected=1
6722         cmd="$LFS find -size +5 -type f -lazy $dir"
6723         nums=$($cmd | wc -l)
6724         [ $nums -eq $expected ] ||
6725                 error "'$cmd' wrong: found $nums, expected $expected"
6726         cmd="$LFS find -size +5 -type f $dir"
6727         nums=$($cmd | wc -l)
6728         [ $nums -eq $expected ] ||
6729                 error "'$cmd' wrong: found $nums, expected $expected"
6730
6731         expected=2
6732         cmd="$LFS find -size +0 -type f -lazy $dir"
6733         nums=$($cmd | wc -l)
6734         [ $nums -eq $expected ] ||
6735                 error "'$cmd' wrong: found $nums, expected $expected"
6736         cmd="$LFS find -size +0 -type f $dir"
6737         nums=$($cmd | wc -l)
6738         [ $nums -eq $expected ] ||
6739                 error "'$cmd' wrong: found $nums, expected $expected"
6740
6741         expected=2
6742         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6743         nums=$($cmd | wc -l)
6744         [ $nums -eq $expected ] ||
6745                 error "'$cmd' wrong: found $nums, expected $expected"
6746         cmd="$LFS find ! -size -5 -type f $dir"
6747         nums=$($cmd | wc -l)
6748         [ $nums -eq $expected ] ||
6749                 error "'$cmd' wrong: found $nums, expected $expected"
6750
6751         expected=12
6752         cmd="$LFS find -size -5 -type f -lazy $dir"
6753         nums=$($cmd | wc -l)
6754         [ $nums -eq $expected ] ||
6755                 error "'$cmd' wrong: found $nums, expected $expected"
6756         cmd="$LFS find -size -5 -type f $dir"
6757         nums=$($cmd | wc -l)
6758         [ $nums -eq $expected ] ||
6759                 error "'$cmd' wrong: found $nums, expected $expected"
6760 }
6761 run_test 56r "check lfs find -size works"
6762
6763 test_56ra_sub() {
6764         local expected=$1
6765         local glimpses=$2
6766         local cmd="$3"
6767
6768         cancel_lru_locks $OSC
6769
6770         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6771         local nums=$($cmd | wc -l)
6772
6773         [ $nums -eq $expected ] ||
6774                 error "'$cmd' wrong: found $nums, expected $expected"
6775
6776         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6777
6778         if (( rpcs_before + glimpses != rpcs_after )); then
6779                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6780                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6781
6782                 if [[ $glimpses == 0 ]]; then
6783                         error "'$cmd' should not send glimpse RPCs to OST"
6784                 else
6785                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6786                 fi
6787         fi
6788 }
6789
6790 test_56ra() {
6791         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6792                 skip "MDS < 2.12.58 doesn't return LSOM data"
6793         local dir=$DIR/$tdir
6794         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6795
6796         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6797
6798         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6799         $LCTL set_param -n llite.*.statahead_agl=0
6800         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6801
6802         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6803         # open and close all files to ensure LSOM is updated
6804         cancel_lru_locks $OSC
6805         find $dir -type f | xargs cat > /dev/null
6806
6807         #   expect_found  glimpse_rpcs  command_to_run
6808         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6809         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6810         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6811         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6812
6813         echo "test" > $dir/$tfile
6814         echo "test2" > $dir/$tfile.2 && sync
6815         cancel_lru_locks $OSC
6816         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6817
6818         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6819         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6820         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6821         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6822
6823         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6824         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6825         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6826         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6827         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6828         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6829 }
6830 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6831
6832 test_56rb() {
6833         local dir=$DIR/$tdir
6834         local tmp=$TMP/$tfile.log
6835         local mdt_idx;
6836
6837         test_mkdir -p $dir || error "failed to mkdir $dir"
6838         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6839                 error "failed to setstripe $dir/$tfile"
6840         mdt_idx=$($LFS getdirstripe -i $dir)
6841         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6842
6843         stack_trap "rm -f $tmp" EXIT
6844         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6845         ! grep -q obd_uuid $tmp ||
6846                 error "failed to find --size +100K --ost 0 $dir"
6847         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6848         ! grep -q obd_uuid $tmp ||
6849                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6850 }
6851 run_test 56rb "check lfs find --size --ost/--mdt works"
6852
6853 test_56rc() {
6854         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6855         local dir=$DIR/$tdir
6856         local found
6857
6858         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6859         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6860         (( $MDSCOUNT > 2 )) &&
6861                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6862         mkdir $dir/$tdir-{1..10}
6863         touch $dir/$tfile-{1..10}
6864
6865         found=$($LFS find $dir --mdt-count 2 | wc -l)
6866         expect=11
6867         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6868
6869         found=$($LFS find $dir -T +1 | wc -l)
6870         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6871         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6872
6873         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6874         expect=11
6875         (( $found == $expect )) || error "found $found all_char, expect $expect"
6876
6877         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6878         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6879         (( $found == $expect )) || error "found $found all_char, expect $expect"
6880 }
6881 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6882
6883 test_56s() { # LU-611 #LU-9369
6884         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6885
6886         local dir=$DIR/$tdir
6887         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6888
6889         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6890         for i in $(seq $NUMDIRS); do
6891                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6892         done
6893
6894         local expected=$NUMDIRS
6895         local cmd="$LFS find -c $OSTCOUNT $dir"
6896         local nums=$($cmd | wc -l)
6897
6898         [ $nums -eq $expected ] || {
6899                 $LFS getstripe -R $dir
6900                 error "'$cmd' wrong: found $nums, expected $expected"
6901         }
6902
6903         expected=$((NUMDIRS + onestripe))
6904         cmd="$LFS find -stripe-count +0 -type f $dir"
6905         nums=$($cmd | wc -l)
6906         [ $nums -eq $expected ] || {
6907                 $LFS getstripe -R $dir
6908                 error "'$cmd' wrong: found $nums, expected $expected"
6909         }
6910
6911         expected=$onestripe
6912         cmd="$LFS find -stripe-count 1 -type f $dir"
6913         nums=$($cmd | wc -l)
6914         [ $nums -eq $expected ] || {
6915                 $LFS getstripe -R $dir
6916                 error "'$cmd' wrong: found $nums, expected $expected"
6917         }
6918
6919         cmd="$LFS find -stripe-count -2 -type f $dir"
6920         nums=$($cmd | wc -l)
6921         [ $nums -eq $expected ] || {
6922                 $LFS getstripe -R $dir
6923                 error "'$cmd' wrong: found $nums, expected $expected"
6924         }
6925
6926         expected=0
6927         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6928         nums=$($cmd | wc -l)
6929         [ $nums -eq $expected ] || {
6930                 $LFS getstripe -R $dir
6931                 error "'$cmd' wrong: found $nums, expected $expected"
6932         }
6933 }
6934 run_test 56s "check lfs find -stripe-count works"
6935
6936 test_56t() { # LU-611 #LU-9369
6937         local dir=$DIR/$tdir
6938
6939         setup_56 $dir 0 $NUMDIRS
6940         for i in $(seq $NUMDIRS); do
6941                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6942         done
6943
6944         local expected=$NUMDIRS
6945         local cmd="$LFS find -S 8M $dir"
6946         local nums=$($cmd | wc -l)
6947
6948         [ $nums -eq $expected ] || {
6949                 $LFS getstripe -R $dir
6950                 error "'$cmd' wrong: found $nums, expected $expected"
6951         }
6952         rm -rf $dir
6953
6954         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6955
6956         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6957
6958         expected=$(((NUMDIRS + 1) * NUMFILES))
6959         cmd="$LFS find -stripe-size 512k -type f $dir"
6960         nums=$($cmd | wc -l)
6961         [ $nums -eq $expected ] ||
6962                 error "'$cmd' wrong: found $nums, expected $expected"
6963
6964         cmd="$LFS find -stripe-size +320k -type f $dir"
6965         nums=$($cmd | wc -l)
6966         [ $nums -eq $expected ] ||
6967                 error "'$cmd' wrong: found $nums, expected $expected"
6968
6969         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6970         cmd="$LFS find -stripe-size +200k -type f $dir"
6971         nums=$($cmd | wc -l)
6972         [ $nums -eq $expected ] ||
6973                 error "'$cmd' wrong: found $nums, expected $expected"
6974
6975         cmd="$LFS find -stripe-size -640k -type f $dir"
6976         nums=$($cmd | wc -l)
6977         [ $nums -eq $expected ] ||
6978                 error "'$cmd' wrong: found $nums, expected $expected"
6979
6980         expected=4
6981         cmd="$LFS find -stripe-size 256k -type f $dir"
6982         nums=$($cmd | wc -l)
6983         [ $nums -eq $expected ] ||
6984                 error "'$cmd' wrong: found $nums, expected $expected"
6985
6986         cmd="$LFS find -stripe-size -320k -type f $dir"
6987         nums=$($cmd | wc -l)
6988         [ $nums -eq $expected ] ||
6989                 error "'$cmd' wrong: found $nums, expected $expected"
6990
6991         expected=0
6992         cmd="$LFS find -stripe-size 1024k -type f $dir"
6993         nums=$($cmd | wc -l)
6994         [ $nums -eq $expected ] ||
6995                 error "'$cmd' wrong: found $nums, expected $expected"
6996 }
6997 run_test 56t "check lfs find -stripe-size works"
6998
6999 test_56u() { # LU-611
7000         local dir=$DIR/$tdir
7001
7002         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7003
7004         if [[ $OSTCOUNT -gt 1 ]]; then
7005                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7006                 onestripe=4
7007         else
7008                 onestripe=0
7009         fi
7010
7011         local expected=$(((NUMDIRS + 1) * NUMFILES))
7012         local cmd="$LFS find -stripe-index 0 -type f $dir"
7013         local nums=$($cmd | wc -l)
7014
7015         [ $nums -eq $expected ] ||
7016                 error "'$cmd' wrong: found $nums, expected $expected"
7017
7018         expected=$onestripe
7019         cmd="$LFS find -stripe-index 1 -type f $dir"
7020         nums=$($cmd | wc -l)
7021         [ $nums -eq $expected ] ||
7022                 error "'$cmd' wrong: found $nums, expected $expected"
7023
7024         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7025         nums=$($cmd | wc -l)
7026         [ $nums -eq $expected ] ||
7027                 error "'$cmd' wrong: found $nums, expected $expected"
7028
7029         expected=0
7030         # This should produce an error and not return any files
7031         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7032         nums=$($cmd 2>/dev/null | wc -l)
7033         [ $nums -eq $expected ] ||
7034                 error "'$cmd' wrong: found $nums, expected $expected"
7035
7036         if [[ $OSTCOUNT -gt 1 ]]; then
7037                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7038                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7039                 nums=$($cmd | wc -l)
7040                 [ $nums -eq $expected ] ||
7041                         error "'$cmd' wrong: found $nums, expected $expected"
7042         fi
7043 }
7044 run_test 56u "check lfs find -stripe-index works"
7045
7046 test_56v() {
7047         local mdt_idx=0
7048         local dir=$DIR/$tdir
7049
7050         setup_56 $dir $NUMFILES $NUMDIRS
7051
7052         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7053         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7054
7055         for file in $($LFS find -m $UUID $dir); do
7056                 file_midx=$($LFS getstripe -m $file)
7057                 [ $file_midx -eq $mdt_idx ] ||
7058                         error "lfs find -m $UUID != getstripe -m $file_midx"
7059         done
7060 }
7061 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7062
7063 test_56w() {
7064         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7066
7067         local dir=$DIR/$tdir
7068
7069         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7070
7071         local stripe_size=$($LFS getstripe -S -d $dir) ||
7072                 error "$LFS getstripe -S -d $dir failed"
7073         stripe_size=${stripe_size%% *}
7074
7075         local file_size=$((stripe_size * OSTCOUNT))
7076         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7077         local required_space=$((file_num * file_size))
7078         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7079                            head -n1)
7080         [[ $free_space -le $((required_space / 1024)) ]] &&
7081                 skip_env "need $required_space, have $free_space kbytes"
7082
7083         local dd_bs=65536
7084         local dd_count=$((file_size / dd_bs))
7085
7086         # write data into the files
7087         local i
7088         local j
7089         local file
7090
7091         for i in $(seq $NUMFILES); do
7092                 file=$dir/file$i
7093                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7094                         error "write data into $file failed"
7095         done
7096         for i in $(seq $NUMDIRS); do
7097                 for j in $(seq $NUMFILES); do
7098                         file=$dir/dir$i/file$j
7099                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7100                                 error "write data into $file failed"
7101                 done
7102         done
7103
7104         # $LFS_MIGRATE will fail if hard link migration is unsupported
7105         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7106                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7107                         error "creating links to $dir/dir1/file1 failed"
7108         fi
7109
7110         local expected=-1
7111
7112         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7113
7114         # lfs_migrate file
7115         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7116
7117         echo "$cmd"
7118         eval $cmd || error "$cmd failed"
7119
7120         check_stripe_count $dir/file1 $expected
7121
7122         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7123         then
7124                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7125                 # OST 1 if it is on OST 0. This file is small enough to
7126                 # be on only one stripe.
7127                 file=$dir/migr_1_ost
7128                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7129                         error "write data into $file failed"
7130                 local obdidx=$($LFS getstripe -i $file)
7131                 local oldmd5=$(md5sum $file)
7132                 local newobdidx=0
7133
7134                 [[ $obdidx -eq 0 ]] && newobdidx=1
7135                 cmd="$LFS migrate -i $newobdidx $file"
7136                 echo $cmd
7137                 eval $cmd || error "$cmd failed"
7138
7139                 local realobdix=$($LFS getstripe -i $file)
7140                 local newmd5=$(md5sum $file)
7141
7142                 [[ $newobdidx -ne $realobdix ]] &&
7143                         error "new OST is different (was=$obdidx, "\
7144                               "wanted=$newobdidx, got=$realobdix)"
7145                 [[ "$oldmd5" != "$newmd5" ]] &&
7146                         error "md5sum differ: $oldmd5, $newmd5"
7147         fi
7148
7149         # lfs_migrate dir
7150         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7151         echo "$cmd"
7152         eval $cmd || error "$cmd failed"
7153
7154         for j in $(seq $NUMFILES); do
7155                 check_stripe_count $dir/dir1/file$j $expected
7156         done
7157
7158         # lfs_migrate works with lfs find
7159         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7160              $LFS_MIGRATE -y -c $expected"
7161         echo "$cmd"
7162         eval $cmd || error "$cmd failed"
7163
7164         for i in $(seq 2 $NUMFILES); do
7165                 check_stripe_count $dir/file$i $expected
7166         done
7167         for i in $(seq 2 $NUMDIRS); do
7168                 for j in $(seq $NUMFILES); do
7169                 check_stripe_count $dir/dir$i/file$j $expected
7170                 done
7171         done
7172 }
7173 run_test 56w "check lfs_migrate -c stripe_count works"
7174
7175 test_56wb() {
7176         local file1=$DIR/$tdir/file1
7177         local create_pool=false
7178         local initial_pool=$($LFS getstripe -p $DIR)
7179         local pool_list=()
7180         local pool=""
7181
7182         echo -n "Creating test dir..."
7183         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7184         echo "done."
7185
7186         echo -n "Creating test file..."
7187         touch $file1 || error "cannot create file"
7188         echo "done."
7189
7190         echo -n "Detecting existing pools..."
7191         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7192
7193         if [ ${#pool_list[@]} -gt 0 ]; then
7194                 echo "${pool_list[@]}"
7195                 for thispool in "${pool_list[@]}"; do
7196                         if [[ -z "$initial_pool" ||
7197                               "$initial_pool" != "$thispool" ]]; then
7198                                 pool="$thispool"
7199                                 echo "Using existing pool '$pool'"
7200                                 break
7201                         fi
7202                 done
7203         else
7204                 echo "none detected."
7205         fi
7206         if [ -z "$pool" ]; then
7207                 pool=${POOL:-testpool}
7208                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7209                 echo -n "Creating pool '$pool'..."
7210                 create_pool=true
7211                 pool_add $pool &> /dev/null ||
7212                         error "pool_add failed"
7213                 echo "done."
7214
7215                 echo -n "Adding target to pool..."
7216                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7217                         error "pool_add_targets failed"
7218                 echo "done."
7219         fi
7220
7221         echo -n "Setting pool using -p option..."
7222         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7223                 error "migrate failed rc = $?"
7224         echo "done."
7225
7226         echo -n "Verifying test file is in pool after migrating..."
7227         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7228                 error "file was not migrated to pool $pool"
7229         echo "done."
7230
7231         echo -n "Removing test file from pool '$pool'..."
7232         # "lfs migrate $file" won't remove the file from the pool
7233         # until some striping information is changed.
7234         $LFS migrate -c 1 $file1 &> /dev/null ||
7235                 error "cannot remove from pool"
7236         [ "$($LFS getstripe -p $file1)" ] &&
7237                 error "pool still set"
7238         echo "done."
7239
7240         echo -n "Setting pool using --pool option..."
7241         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7242                 error "migrate failed rc = $?"
7243         echo "done."
7244
7245         # Clean up
7246         rm -f $file1
7247         if $create_pool; then
7248                 destroy_test_pools 2> /dev/null ||
7249                         error "destroy test pools failed"
7250         fi
7251 }
7252 run_test 56wb "check lfs_migrate pool support"
7253
7254 test_56wc() {
7255         local file1="$DIR/$tdir/file1"
7256         local parent_ssize
7257         local parent_scount
7258         local cur_ssize
7259         local cur_scount
7260         local orig_ssize
7261
7262         echo -n "Creating test dir..."
7263         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7264         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7265                 error "cannot set stripe by '-S 1M -c 1'"
7266         echo "done"
7267
7268         echo -n "Setting initial stripe for test file..."
7269         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7270                 error "cannot set stripe"
7271         cur_ssize=$($LFS getstripe -S "$file1")
7272         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7273         echo "done."
7274
7275         # File currently set to -S 512K -c 1
7276
7277         # Ensure -c and -S options are rejected when -R is set
7278         echo -n "Verifying incompatible options are detected..."
7279         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7280                 error "incompatible -c and -R options not detected"
7281         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7282                 error "incompatible -S and -R options not detected"
7283         echo "done."
7284
7285         # Ensure unrecognized options are passed through to 'lfs migrate'
7286         echo -n "Verifying -S option is passed through to lfs migrate..."
7287         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7288                 error "migration failed"
7289         cur_ssize=$($LFS getstripe -S "$file1")
7290         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7291         echo "done."
7292
7293         # File currently set to -S 1M -c 1
7294
7295         # Ensure long options are supported
7296         echo -n "Verifying long options supported..."
7297         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7298                 error "long option without argument not supported"
7299         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7300                 error "long option with argument not supported"
7301         cur_ssize=$($LFS getstripe -S "$file1")
7302         [ $cur_ssize -eq 524288 ] ||
7303                 error "migrate --stripe-size $cur_ssize != 524288"
7304         echo "done."
7305
7306         # File currently set to -S 512K -c 1
7307
7308         if [ "$OSTCOUNT" -gt 1 ]; then
7309                 echo -n "Verifying explicit stripe count can be set..."
7310                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7311                         error "migrate failed"
7312                 cur_scount=$($LFS getstripe -c "$file1")
7313                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7314                 echo "done."
7315         fi
7316
7317         # File currently set to -S 512K -c 1 or -S 512K -c 2
7318
7319         # Ensure parent striping is used if -R is set, and no stripe
7320         # count or size is specified
7321         echo -n "Setting stripe for parent directory..."
7322         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7323                 error "cannot set stripe '-S 2M -c 1'"
7324         echo "done."
7325
7326         echo -n "Verifying restripe option uses parent stripe settings..."
7327         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7328         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7329         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7330                 error "migrate failed"
7331         cur_ssize=$($LFS getstripe -S "$file1")
7332         [ $cur_ssize -eq $parent_ssize ] ||
7333                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7334         cur_scount=$($LFS getstripe -c "$file1")
7335         [ $cur_scount -eq $parent_scount ] ||
7336                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7337         echo "done."
7338
7339         # File currently set to -S 1M -c 1
7340
7341         # Ensure striping is preserved if -R is not set, and no stripe
7342         # count or size is specified
7343         echo -n "Verifying striping size preserved when not specified..."
7344         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7345         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7346                 error "cannot set stripe on parent directory"
7347         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7348                 error "migrate failed"
7349         cur_ssize=$($LFS getstripe -S "$file1")
7350         [ $cur_ssize -eq $orig_ssize ] ||
7351                 error "migrate by default $cur_ssize != $orig_ssize"
7352         echo "done."
7353
7354         # Ensure file name properly detected when final option has no argument
7355         echo -n "Verifying file name properly detected..."
7356         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7357                 error "file name interpreted as option argument"
7358         echo "done."
7359
7360         # Clean up
7361         rm -f "$file1"
7362 }
7363 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7364
7365 test_56wd() {
7366         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7367
7368         local file1=$DIR/$tdir/file1
7369
7370         echo -n "Creating test dir..."
7371         test_mkdir $DIR/$tdir || error "cannot create dir"
7372         echo "done."
7373
7374         echo -n "Creating test file..."
7375         touch $file1
7376         echo "done."
7377
7378         # Ensure 'lfs migrate' will fail by using a non-existent option,
7379         # and make sure rsync is not called to recover
7380         echo -n "Make sure --no-rsync option works..."
7381         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7382                 grep -q 'refusing to fall back to rsync' ||
7383                 error "rsync was called with --no-rsync set"
7384         echo "done."
7385
7386         # Ensure rsync is called without trying 'lfs migrate' first
7387         echo -n "Make sure --rsync option works..."
7388         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7389                 grep -q 'falling back to rsync' &&
7390                 error "lfs migrate was called with --rsync set"
7391         echo "done."
7392
7393         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7394         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7395                 grep -q 'at the same time' ||
7396                 error "--rsync and --no-rsync accepted concurrently"
7397         echo "done."
7398
7399         # Clean up
7400         rm -f $file1
7401 }
7402 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7403
7404 test_56we() {
7405         local td=$DIR/$tdir
7406         local tf=$td/$tfile
7407
7408         test_mkdir $td || error "cannot create $td"
7409         touch $tf || error "cannot touch $tf"
7410
7411         echo -n "Make sure --non-direct|-D works..."
7412         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7413                 grep -q "lfs migrate --non-direct" ||
7414                 error "--non-direct option cannot work correctly"
7415         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7416                 grep -q "lfs migrate -D" ||
7417                 error "-D option cannot work correctly"
7418         echo "done."
7419 }
7420 run_test 56we "check lfs_migrate --non-direct|-D support"
7421
7422 test_56x() {
7423         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7424         check_swap_layouts_support
7425
7426         local dir=$DIR/$tdir
7427         local ref1=/etc/passwd
7428         local file1=$dir/file1
7429
7430         test_mkdir $dir || error "creating dir $dir"
7431         $LFS setstripe -c 2 $file1
7432         cp $ref1 $file1
7433         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7434         stripe=$($LFS getstripe -c $file1)
7435         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7436         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7437
7438         # clean up
7439         rm -f $file1
7440 }
7441 run_test 56x "lfs migration support"
7442
7443 test_56xa() {
7444         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7445         check_swap_layouts_support
7446
7447         local dir=$DIR/$tdir/$testnum
7448
7449         test_mkdir -p $dir
7450
7451         local ref1=/etc/passwd
7452         local file1=$dir/file1
7453
7454         $LFS setstripe -c 2 $file1
7455         cp $ref1 $file1
7456         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7457
7458         local stripe=$($LFS getstripe -c $file1)
7459
7460         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7461         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7462
7463         # clean up
7464         rm -f $file1
7465 }
7466 run_test 56xa "lfs migration --block support"
7467
7468 check_migrate_links() {
7469         local dir="$1"
7470         local file1="$dir/file1"
7471         local begin="$2"
7472         local count="$3"
7473         local runas="$4"
7474         local total_count=$(($begin + $count - 1))
7475         local symlink_count=10
7476         local uniq_count=10
7477
7478         if [ ! -f "$file1" ]; then
7479                 echo -n "creating initial file..."
7480                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7481                         error "cannot setstripe initial file"
7482                 echo "done"
7483
7484                 echo -n "creating symlinks..."
7485                 for s in $(seq 1 $symlink_count); do
7486                         ln -s "$file1" "$dir/slink$s" ||
7487                                 error "cannot create symlinks"
7488                 done
7489                 echo "done"
7490
7491                 echo -n "creating nonlinked files..."
7492                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7493                         error "cannot create nonlinked files"
7494                 echo "done"
7495         fi
7496
7497         # create hard links
7498         if [ ! -f "$dir/file$total_count" ]; then
7499                 echo -n "creating hard links $begin:$total_count..."
7500                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7501                         /dev/null || error "cannot create hard links"
7502                 echo "done"
7503         fi
7504
7505         echo -n "checking number of hard links listed in xattrs..."
7506         local fid=$($LFS getstripe -F "$file1")
7507         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7508
7509         echo "${#paths[*]}"
7510         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7511                         skip "hard link list has unexpected size, skipping test"
7512         fi
7513         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7514                         error "link names should exceed xattrs size"
7515         fi
7516
7517         echo -n "migrating files..."
7518         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7519         local rc=$?
7520         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7521         echo "done"
7522
7523         # make sure all links have been properly migrated
7524         echo -n "verifying files..."
7525         fid=$($LFS getstripe -F "$file1") ||
7526                 error "cannot get fid for file $file1"
7527         for i in $(seq 2 $total_count); do
7528                 local fid2=$($LFS getstripe -F $dir/file$i)
7529
7530                 [ "$fid2" == "$fid" ] ||
7531                         error "migrated hard link has mismatched FID"
7532         done
7533
7534         # make sure hard links were properly detected, and migration was
7535         # performed only once for the entire link set; nonlinked files should
7536         # also be migrated
7537         local actual=$(grep -c 'done' <<< "$migrate_out")
7538         local expected=$(($uniq_count + 1))
7539
7540         [ "$actual" -eq  "$expected" ] ||
7541                 error "hard links individually migrated ($actual != $expected)"
7542
7543         # make sure the correct number of hard links are present
7544         local hardlinks=$(stat -c '%h' "$file1")
7545
7546         [ $hardlinks -eq $total_count ] ||
7547                 error "num hard links $hardlinks != $total_count"
7548         echo "done"
7549
7550         return 0
7551 }
7552
7553 test_56xb() {
7554         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7555                 skip "Need MDS version at least 2.10.55"
7556
7557         local dir="$DIR/$tdir"
7558
7559         test_mkdir "$dir" || error "cannot create dir $dir"
7560
7561         echo "testing lfs migrate mode when all links fit within xattrs"
7562         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7563
7564         echo "testing rsync mode when all links fit within xattrs"
7565         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7566
7567         echo "testing lfs migrate mode when all links do not fit within xattrs"
7568         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7569
7570         echo "testing rsync mode when all links do not fit within xattrs"
7571         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7572
7573         chown -R $RUNAS_ID $dir
7574         echo "testing non-root lfs migrate mode when not all links are in xattr"
7575         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7576
7577         # clean up
7578         rm -rf $dir
7579 }
7580 run_test 56xb "lfs migration hard link support"
7581
7582 test_56xc() {
7583         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7584
7585         local dir="$DIR/$tdir"
7586
7587         test_mkdir "$dir" || error "cannot create dir $dir"
7588
7589         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7590         echo -n "Setting initial stripe for 20MB test file..."
7591         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7592                 error "cannot setstripe 20MB file"
7593         echo "done"
7594         echo -n "Sizing 20MB test file..."
7595         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7596         echo "done"
7597         echo -n "Verifying small file autostripe count is 1..."
7598         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7599                 error "cannot migrate 20MB file"
7600         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7601                 error "cannot get stripe for $dir/20mb"
7602         [ $stripe_count -eq 1 ] ||
7603                 error "unexpected stripe count $stripe_count for 20MB file"
7604         rm -f "$dir/20mb"
7605         echo "done"
7606
7607         # Test 2: File is small enough to fit within the available space on
7608         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7609         # have at least an additional 1KB for each desired stripe for test 3
7610         echo -n "Setting stripe for 1GB test file..."
7611         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7612         echo "done"
7613         echo -n "Sizing 1GB test file..."
7614         # File size is 1GB + 3KB
7615         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7616         echo "done"
7617
7618         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7619         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7620         if (( avail > 524288 * OSTCOUNT )); then
7621                 echo -n "Migrating 1GB file..."
7622                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7623                         error "cannot migrate 1GB file"
7624                 echo "done"
7625                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7626                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7627                         error "cannot getstripe for 1GB file"
7628                 [ $stripe_count -eq 2 ] ||
7629                         error "unexpected stripe count $stripe_count != 2"
7630                 echo "done"
7631         fi
7632
7633         # Test 3: File is too large to fit within the available space on
7634         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7635         if [ $OSTCOUNT -ge 3 ]; then
7636                 # The required available space is calculated as
7637                 # file size (1GB + 3KB) / OST count (3).
7638                 local kb_per_ost=349526
7639
7640                 echo -n "Migrating 1GB file with limit..."
7641                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7642                         error "cannot migrate 1GB file with limit"
7643                 echo "done"
7644
7645                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7646                 echo -n "Verifying 1GB autostripe count with limited space..."
7647                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7648                         error "unexpected stripe count $stripe_count (min 3)"
7649                 echo "done"
7650         fi
7651
7652         # clean up
7653         rm -rf $dir
7654 }
7655 run_test 56xc "lfs migration autostripe"
7656
7657 test_56xd() {
7658         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7659
7660         local dir=$DIR/$tdir
7661         local f_mgrt=$dir/$tfile.mgrt
7662         local f_yaml=$dir/$tfile.yaml
7663         local f_copy=$dir/$tfile.copy
7664         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7665         local layout_copy="-c 2 -S 2M -i 1"
7666         local yamlfile=$dir/yamlfile
7667         local layout_before;
7668         local layout_after;
7669
7670         test_mkdir "$dir" || error "cannot create dir $dir"
7671         $LFS setstripe $layout_yaml $f_yaml ||
7672                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7673         $LFS getstripe --yaml $f_yaml > $yamlfile
7674         $LFS setstripe $layout_copy $f_copy ||
7675                 error "cannot setstripe $f_copy with layout $layout_copy"
7676         touch $f_mgrt
7677         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7678
7679         # 1. test option --yaml
7680         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7681                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7682         layout_before=$(get_layout_param $f_yaml)
7683         layout_after=$(get_layout_param $f_mgrt)
7684         [ "$layout_after" == "$layout_before" ] ||
7685                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7686
7687         # 2. test option --copy
7688         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7689                 error "cannot migrate $f_mgrt with --copy $f_copy"
7690         layout_before=$(get_layout_param $f_copy)
7691         layout_after=$(get_layout_param $f_mgrt)
7692         [ "$layout_after" == "$layout_before" ] ||
7693                 error "lfs_migrate --copy: $layout_after != $layout_before"
7694 }
7695 run_test 56xd "check lfs_migrate --yaml and --copy support"
7696
7697 test_56xe() {
7698         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7699
7700         local dir=$DIR/$tdir
7701         local f_comp=$dir/$tfile
7702         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7703         local layout_before=""
7704         local layout_after=""
7705
7706         test_mkdir "$dir" || error "cannot create dir $dir"
7707         $LFS setstripe $layout $f_comp ||
7708                 error "cannot setstripe $f_comp with layout $layout"
7709         layout_before=$(get_layout_param $f_comp)
7710         dd if=/dev/zero of=$f_comp bs=1M count=4
7711
7712         # 1. migrate a comp layout file by lfs_migrate
7713         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7714         layout_after=$(get_layout_param $f_comp)
7715         [ "$layout_before" == "$layout_after" ] ||
7716                 error "lfs_migrate: $layout_before != $layout_after"
7717
7718         # 2. migrate a comp layout file by lfs migrate
7719         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7720         layout_after=$(get_layout_param $f_comp)
7721         [ "$layout_before" == "$layout_after" ] ||
7722                 error "lfs migrate: $layout_before != $layout_after"
7723 }
7724 run_test 56xe "migrate a composite layout file"
7725
7726 test_56xf() {
7727         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7728
7729         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7730                 skip "Need server version at least 2.13.53"
7731
7732         local dir=$DIR/$tdir
7733         local f_comp=$dir/$tfile
7734         local layout="-E 1M -c1 -E -1 -c2"
7735         local fid_before=""
7736         local fid_after=""
7737
7738         test_mkdir "$dir" || error "cannot create dir $dir"
7739         $LFS setstripe $layout $f_comp ||
7740                 error "cannot setstripe $f_comp with layout $layout"
7741         fid_before=$($LFS getstripe --fid $f_comp)
7742         dd if=/dev/zero of=$f_comp bs=1M count=4
7743
7744         # 1. migrate a comp layout file to a comp layout
7745         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7746         fid_after=$($LFS getstripe --fid $f_comp)
7747         [ "$fid_before" == "$fid_after" ] ||
7748                 error "comp-to-comp migrate: $fid_before != $fid_after"
7749
7750         # 2. migrate a comp layout file to a plain layout
7751         $LFS migrate -c2 $f_comp ||
7752                 error "cannot migrate $f_comp by lfs migrate"
7753         fid_after=$($LFS getstripe --fid $f_comp)
7754         [ "$fid_before" == "$fid_after" ] ||
7755                 error "comp-to-plain migrate: $fid_before != $fid_after"
7756
7757         # 3. migrate a plain layout file to a comp layout
7758         $LFS migrate $layout $f_comp ||
7759                 error "cannot migrate $f_comp by lfs migrate"
7760         fid_after=$($LFS getstripe --fid $f_comp)
7761         [ "$fid_before" == "$fid_after" ] ||
7762                 error "plain-to-comp migrate: $fid_before != $fid_after"
7763 }
7764 run_test 56xf "FID is not lost during migration of a composite layout file"
7765
7766 check_file_ost_range() {
7767         local file="$1"
7768         shift
7769         local range="$*"
7770         local -a file_range
7771         local idx
7772
7773         file_range=($($LFS getstripe -y "$file" |
7774                 awk '/l_ost_idx:/ { print $NF }'))
7775
7776         if [[ "${#file_range[@]}" = 0 ]]; then
7777                 echo "No osts found for $file"
7778                 return 1
7779         fi
7780
7781         for idx in "${file_range[@]}"; do
7782                 [[ " $range " =~ " $idx " ]] ||
7783                         return 1
7784         done
7785
7786         return 0
7787 }
7788
7789 sub_test_56xg() {
7790         local stripe_opt="$1"
7791         local pool="$2"
7792         shift 2
7793         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7794
7795         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7796                 error "Fail to migrate $tfile on $pool"
7797         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7798                 error "$tfile is not in pool $pool"
7799         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7800                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7801 }
7802
7803 test_56xg() {
7804         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7805         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7806         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7807                 skip "Need MDS version newer than 2.14.52"
7808
7809         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7810         local -a pool_ranges=("0 0" "1 1" "0 1")
7811
7812         # init pools
7813         for i in "${!pool_names[@]}"; do
7814                 pool_add ${pool_names[$i]} ||
7815                         error "pool_add failed (pool: ${pool_names[$i]})"
7816                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7817                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7818         done
7819
7820         # init the file to migrate
7821         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7822                 error "Unable to create $tfile on OST1"
7823         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7824                 error "Unable to write on $tfile"
7825
7826         echo "1. migrate $tfile on pool ${pool_names[0]}"
7827         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7828
7829         echo "2. migrate $tfile on pool ${pool_names[2]}"
7830         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7831
7832         echo "3. migrate $tfile on pool ${pool_names[1]}"
7833         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7834
7835         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7836         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7837         echo
7838
7839         # Clean pools
7840         destroy_test_pools ||
7841                 error "pool_destroy failed"
7842 }
7843 run_test 56xg "lfs migrate pool support"
7844
7845 test_56y() {
7846         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7847                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7848
7849         local res=""
7850         local dir=$DIR/$tdir
7851         local f1=$dir/file1
7852         local f2=$dir/file2
7853
7854         test_mkdir -p $dir || error "creating dir $dir"
7855         touch $f1 || error "creating std file $f1"
7856         $MULTIOP $f2 H2c || error "creating released file $f2"
7857
7858         # a directory can be raid0, so ask only for files
7859         res=$($LFS find $dir -L raid0 -type f | wc -l)
7860         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7861
7862         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7863         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7864
7865         # only files can be released, so no need to force file search
7866         res=$($LFS find $dir -L released)
7867         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7868
7869         res=$($LFS find $dir -type f \! -L released)
7870         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7871 }
7872 run_test 56y "lfs find -L raid0|released"
7873
7874 test_56z() { # LU-4824
7875         # This checks to make sure 'lfs find' continues after errors
7876         # There are two classes of errors that should be caught:
7877         # - If multiple paths are provided, all should be searched even if one
7878         #   errors out
7879         # - If errors are encountered during the search, it should not terminate
7880         #   early
7881         local dir=$DIR/$tdir
7882         local i
7883
7884         test_mkdir $dir
7885         for i in d{0..9}; do
7886                 test_mkdir $dir/$i
7887                 touch $dir/$i/$tfile
7888         done
7889         $LFS find $DIR/non_existent_dir $dir &&
7890                 error "$LFS find did not return an error"
7891         # Make a directory unsearchable. This should NOT be the last entry in
7892         # directory order.  Arbitrarily pick the 6th entry
7893         chmod 700 $($LFS find $dir -type d | sed '6!d')
7894
7895         $RUNAS $LFS find $DIR/non_existent $dir
7896         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7897
7898         # The user should be able to see 10 directories and 9 files
7899         (( count == 19 )) ||
7900                 error "$LFS find found $count != 19 entries after error"
7901 }
7902 run_test 56z "lfs find should continue after an error"
7903
7904 test_56aa() { # LU-5937
7905         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7906
7907         local dir=$DIR/$tdir
7908
7909         mkdir $dir
7910         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7911
7912         createmany -o $dir/striped_dir/${tfile}- 1024
7913         local dirs=$($LFS find --size +8k $dir/)
7914
7915         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7916 }
7917 run_test 56aa "lfs find --size under striped dir"
7918
7919 test_56ab() { # LU-10705
7920         test_mkdir $DIR/$tdir
7921         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7922         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7923         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7924         # Flush writes to ensure valid blocks.  Need to be more thorough for
7925         # ZFS, since blocks are not allocated/returned to client immediately.
7926         sync_all_data
7927         wait_zfs_commit ost1 2
7928         cancel_lru_locks osc
7929         ls -ls $DIR/$tdir
7930
7931         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7932
7933         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7934
7935         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7936         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7937
7938         rm -f $DIR/$tdir/$tfile.[123]
7939 }
7940 run_test 56ab "lfs find --blocks"
7941
7942 # LU-11188
7943 test_56aca() {
7944         local dir="$DIR/$tdir"
7945         local perms=(001 002 003 004 005 006 007
7946                      010 020 030 040 050 060 070
7947                      100 200 300 400 500 600 700
7948                      111 222 333 444 555 666 777)
7949         local perm_minus=(8 8 4 8 4 4 2
7950                           8 8 4 8 4 4 2
7951                           8 8 4 8 4 4 2
7952                           4 4 2 4 2 2 1)
7953         local perm_slash=(8  8 12  8 12 12 14
7954                           8  8 12  8 12 12 14
7955                           8  8 12  8 12 12 14
7956                          16 16 24 16 24 24 28)
7957
7958         test_mkdir "$dir"
7959         for perm in ${perms[*]}; do
7960                 touch "$dir/$tfile.$perm"
7961                 chmod $perm "$dir/$tfile.$perm"
7962         done
7963
7964         for ((i = 0; i < ${#perms[*]}; i++)); do
7965                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7966                 (( $num == 1 )) ||
7967                         error "lfs find -perm ${perms[i]}:"\
7968                               "$num != 1"
7969
7970                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7971                 (( $num == ${perm_minus[i]} )) ||
7972                         error "lfs find -perm -${perms[i]}:"\
7973                               "$num != ${perm_minus[i]}"
7974
7975                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7976                 (( $num == ${perm_slash[i]} )) ||
7977                         error "lfs find -perm /${perms[i]}:"\
7978                               "$num != ${perm_slash[i]}"
7979         done
7980 }
7981 run_test 56aca "check lfs find -perm with octal representation"
7982
7983 test_56acb() {
7984         local dir=$DIR/$tdir
7985         # p is the permission of write and execute for user, group and other
7986         # without the umask. It is used to test +wx.
7987         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7988         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7989         local symbolic=(+t  a+t u+t g+t o+t
7990                         g+s u+s o+s +s o+sr
7991                         o=r,ug+o,u+w
7992                         u+ g+ o+ a+ ugo+
7993                         u- g- o- a- ugo-
7994                         u= g= o= a= ugo=
7995                         o=r,ug+o,u+w u=r,a+u,u+w
7996                         g=r,ugo=g,u+w u+x,+X +X
7997                         u+x,u+X u+X u+x,g+X o+r,+X
7998                         u+x,go+X +wx +rwx)
7999
8000         test_mkdir $dir
8001         for perm in ${perms[*]}; do
8002                 touch "$dir/$tfile.$perm"
8003                 chmod $perm "$dir/$tfile.$perm"
8004         done
8005
8006         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8007                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8008
8009                 (( $num == 1 )) ||
8010                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8011         done
8012 }
8013 run_test 56acb "check lfs find -perm with symbolic representation"
8014
8015 test_56acc() {
8016         local dir=$DIR/$tdir
8017         local tests="17777 787 789 abcd
8018                 ug=uu ug=a ug=gu uo=ou urw
8019                 u+xg+x a=r,u+x,"
8020
8021         test_mkdir $dir
8022         for err in $tests; do
8023                 if $LFS find $dir -perm $err 2>/dev/null; then
8024                         error "lfs find -perm $err: parsing should have failed"
8025                 fi
8026         done
8027 }
8028 run_test 56acc "check parsing error for lfs find -perm"
8029
8030 test_56ba() {
8031         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8032                 skip "Need MDS version at least 2.10.50"
8033
8034         # Create composite files with one component
8035         local dir=$DIR/$tdir
8036
8037         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8038         # Create composite files with three components
8039         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8040         # Create non-composite files
8041         createmany -o $dir/${tfile}- 10
8042
8043         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8044
8045         [[ $nfiles == 10 ]] ||
8046                 error "lfs find -E 1M found $nfiles != 10 files"
8047
8048         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8049         [[ $nfiles == 25 ]] ||
8050                 error "lfs find ! -E 1M found $nfiles != 25 files"
8051
8052         # All files have a component that starts at 0
8053         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8054         [[ $nfiles == 35 ]] ||
8055                 error "lfs find --component-start 0 - $nfiles != 35 files"
8056
8057         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8058         [[ $nfiles == 15 ]] ||
8059                 error "lfs find --component-start 2M - $nfiles != 15 files"
8060
8061         # All files created here have a componenet that does not starts at 2M
8062         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8063         [[ $nfiles == 35 ]] ||
8064                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8065
8066         # Find files with a specified number of components
8067         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8068         [[ $nfiles == 15 ]] ||
8069                 error "lfs find --component-count 3 - $nfiles != 15 files"
8070
8071         # Remember non-composite files have a component count of zero
8072         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8073         [[ $nfiles == 10 ]] ||
8074                 error "lfs find --component-count 0 - $nfiles != 10 files"
8075
8076         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8077         [[ $nfiles == 20 ]] ||
8078                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8079
8080         # All files have a flag called "init"
8081         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8082         [[ $nfiles == 35 ]] ||
8083                 error "lfs find --component-flags init - $nfiles != 35 files"
8084
8085         # Multi-component files will have a component not initialized
8086         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8087         [[ $nfiles == 15 ]] ||
8088                 error "lfs find !--component-flags init - $nfiles != 15 files"
8089
8090         rm -rf $dir
8091
8092 }
8093 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8094
8095 test_56ca() {
8096         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8097                 skip "Need MDS version at least 2.10.57"
8098
8099         local td=$DIR/$tdir
8100         local tf=$td/$tfile
8101         local dir
8102         local nfiles
8103         local cmd
8104         local i
8105         local j
8106
8107         # create mirrored directories and mirrored files
8108         mkdir $td || error "mkdir $td failed"
8109         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8110         createmany -o $tf- 10 || error "create $tf- failed"
8111
8112         for i in $(seq 2); do
8113                 dir=$td/dir$i
8114                 mkdir $dir || error "mkdir $dir failed"
8115                 $LFS mirror create -N$((3 + i)) $dir ||
8116                         error "create mirrored dir $dir failed"
8117                 createmany -o $dir/$tfile- 10 ||
8118                         error "create $dir/$tfile- failed"
8119         done
8120
8121         # change the states of some mirrored files
8122         echo foo > $tf-6
8123         for i in $(seq 2); do
8124                 dir=$td/dir$i
8125                 for j in $(seq 4 9); do
8126                         echo foo > $dir/$tfile-$j
8127                 done
8128         done
8129
8130         # find mirrored files with specific mirror count
8131         cmd="$LFS find --mirror-count 3 --type f $td"
8132         nfiles=$($cmd | wc -l)
8133         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8134
8135         cmd="$LFS find ! --mirror-count 3 --type f $td"
8136         nfiles=$($cmd | wc -l)
8137         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8138
8139         cmd="$LFS find --mirror-count +2 --type f $td"
8140         nfiles=$($cmd | wc -l)
8141         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8142
8143         cmd="$LFS find --mirror-count -6 --type f $td"
8144         nfiles=$($cmd | wc -l)
8145         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8146
8147         # find mirrored files with specific file state
8148         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8149         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8150
8151         cmd="$LFS find --mirror-state=ro --type f $td"
8152         nfiles=$($cmd | wc -l)
8153         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8154
8155         cmd="$LFS find ! --mirror-state=ro --type f $td"
8156         nfiles=$($cmd | wc -l)
8157         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8158
8159         cmd="$LFS find --mirror-state=wp --type f $td"
8160         nfiles=$($cmd | wc -l)
8161         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8162
8163         cmd="$LFS find ! --mirror-state=sp --type f $td"
8164         nfiles=$($cmd | wc -l)
8165         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8166 }
8167 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8168
8169 test_56da() { # LU-14179
8170         local path=$DIR/$tdir
8171
8172         test_mkdir $path
8173         cd $path
8174
8175         local longdir=$(str_repeat 'a' 255)
8176
8177         for i in {1..15}; do
8178                 path=$path/$longdir
8179                 test_mkdir $longdir
8180                 cd $longdir
8181         done
8182
8183         local len=${#path}
8184         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8185
8186         test_mkdir $lastdir
8187         cd $lastdir
8188         # PATH_MAX-1
8189         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8190
8191         # NAME_MAX
8192         touch $(str_repeat 'f' 255)
8193
8194         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8195                 error "lfs find reported an error"
8196
8197         rm -rf $DIR/$tdir
8198 }
8199 run_test 56da "test lfs find with long paths"
8200
8201 test_56ea() { #LU-10378
8202         local path=$DIR/$tdir
8203         local pool=$TESTNAME
8204
8205         # Create ost pool
8206         pool_add $pool || error "pool_add $pool failed"
8207         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8208                 error "adding targets to $pool failed"
8209
8210         # Set default pool on directory before creating file
8211         mkdir $path || error "mkdir $path failed"
8212         $LFS setstripe -p $pool $path ||
8213                 error "set OST pool on $pool failed"
8214         touch $path/$tfile || error "touch $path/$tfile failed"
8215
8216         # Compare basic file attributes from -printf and stat
8217         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8218         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8219
8220         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8221                 error "Attrs from lfs find and stat don't match"
8222
8223         # Compare Lustre attributes from lfs find and lfs getstripe
8224         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8225         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8226         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8227         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8228         local fpool=$($LFS getstripe --pool $path/$tfile)
8229         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8230
8231         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8232                 error "Attrs from lfs find and lfs getstripe don't match"
8233
8234         # Verify behavior for unknown escape/format sequences
8235         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8236
8237         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8238                 error "Escape/format codes don't match"
8239 }
8240 run_test 56ea "test lfs find -printf option"
8241
8242 test_57a() {
8243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8244         # note test will not do anything if MDS is not local
8245         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8246                 skip_env "ldiskfs only test"
8247         fi
8248         remote_mds_nodsh && skip "remote MDS with nodsh"
8249
8250         local MNTDEV="osd*.*MDT*.mntdev"
8251         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8252         [ -z "$DEV" ] && error "can't access $MNTDEV"
8253         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8254                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8255                         error "can't access $DEV"
8256                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8257                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8258                 rm $TMP/t57a.dump
8259         done
8260 }
8261 run_test 57a "verify MDS filesystem created with large inodes =="
8262
8263 test_57b() {
8264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8265         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8266                 skip_env "ldiskfs only test"
8267         fi
8268         remote_mds_nodsh && skip "remote MDS with nodsh"
8269
8270         local dir=$DIR/$tdir
8271         local filecount=100
8272         local file1=$dir/f1
8273         local fileN=$dir/f$filecount
8274
8275         rm -rf $dir || error "removing $dir"
8276         test_mkdir -c1 $dir
8277         local mdtidx=$($LFS getstripe -m $dir)
8278         local mdtname=MDT$(printf %04x $mdtidx)
8279         local facet=mds$((mdtidx + 1))
8280
8281         echo "mcreating $filecount files"
8282         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8283
8284         # verify that files do not have EAs yet
8285         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8286                 error "$file1 has an EA"
8287         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8288                 error "$fileN has an EA"
8289
8290         sync
8291         sleep 1
8292         df $dir  #make sure we get new statfs data
8293         local mdsfree=$(do_facet $facet \
8294                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8295         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8296         local file
8297
8298         echo "opening files to create objects/EAs"
8299         for file in $(seq -f $dir/f%g 1 $filecount); do
8300                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8301                         error "opening $file"
8302         done
8303
8304         # verify that files have EAs now
8305         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8306         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8307
8308         sleep 1  #make sure we get new statfs data
8309         df $dir
8310         local mdsfree2=$(do_facet $facet \
8311                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8312         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8313
8314         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8315                 if [ "$mdsfree" != "$mdsfree2" ]; then
8316                         error "MDC before $mdcfree != after $mdcfree2"
8317                 else
8318                         echo "MDC before $mdcfree != after $mdcfree2"
8319                         echo "unable to confirm if MDS has large inodes"
8320                 fi
8321         fi
8322         rm -rf $dir
8323 }
8324 run_test 57b "default LOV EAs are stored inside large inodes ==="
8325
8326 test_58() {
8327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8328         [ -z "$(which wiretest 2>/dev/null)" ] &&
8329                         skip_env "could not find wiretest"
8330
8331         wiretest
8332 }
8333 run_test 58 "verify cross-platform wire constants =============="
8334
8335 test_59() {
8336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8337
8338         echo "touch 130 files"
8339         createmany -o $DIR/f59- 130
8340         echo "rm 130 files"
8341         unlinkmany $DIR/f59- 130
8342         sync
8343         # wait for commitment of removal
8344         wait_delete_completed
8345 }
8346 run_test 59 "verify cancellation of llog records async ========="
8347
8348 TEST60_HEAD="test_60 run $RANDOM"
8349 test_60a() {
8350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8351         remote_mgs_nodsh && skip "remote MGS with nodsh"
8352         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8353                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8354                         skip_env "missing subtest run-llog.sh"
8355
8356         log "$TEST60_HEAD - from kernel mode"
8357         do_facet mgs "$LCTL dk > /dev/null"
8358         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8359         do_facet mgs $LCTL dk > $TMP/$tfile
8360
8361         # LU-6388: test llog_reader
8362         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8363         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8364         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8365                         skip_env "missing llog_reader"
8366         local fstype=$(facet_fstype mgs)
8367         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8368                 skip_env "Only for ldiskfs or zfs type mgs"
8369
8370         local mntpt=$(facet_mntpt mgs)
8371         local mgsdev=$(mgsdevname 1)
8372         local fid_list
8373         local fid
8374         local rec_list
8375         local rec
8376         local rec_type
8377         local obj_file
8378         local path
8379         local seq
8380         local oid
8381         local pass=true
8382
8383         #get fid and record list
8384         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8385                 tail -n 4))
8386         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8387                 tail -n 4))
8388         #remount mgs as ldiskfs or zfs type
8389         stop mgs || error "stop mgs failed"
8390         mount_fstype mgs || error "remount mgs failed"
8391         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8392                 fid=${fid_list[i]}
8393                 rec=${rec_list[i]}
8394                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8395                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8396                 oid=$((16#$oid))
8397
8398                 case $fstype in
8399                         ldiskfs )
8400                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8401                         zfs )
8402                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8403                 esac
8404                 echo "obj_file is $obj_file"
8405                 do_facet mgs $llog_reader $obj_file
8406
8407                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8408                         awk '{ print $3 }' | sed -e "s/^type=//g")
8409                 if [ $rec_type != $rec ]; then
8410                         echo "FAILED test_60a wrong record type $rec_type," \
8411                               "should be $rec"
8412                         pass=false
8413                         break
8414                 fi
8415
8416                 #check obj path if record type is LLOG_LOGID_MAGIC
8417                 if [ "$rec" == "1064553b" ]; then
8418                         path=$(do_facet mgs $llog_reader $obj_file |
8419                                 grep "path=" | awk '{ print $NF }' |
8420                                 sed -e "s/^path=//g")
8421                         if [ $obj_file != $mntpt/$path ]; then
8422                                 echo "FAILED test_60a wrong obj path" \
8423                                       "$montpt/$path, should be $obj_file"
8424                                 pass=false
8425                                 break
8426                         fi
8427                 fi
8428         done
8429         rm -f $TMP/$tfile
8430         #restart mgs before "error", otherwise it will block the next test
8431         stop mgs || error "stop mgs failed"
8432         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8433         $pass || error "test failed, see FAILED test_60a messages for specifics"
8434 }
8435 run_test 60a "llog_test run from kernel module and test llog_reader"
8436
8437 test_60b() { # bug 6411
8438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8439
8440         dmesg > $DIR/$tfile
8441         LLOG_COUNT=$(do_facet mgs dmesg |
8442                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8443                           /llog_[a-z]*.c:[0-9]/ {
8444                                 if (marker)
8445                                         from_marker++
8446                                 from_begin++
8447                           }
8448                           END {
8449                                 if (marker)
8450                                         print from_marker
8451                                 else
8452                                         print from_begin
8453                           }")
8454
8455         [[ $LLOG_COUNT -gt 120 ]] &&
8456                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8457 }
8458 run_test 60b "limit repeated messages from CERROR/CWARN"
8459
8460 test_60c() {
8461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8462
8463         echo "create 5000 files"
8464         createmany -o $DIR/f60c- 5000
8465 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8466         lctl set_param fail_loc=0x80000137
8467         unlinkmany $DIR/f60c- 5000
8468         lctl set_param fail_loc=0
8469 }
8470 run_test 60c "unlink file when mds full"
8471
8472 test_60d() {
8473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8474
8475         SAVEPRINTK=$(lctl get_param -n printk)
8476         # verify "lctl mark" is even working"
8477         MESSAGE="test message ID $RANDOM $$"
8478         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8479         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8480
8481         lctl set_param printk=0 || error "set lnet.printk failed"
8482         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8483         MESSAGE="new test message ID $RANDOM $$"
8484         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8485         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8486         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8487
8488         lctl set_param -n printk="$SAVEPRINTK"
8489 }
8490 run_test 60d "test printk console message masking"
8491
8492 test_60e() {
8493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8494         remote_mds_nodsh && skip "remote MDS with nodsh"
8495
8496         touch $DIR/$tfile
8497 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8498         do_facet mds1 lctl set_param fail_loc=0x15b
8499         rm $DIR/$tfile
8500 }
8501 run_test 60e "no space while new llog is being created"
8502
8503 test_60f() {
8504         local old_path=$($LCTL get_param -n debug_path)
8505
8506         stack_trap "$LCTL set_param debug_path=$old_path"
8507         stack_trap "rm -f $TMP/$tfile*"
8508         rm -f $TMP/$tfile* 2> /dev/null
8509         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8510         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8511         test_mkdir $DIR/$tdir
8512         # retry in case the open is cached and not released
8513         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8514                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8515                 sleep 0.1
8516         done
8517         ls $TMP/$tfile*
8518         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8519 }
8520 run_test 60f "change debug_path works"
8521
8522 test_60g() {
8523         local pid
8524         local i
8525
8526         test_mkdir -c $MDSCOUNT $DIR/$tdir
8527
8528         (
8529                 local index=0
8530                 while true; do
8531                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8532                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8533                                 2>/dev/null
8534                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8535                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8536                         index=$((index + 1))
8537                 done
8538         ) &
8539
8540         pid=$!
8541
8542         for i in {0..100}; do
8543                 # define OBD_FAIL_OSD_TXN_START    0x19a
8544                 local index=$((i % MDSCOUNT + 1))
8545
8546                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8547                         > /dev/null
8548                 sleep 0.01
8549         done
8550
8551         kill -9 $pid
8552
8553         for i in $(seq $MDSCOUNT); do
8554                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8555         done
8556
8557         mkdir $DIR/$tdir/new || error "mkdir failed"
8558         rmdir $DIR/$tdir/new || error "rmdir failed"
8559
8560         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8561                 -t namespace
8562         for i in $(seq $MDSCOUNT); do
8563                 wait_update_facet mds$i "$LCTL get_param -n \
8564                         mdd.$(facet_svc mds$i).lfsck_namespace |
8565                         awk '/^status/ { print \\\$2 }'" "completed"
8566         done
8567
8568         ls -R $DIR/$tdir
8569         rm -rf $DIR/$tdir || error "rmdir failed"
8570 }
8571 run_test 60g "transaction abort won't cause MDT hung"
8572
8573 test_60h() {
8574         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8575                 skip "Need MDS version at least 2.12.52"
8576         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8577
8578         local f
8579
8580         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8581         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8582         for fail_loc in 0x80000188 0x80000189; do
8583                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8584                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8585                         error "mkdir $dir-$fail_loc failed"
8586                 for i in {0..10}; do
8587                         # create may fail on missing stripe
8588                         echo $i > $DIR/$tdir-$fail_loc/$i
8589                 done
8590                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8591                         error "getdirstripe $tdir-$fail_loc failed"
8592                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8593                         error "migrate $tdir-$fail_loc failed"
8594                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8595                         error "getdirstripe $tdir-$fail_loc failed"
8596                 pushd $DIR/$tdir-$fail_loc
8597                 for f in *; do
8598                         echo $f | cmp $f - || error "$f data mismatch"
8599                 done
8600                 popd
8601                 rm -rf $DIR/$tdir-$fail_loc
8602         done
8603 }
8604 run_test 60h "striped directory with missing stripes can be accessed"
8605
8606 function t60i_load() {
8607         mkdir $DIR/$tdir
8608         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8609         $LCTL set_param fail_loc=0x131c fail_val=1
8610         for ((i=0; i<5000; i++)); do
8611                 touch $DIR/$tdir/f$i
8612         done
8613 }
8614
8615 test_60i() {
8616         changelog_register || error "changelog_register failed"
8617         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8618         changelog_users $SINGLEMDS | grep -q $cl_user ||
8619                 error "User $cl_user not found in changelog_users"
8620         changelog_chmask "ALL"
8621         t60i_load &
8622         local PID=$!
8623         for((i=0; i<100; i++)); do
8624                 changelog_dump >/dev/null ||
8625                         error "can't read changelog"
8626         done
8627         kill $PID
8628         wait $PID
8629         changelog_deregister || error "changelog_deregister failed"
8630         $LCTL set_param fail_loc=0
8631 }
8632 run_test 60i "llog: new record vs reader race"
8633
8634 test_61a() {
8635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8636
8637         f="$DIR/f61"
8638         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8639         cancel_lru_locks osc
8640         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8641         sync
8642 }
8643 run_test 61a "mmap() writes don't make sync hang ================"
8644
8645 test_61b() {
8646         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8647 }
8648 run_test 61b "mmap() of unstriped file is successful"
8649
8650 # bug 2330 - insufficient obd_match error checking causes LBUG
8651 test_62() {
8652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8653
8654         f="$DIR/f62"
8655         echo foo > $f
8656         cancel_lru_locks osc
8657         lctl set_param fail_loc=0x405
8658         cat $f && error "cat succeeded, expect -EIO"
8659         lctl set_param fail_loc=0
8660 }
8661 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8662 # match every page all of the time.
8663 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8664
8665 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8666 # Though this test is irrelevant anymore, it helped to reveal some
8667 # other grant bugs (LU-4482), let's keep it.
8668 test_63a() {   # was test_63
8669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8670
8671         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8672
8673         for i in `seq 10` ; do
8674                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8675                 sleep 5
8676                 kill $!
8677                 sleep 1
8678         done
8679
8680         rm -f $DIR/f63 || true
8681 }
8682 run_test 63a "Verify oig_wait interruption does not crash ======="
8683
8684 # bug 2248 - async write errors didn't return to application on sync
8685 # bug 3677 - async write errors left page locked
8686 test_63b() {
8687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8688
8689         debugsave
8690         lctl set_param debug=-1
8691
8692         # ensure we have a grant to do async writes
8693         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8694         rm $DIR/$tfile
8695
8696         sync    # sync lest earlier test intercept the fail_loc
8697
8698         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8699         lctl set_param fail_loc=0x80000406
8700         $MULTIOP $DIR/$tfile Owy && \
8701                 error "sync didn't return ENOMEM"
8702         sync; sleep 2; sync     # do a real sync this time to flush page
8703         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8704                 error "locked page left in cache after async error" || true
8705         debugrestore
8706 }
8707 run_test 63b "async write errors should be returned to fsync ==="
8708
8709 test_64a () {
8710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8711
8712         lfs df $DIR
8713         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8714 }
8715 run_test 64a "verify filter grant calculations (in kernel) ====="
8716
8717 test_64b () {
8718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8719
8720         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8721 }
8722 run_test 64b "check out-of-space detection on client"
8723
8724 test_64c() {
8725         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8726 }
8727 run_test 64c "verify grant shrink"
8728
8729 import_param() {
8730         local tgt=$1
8731         local param=$2
8732
8733         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8734 }
8735
8736 # this does exactly what osc_request.c:osc_announce_cached() does in
8737 # order to calculate max amount of grants to ask from server
8738 want_grant() {
8739         local tgt=$1
8740
8741         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8742         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8743
8744         ((rpc_in_flight++));
8745         nrpages=$((nrpages * rpc_in_flight))
8746
8747         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8748
8749         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8750
8751         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8752         local undirty=$((nrpages * PAGE_SIZE))
8753
8754         local max_extent_pages
8755         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8756         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8757         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8758         local grant_extent_tax
8759         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8760
8761         undirty=$((undirty + nrextents * grant_extent_tax))
8762
8763         echo $undirty
8764 }
8765
8766 # this is size of unit for grant allocation. It should be equal to
8767 # what tgt_grant.c:tgt_grant_chunk() calculates
8768 grant_chunk() {
8769         local tgt=$1
8770         local max_brw_size
8771         local grant_extent_tax
8772
8773         max_brw_size=$(import_param $tgt max_brw_size)
8774
8775         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8776
8777         echo $(((max_brw_size + grant_extent_tax) * 2))
8778 }
8779
8780 test_64d() {
8781         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8782                 skip "OST < 2.10.55 doesn't limit grants enough"
8783
8784         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8785
8786         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8787                 skip "no grant_param connect flag"
8788
8789         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8790
8791         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8792         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8793
8794
8795         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8796         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8797
8798         $LFS setstripe $DIR/$tfile -i 0 -c 1
8799         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8800         ddpid=$!
8801
8802         while kill -0 $ddpid; do
8803                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8804
8805                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8806                         kill $ddpid
8807                         error "cur_grant $cur_grant > $max_cur_granted"
8808                 fi
8809
8810                 sleep 1
8811         done
8812 }
8813 run_test 64d "check grant limit exceed"
8814
8815 check_grants() {
8816         local tgt=$1
8817         local expected=$2
8818         local msg=$3
8819         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8820
8821         ((cur_grants == expected)) ||
8822                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8823 }
8824
8825 round_up_p2() {
8826         echo $((($1 + $2 - 1) & ~($2 - 1)))
8827 }
8828
8829 test_64e() {
8830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8831         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8832                 skip "Need OSS version at least 2.11.56"
8833
8834         # Remount client to reset grant
8835         remount_client $MOUNT || error "failed to remount client"
8836         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8837
8838         local init_grants=$(import_param $osc_tgt initial_grant)
8839
8840         check_grants $osc_tgt $init_grants "init grants"
8841
8842         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8843         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8844         local gbs=$(import_param $osc_tgt grant_block_size)
8845
8846         # write random number of bytes from max_brw_size / 4 to max_brw_size
8847         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8848         # align for direct io
8849         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8850         # round to grant consumption unit
8851         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8852
8853         local grants=$((wb_round_up + extent_tax))
8854
8855         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8856
8857         # define OBD_FAIL_TGT_NO_GRANT 0x725
8858         # make the server not grant more back
8859         do_facet ost1 $LCTL set_param fail_loc=0x725
8860         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8861
8862         do_facet ost1 $LCTL set_param fail_loc=0
8863
8864         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8865
8866         rm -f $DIR/$tfile || error "rm failed"
8867
8868         # Remount client to reset grant
8869         remount_client $MOUNT || error "failed to remount client"
8870         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8871
8872         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8873
8874         # define OBD_FAIL_TGT_NO_GRANT 0x725
8875         # make the server not grant more back
8876         do_facet ost1 $LCTL set_param fail_loc=0x725
8877         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8878         do_facet ost1 $LCTL set_param fail_loc=0
8879
8880         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8881 }
8882 run_test 64e "check grant consumption (no grant allocation)"
8883
8884 test_64f() {
8885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8886
8887         # Remount client to reset grant
8888         remount_client $MOUNT || error "failed to remount client"
8889         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8890
8891         local init_grants=$(import_param $osc_tgt initial_grant)
8892         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8893         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8894         local gbs=$(import_param $osc_tgt grant_block_size)
8895         local chunk=$(grant_chunk $osc_tgt)
8896
8897         # write random number of bytes from max_brw_size / 4 to max_brw_size
8898         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8899         # align for direct io
8900         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8901         # round to grant consumption unit
8902         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8903
8904         local grants=$((wb_round_up + extent_tax))
8905
8906         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8907         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8908                 error "error writing to $DIR/$tfile"
8909
8910         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8911                 "direct io with grant allocation"
8912
8913         rm -f $DIR/$tfile || error "rm failed"
8914
8915         # Remount client to reset grant
8916         remount_client $MOUNT || error "failed to remount client"
8917         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8918
8919         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8920
8921         local cmd="oO_WRONLY:w${write_bytes}_yc"
8922
8923         $MULTIOP $DIR/$tfile $cmd &
8924         MULTIPID=$!
8925         sleep 1
8926
8927         check_grants $osc_tgt $((init_grants - grants)) \
8928                 "buffered io, not write rpc"
8929
8930         kill -USR1 $MULTIPID
8931         wait
8932
8933         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8934                 "buffered io, one RPC"
8935 }
8936 run_test 64f "check grant consumption (with grant allocation)"
8937
8938 test_64g() {
8939         #[ $MDS1_VERSION -lt $(version_code 2.14.54) ] &&
8940         #       skip "Need MDS version at least 2.14.54"
8941
8942         local mdts=$(comma_list $(mdts_nodes))
8943
8944         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8945                         tr '\n' ' ')
8946         stack_trap "$LCTL set_param $old"
8947
8948         # generate dirty pages and increase dirty granted on MDT
8949         stack_trap "rm -f $DIR/$tfile-*"
8950         for (( i = 0; i < 10; i++)); do
8951                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8952                         error "can't set stripe"
8953                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8954                         error "can't dd"
8955                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8956                         $LFS getstripe $DIR/$tfile-$i
8957                         error "not DoM file"
8958                 }
8959         done
8960
8961         # flush dirty pages
8962         sync
8963
8964         # wait until grant shrink reset grant dirty on MDTs
8965         for ((i = 0; i < 120; i++)); do
8966                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8967                         awk '{sum=sum+$1} END {print sum}')
8968                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8969                 echo "$grant_dirty grants, $vm_dirty pages"
8970                 (( grant_dirty + vm_dirty == 0 )) && break
8971                 (( i == 3 )) && sync &&
8972                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8973                 sleep 1
8974         done
8975
8976         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8977                 awk '{sum=sum+$1} END {print sum}')
8978         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8979 }
8980 run_test 64g "grant shrink on MDT"
8981
8982 test_64h() {
8983         local instance=$($LFS getname -i $DIR)
8984         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8985         local num_exps=$(do_facet ost1 \
8986             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8987         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8988         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8989         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8990
8991         # 10MiB is for file to be written, max_brw_size * 16 *
8992         # num_exps is space reserve so that tgt_grant_shrink() decided
8993         # to not shrink
8994         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8995         (( avail * 1024 < expect )) &&
8996                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8997
8998         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8999         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9000         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9001         $LCTL set_param osc.*OST0000*.grant_shrink=1
9002         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9003
9004         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9005         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9006
9007         # drop cache so that coming read would do rpc
9008         cancel_lru_locks osc
9009
9010         # shrink interval is set to 10, pause for 7 seconds so that
9011         # grant thread did not wake up yet but coming read entered
9012         # shrink mode for rpc (osc_should_shrink_grant())
9013         sleep 7
9014
9015         declare -a cur_grant_bytes
9016         declare -a tot_granted
9017         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9018         tot_granted[0]=$(do_facet ost1 \
9019             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9020
9021         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9022
9023         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9024         tot_granted[1]=$(do_facet ost1 \
9025             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9026
9027         # grant change should be equal on both sides
9028         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9029                 tot_granted[0] - tot_granted[1])) ||
9030                 error "grant change mismatch, "                                \
9031                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9032                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9033 }
9034 run_test 64h "grant shrink on read"
9035
9036 test_64i() {
9037         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
9038                 skip "need OST at least 2.14.55 to avoid grant shrink on replay"
9039
9040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9041         remote_ost_nodsh && skip "remote OSTs with nodsh"
9042
9043         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9044
9045         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9046
9047         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9048         local instance=$($LFS getname -i $DIR)
9049
9050         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9051         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9052
9053         # shrink grants and simulate rpc loss
9054         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9055         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9056         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9057
9058         fail ost1
9059
9060         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9061
9062         local testid=$(echo $TESTNAME | tr '_' ' ')
9063
9064         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9065                 grep "GRANT, real grant" &&
9066                 error "client has more grants then it owns" || true
9067 }
9068 run_test 64i "shrink on reconnect"
9069
9070 # bug 1414 - set/get directories' stripe info
9071 test_65a() {
9072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9073
9074         test_mkdir $DIR/$tdir
9075         touch $DIR/$tdir/f1
9076         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9077 }
9078 run_test 65a "directory with no stripe info"
9079
9080 test_65b() {
9081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9082
9083         test_mkdir $DIR/$tdir
9084         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9085
9086         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9087                                                 error "setstripe"
9088         touch $DIR/$tdir/f2
9089         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9090 }
9091 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9092
9093 test_65c() {
9094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9095         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9096
9097         test_mkdir $DIR/$tdir
9098         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9099
9100         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9101                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9102         touch $DIR/$tdir/f3
9103         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9104 }
9105 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9106
9107 test_65d() {
9108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9109
9110         test_mkdir $DIR/$tdir
9111         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9112         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9113
9114         if [[ $STRIPECOUNT -le 0 ]]; then
9115                 sc=1
9116         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9117                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9118                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9119         else
9120                 sc=$(($STRIPECOUNT - 1))
9121         fi
9122         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9123         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9124         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9125                 error "lverify failed"
9126 }
9127 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9128
9129 test_65e() {
9130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9131
9132         test_mkdir $DIR/$tdir
9133
9134         $LFS setstripe $DIR/$tdir || error "setstripe"
9135         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9136                                         error "no stripe info failed"
9137         touch $DIR/$tdir/f6
9138         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9139 }
9140 run_test 65e "directory setstripe defaults"
9141
9142 test_65f() {
9143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9144
9145         test_mkdir $DIR/${tdir}f
9146         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9147                 error "setstripe succeeded" || true
9148 }
9149 run_test 65f "dir setstripe permission (should return error) ==="
9150
9151 test_65g() {
9152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9153
9154         test_mkdir $DIR/$tdir
9155         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9156
9157         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9158                 error "setstripe -S failed"
9159         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9160         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9161                 error "delete default stripe failed"
9162 }
9163 run_test 65g "directory setstripe -d"
9164
9165 test_65h() {
9166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9167
9168         test_mkdir $DIR/$tdir
9169         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9170
9171         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9172                 error "setstripe -S failed"
9173         test_mkdir $DIR/$tdir/dd1
9174         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9175                 error "stripe info inherit failed"
9176 }
9177 run_test 65h "directory stripe info inherit ===================="
9178
9179 test_65i() {
9180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9181
9182         save_layout_restore_at_exit $MOUNT
9183
9184         # bug6367: set non-default striping on root directory
9185         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9186
9187         # bug12836: getstripe on -1 default directory striping
9188         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9189
9190         # bug12836: getstripe -v on -1 default directory striping
9191         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9192
9193         # bug12836: new find on -1 default directory striping
9194         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9195 }
9196 run_test 65i "various tests to set root directory striping"
9197
9198 test_65j() { # bug6367
9199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9200
9201         sync; sleep 1
9202
9203         # if we aren't already remounting for each test, do so for this test
9204         if [ "$I_MOUNTED" = "yes" ]; then
9205                 cleanup || error "failed to unmount"
9206                 setup
9207         fi
9208
9209         save_layout_restore_at_exit $MOUNT
9210
9211         $LFS setstripe -d $MOUNT || error "setstripe failed"
9212 }
9213 run_test 65j "set default striping on root directory (bug 6367)="
9214
9215 cleanup_65k() {
9216         rm -rf $DIR/$tdir
9217         wait_delete_completed
9218         do_facet $SINGLEMDS "lctl set_param -n \
9219                 osp.$ost*MDT0000.max_create_count=$max_count"
9220         do_facet $SINGLEMDS "lctl set_param -n \
9221                 osp.$ost*MDT0000.create_count=$count"
9222         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9223         echo $INACTIVE_OSC "is Activate"
9224
9225         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9226 }
9227
9228 test_65k() { # bug11679
9229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9230         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9231         remote_mds_nodsh && skip "remote MDS with nodsh"
9232
9233         local disable_precreate=true
9234         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9235                 disable_precreate=false
9236
9237         echo "Check OST status: "
9238         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9239                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9240
9241         for OSC in $MDS_OSCS; do
9242                 echo $OSC "is active"
9243                 do_facet $SINGLEMDS lctl --device %$OSC activate
9244         done
9245
9246         for INACTIVE_OSC in $MDS_OSCS; do
9247                 local ost=$(osc_to_ost $INACTIVE_OSC)
9248                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9249                                lov.*md*.target_obd |
9250                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9251
9252                 mkdir -p $DIR/$tdir
9253                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9254                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9255
9256                 echo "Deactivate: " $INACTIVE_OSC
9257                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9258
9259                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9260                               osp.$ost*MDT0000.create_count")
9261                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9262                                   osp.$ost*MDT0000.max_create_count")
9263                 $disable_precreate &&
9264                         do_facet $SINGLEMDS "lctl set_param -n \
9265                                 osp.$ost*MDT0000.max_create_count=0"
9266
9267                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9268                         [ -f $DIR/$tdir/$idx ] && continue
9269                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9270                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9271                                 { cleanup_65k;
9272                                   error "setstripe $idx should succeed"; }
9273                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9274                 done
9275                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9276                 rmdir $DIR/$tdir
9277
9278                 do_facet $SINGLEMDS "lctl set_param -n \
9279                         osp.$ost*MDT0000.max_create_count=$max_count"
9280                 do_facet $SINGLEMDS "lctl set_param -n \
9281                         osp.$ost*MDT0000.create_count=$count"
9282                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9283                 echo $INACTIVE_OSC "is Activate"
9284
9285                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9286         done
9287 }
9288 run_test 65k "validate manual striping works properly with deactivated OSCs"
9289
9290 test_65l() { # bug 12836
9291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9292
9293         test_mkdir -p $DIR/$tdir/test_dir
9294         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9295         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9296 }
9297 run_test 65l "lfs find on -1 stripe dir ========================"
9298
9299 test_65m() {
9300         local layout=$(save_layout $MOUNT)
9301         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9302                 restore_layout $MOUNT $layout
9303                 error "setstripe should fail by non-root users"
9304         }
9305         true
9306 }
9307 run_test 65m "normal user can't set filesystem default stripe"
9308
9309 test_65n() {
9310         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9311         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9312                 skip "Need MDS version at least 2.12.50"
9313         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9314
9315         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9316         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9317         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9318
9319         save_layout_restore_at_exit $MOUNT
9320
9321         # new subdirectory under root directory should not inherit
9322         # the default layout from root
9323         local dir1=$MOUNT/$tdir-1
9324         mkdir $dir1 || error "mkdir $dir1 failed"
9325         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9326                 error "$dir1 shouldn't have LOV EA"
9327
9328         # delete the default layout on root directory
9329         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9330
9331         local dir2=$MOUNT/$tdir-2
9332         mkdir $dir2 || error "mkdir $dir2 failed"
9333         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9334                 error "$dir2 shouldn't have LOV EA"
9335
9336         # set a new striping pattern on root directory
9337         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9338         local new_def_stripe_size=$((def_stripe_size * 2))
9339         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9340                 error "set stripe size on $MOUNT failed"
9341
9342         # new file created in $dir2 should inherit the new stripe size from
9343         # the filesystem default
9344         local file2=$dir2/$tfile-2
9345         touch $file2 || error "touch $file2 failed"
9346
9347         local file2_stripe_size=$($LFS getstripe -S $file2)
9348         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9349         {
9350                 echo "file2_stripe_size: '$file2_stripe_size'"
9351                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9352                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9353         }
9354
9355         local dir3=$MOUNT/$tdir-3
9356         mkdir $dir3 || error "mkdir $dir3 failed"
9357         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9358         # the root layout, which is the actual default layout that will be used
9359         # when new files are created in $dir3.
9360         local dir3_layout=$(get_layout_param $dir3)
9361         local root_dir_layout=$(get_layout_param $MOUNT)
9362         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9363         {
9364                 echo "dir3_layout: '$dir3_layout'"
9365                 echo "root_dir_layout: '$root_dir_layout'"
9366                 error "$dir3 should show the default layout from $MOUNT"
9367         }
9368
9369         # set OST pool on root directory
9370         local pool=$TESTNAME
9371         pool_add $pool || error "add $pool failed"
9372         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9373                 error "add targets to $pool failed"
9374
9375         $LFS setstripe -p $pool $MOUNT ||
9376                 error "set OST pool on $MOUNT failed"
9377
9378         # new file created in $dir3 should inherit the pool from
9379         # the filesystem default
9380         local file3=$dir3/$tfile-3
9381         touch $file3 || error "touch $file3 failed"
9382
9383         local file3_pool=$($LFS getstripe -p $file3)
9384         [[ "$file3_pool" = "$pool" ]] ||
9385                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9386
9387         local dir4=$MOUNT/$tdir-4
9388         mkdir $dir4 || error "mkdir $dir4 failed"
9389         local dir4_layout=$(get_layout_param $dir4)
9390         root_dir_layout=$(get_layout_param $MOUNT)
9391         echo "$LFS getstripe -d $dir4"
9392         $LFS getstripe -d $dir4
9393         echo "$LFS getstripe -d $MOUNT"
9394         $LFS getstripe -d $MOUNT
9395         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9396         {
9397                 echo "dir4_layout: '$dir4_layout'"
9398                 echo "root_dir_layout: '$root_dir_layout'"
9399                 error "$dir4 should show the default layout from $MOUNT"
9400         }
9401
9402         # new file created in $dir4 should inherit the pool from
9403         # the filesystem default
9404         local file4=$dir4/$tfile-4
9405         touch $file4 || error "touch $file4 failed"
9406
9407         local file4_pool=$($LFS getstripe -p $file4)
9408         [[ "$file4_pool" = "$pool" ]] ||
9409                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9410
9411         # new subdirectory under non-root directory should inherit
9412         # the default layout from its parent directory
9413         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9414                 error "set directory layout on $dir4 failed"
9415
9416         local dir5=$dir4/$tdir-5
9417         mkdir $dir5 || error "mkdir $dir5 failed"
9418
9419         dir4_layout=$(get_layout_param $dir4)
9420         local dir5_layout=$(get_layout_param $dir5)
9421         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9422         {
9423                 echo "dir4_layout: '$dir4_layout'"
9424                 echo "dir5_layout: '$dir5_layout'"
9425                 error "$dir5 should inherit the default layout from $dir4"
9426         }
9427
9428         # though subdir under ROOT doesn't inherit default layout, but
9429         # its sub dir/file should be created with default layout.
9430         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9431         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9432                 skip "Need MDS version at least 2.12.59"
9433
9434         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9435         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9436         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9437
9438         if [ $default_lmv_hash == "none" ]; then
9439                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9440         else
9441                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9442                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9443         fi
9444
9445         $LFS setdirstripe -D -c 2 $MOUNT ||
9446                 error "setdirstripe -D -c 2 failed"
9447         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9448         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9449         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9450
9451         # $dir4 layout includes pool
9452         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9453         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9454                 error "pool lost on setstripe"
9455         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9456         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9457                 error "pool lost on compound layout setstripe"
9458 }
9459 run_test 65n "don't inherit default layout from root for new subdirectories"
9460
9461 # bug 2543 - update blocks count on client
9462 test_66() {
9463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9464
9465         COUNT=${COUNT:-8}
9466         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9467         sync; sync_all_data; sync; sync_all_data
9468         cancel_lru_locks osc
9469         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9470         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9471 }
9472 run_test 66 "update inode blocks count on client ==============="
9473
9474 meminfo() {
9475         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9476 }
9477
9478 swap_used() {
9479         swapon -s | awk '($1 == "'$1'") { print $4 }'
9480 }
9481
9482 # bug5265, obdfilter oa2dentry return -ENOENT
9483 # #define OBD_FAIL_SRV_ENOENT 0x217
9484 test_69() {
9485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9486         remote_ost_nodsh && skip "remote OST with nodsh"
9487
9488         f="$DIR/$tfile"
9489         $LFS setstripe -c 1 -i 0 $f
9490
9491         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9492
9493         do_facet ost1 lctl set_param fail_loc=0x217
9494         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9495         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9496
9497         do_facet ost1 lctl set_param fail_loc=0
9498         $DIRECTIO write $f 0 2 || error "write error"
9499
9500         cancel_lru_locks osc
9501         $DIRECTIO read $f 0 1 || error "read error"
9502
9503         do_facet ost1 lctl set_param fail_loc=0x217
9504         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9505
9506         do_facet ost1 lctl set_param fail_loc=0
9507         rm -f $f
9508 }
9509 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9510
9511 test_71() {
9512         test_mkdir $DIR/$tdir
9513         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9514         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9515 }
9516 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9517
9518 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9520         [ "$RUNAS_ID" = "$UID" ] &&
9521                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9522         # Check that testing environment is properly set up. Skip if not
9523         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9524                 skip_env "User $RUNAS_ID does not exist - skipping"
9525
9526         touch $DIR/$tfile
9527         chmod 777 $DIR/$tfile
9528         chmod ug+s $DIR/$tfile
9529         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9530                 error "$RUNAS dd $DIR/$tfile failed"
9531         # See if we are still setuid/sgid
9532         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9533                 error "S/gid is not dropped on write"
9534         # Now test that MDS is updated too
9535         cancel_lru_locks mdc
9536         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9537                 error "S/gid is not dropped on MDS"
9538         rm -f $DIR/$tfile
9539 }
9540 run_test 72a "Test that remove suid works properly (bug5695) ===="
9541
9542 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9543         local perm
9544
9545         [ "$RUNAS_ID" = "$UID" ] &&
9546                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9547         [ "$RUNAS_ID" -eq 0 ] &&
9548                 skip_env "RUNAS_ID = 0 -- skipping"
9549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9550         # Check that testing environment is properly set up. Skip if not
9551         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9552                 skip_env "User $RUNAS_ID does not exist - skipping"
9553
9554         touch $DIR/${tfile}-f{g,u}
9555         test_mkdir $DIR/${tfile}-dg
9556         test_mkdir $DIR/${tfile}-du
9557         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9558         chmod g+s $DIR/${tfile}-{f,d}g
9559         chmod u+s $DIR/${tfile}-{f,d}u
9560         for perm in 777 2777 4777; do
9561                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9562                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9563                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9564                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9565         done
9566         true
9567 }
9568 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9569
9570 # bug 3462 - multiple simultaneous MDC requests
9571 test_73() {
9572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9573
9574         test_mkdir $DIR/d73-1
9575         test_mkdir $DIR/d73-2
9576         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9577         pid1=$!
9578
9579         lctl set_param fail_loc=0x80000129
9580         $MULTIOP $DIR/d73-1/f73-2 Oc &
9581         sleep 1
9582         lctl set_param fail_loc=0
9583
9584         $MULTIOP $DIR/d73-2/f73-3 Oc &
9585         pid3=$!
9586
9587         kill -USR1 $pid1
9588         wait $pid1 || return 1
9589
9590         sleep 25
9591
9592         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9593         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9594         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9595
9596         rm -rf $DIR/d73-*
9597 }
9598 run_test 73 "multiple MDC requests (should not deadlock)"
9599
9600 test_74a() { # bug 6149, 6184
9601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9602
9603         touch $DIR/f74a
9604         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9605         #
9606         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9607         # will spin in a tight reconnection loop
9608         $LCTL set_param fail_loc=0x8000030e
9609         # get any lock that won't be difficult - lookup works.
9610         ls $DIR/f74a
9611         $LCTL set_param fail_loc=0
9612         rm -f $DIR/f74a
9613         true
9614 }
9615 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9616
9617 test_74b() { # bug 13310
9618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9619
9620         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9621         #
9622         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9623         # will spin in a tight reconnection loop
9624         $LCTL set_param fail_loc=0x8000030e
9625         # get a "difficult" lock
9626         touch $DIR/f74b
9627         $LCTL set_param fail_loc=0
9628         rm -f $DIR/f74b
9629         true
9630 }
9631 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9632
9633 test_74c() {
9634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9635
9636         #define OBD_FAIL_LDLM_NEW_LOCK
9637         $LCTL set_param fail_loc=0x319
9638         touch $DIR/$tfile && error "touch successful"
9639         $LCTL set_param fail_loc=0
9640         true
9641 }
9642 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9643
9644 slab_lic=/sys/kernel/slab/lustre_inode_cache
9645 num_objects() {
9646         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9647         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9648                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9649 }
9650
9651 test_76a() { # Now for b=20433, added originally in b=1443
9652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9653
9654         cancel_lru_locks osc
9655         # there may be some slab objects cached per core
9656         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9657         local before=$(num_objects)
9658         local count=$((512 * cpus))
9659         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9660         local margin=$((count / 10))
9661         if [[ -f $slab_lic/aliases ]]; then
9662                 local aliases=$(cat $slab_lic/aliases)
9663                 (( aliases > 0 )) && margin=$((margin * aliases))
9664         fi
9665
9666         echo "before slab objects: $before"
9667         for i in $(seq $count); do
9668                 touch $DIR/$tfile
9669                 rm -f $DIR/$tfile
9670         done
9671         cancel_lru_locks osc
9672         local after=$(num_objects)
9673         echo "created: $count, after slab objects: $after"
9674         # shared slab counts are not very accurate, allow significant margin
9675         # the main goal is that the cache growth is not permanently > $count
9676         while (( after > before + margin )); do
9677                 sleep 1
9678                 after=$(num_objects)
9679                 wait=$((wait + 1))
9680                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9681                 if (( wait > 60 )); then
9682                         error "inode slab grew from $before+$margin to $after"
9683                 fi
9684         done
9685 }
9686 run_test 76a "confirm clients recycle inodes properly ===="
9687
9688 test_76b() {
9689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9690         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9691
9692         local count=512
9693         local before=$(num_objects)
9694
9695         for i in $(seq $count); do
9696                 mkdir $DIR/$tdir
9697                 rmdir $DIR/$tdir
9698         done
9699
9700         local after=$(num_objects)
9701         local wait=0
9702
9703         while (( after > before )); do
9704                 sleep 1
9705                 after=$(num_objects)
9706                 wait=$((wait + 1))
9707                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9708                 if (( wait > 60 )); then
9709                         error "inode slab grew from $before to $after"
9710                 fi
9711         done
9712
9713         echo "slab objects before: $before, after: $after"
9714 }
9715 run_test 76b "confirm clients recycle directory inodes properly ===="
9716
9717 export ORIG_CSUM=""
9718 set_checksums()
9719 {
9720         # Note: in sptlrpc modes which enable its own bulk checksum, the
9721         # original crc32_le bulk checksum will be automatically disabled,
9722         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9723         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9724         # In this case set_checksums() will not be no-op, because sptlrpc
9725         # bulk checksum will be enabled all through the test.
9726
9727         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9728         lctl set_param -n osc.*.checksums $1
9729         return 0
9730 }
9731
9732 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9733                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9734 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9735                              tr -d [] | head -n1)}
9736 set_checksum_type()
9737 {
9738         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9739         rc=$?
9740         log "set checksum type to $1, rc = $rc"
9741         return $rc
9742 }
9743
9744 get_osc_checksum_type()
9745 {
9746         # arugment 1: OST name, like OST0000
9747         ost=$1
9748         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9749                         sed 's/.*\[\(.*\)\].*/\1/g')
9750         rc=$?
9751         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9752         echo $checksum_type
9753 }
9754
9755 F77_TMP=$TMP/f77-temp
9756 F77SZ=8
9757 setup_f77() {
9758         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9759                 error "error writing to $F77_TMP"
9760 }
9761
9762 test_77a() { # bug 10889
9763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9764         $GSS && skip_env "could not run with gss"
9765
9766         [ ! -f $F77_TMP ] && setup_f77
9767         set_checksums 1
9768         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9769         set_checksums 0
9770         rm -f $DIR/$tfile
9771 }
9772 run_test 77a "normal checksum read/write operation"
9773
9774 test_77b() { # bug 10889
9775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9776         $GSS && skip_env "could not run with gss"
9777
9778         [ ! -f $F77_TMP ] && setup_f77
9779         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9780         $LCTL set_param fail_loc=0x80000409
9781         set_checksums 1
9782
9783         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9784                 error "dd error: $?"
9785         $LCTL set_param fail_loc=0
9786
9787         for algo in $CKSUM_TYPES; do
9788                 cancel_lru_locks osc
9789                 set_checksum_type $algo
9790                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9791                 $LCTL set_param fail_loc=0x80000408
9792                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9793                 $LCTL set_param fail_loc=0
9794         done
9795         set_checksums 0
9796         set_checksum_type $ORIG_CSUM_TYPE
9797         rm -f $DIR/$tfile
9798 }
9799 run_test 77b "checksum error on client write, read"
9800
9801 cleanup_77c() {
9802         trap 0
9803         set_checksums 0
9804         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9805         $check_ost &&
9806                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9807         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9808         $check_ost && [ -n "$ost_file_prefix" ] &&
9809                 do_facet ost1 rm -f ${ost_file_prefix}\*
9810 }
9811
9812 test_77c() {
9813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9814         $GSS && skip_env "could not run with gss"
9815         remote_ost_nodsh && skip "remote OST with nodsh"
9816
9817         local bad1
9818         local osc_file_prefix
9819         local osc_file
9820         local check_ost=false
9821         local ost_file_prefix
9822         local ost_file
9823         local orig_cksum
9824         local dump_cksum
9825         local fid
9826
9827         # ensure corruption will occur on first OSS/OST
9828         $LFS setstripe -i 0 $DIR/$tfile
9829
9830         [ ! -f $F77_TMP ] && setup_f77
9831         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9832                 error "dd write error: $?"
9833         fid=$($LFS path2fid $DIR/$tfile)
9834
9835         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9836         then
9837                 check_ost=true
9838                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9839                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9840         else
9841                 echo "OSS do not support bulk pages dump upon error"
9842         fi
9843
9844         osc_file_prefix=$($LCTL get_param -n debug_path)
9845         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9846
9847         trap cleanup_77c EXIT
9848
9849         set_checksums 1
9850         # enable bulk pages dump upon error on Client
9851         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9852         # enable bulk pages dump upon error on OSS
9853         $check_ost &&
9854                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9855
9856         # flush Client cache to allow next read to reach OSS
9857         cancel_lru_locks osc
9858
9859         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9860         $LCTL set_param fail_loc=0x80000408
9861         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9862         $LCTL set_param fail_loc=0
9863
9864         rm -f $DIR/$tfile
9865
9866         # check cksum dump on Client
9867         osc_file=$(ls ${osc_file_prefix}*)
9868         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9869         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9870         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9871         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9872         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9873                      cksum)
9874         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9875         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9876                 error "dump content does not match on Client"
9877
9878         $check_ost || skip "No need to check cksum dump on OSS"
9879
9880         # check cksum dump on OSS
9881         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9882         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9883         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9884         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9885         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9886                 error "dump content does not match on OSS"
9887
9888         cleanup_77c
9889 }
9890 run_test 77c "checksum error on client read with debug"
9891
9892 test_77d() { # bug 10889
9893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9894         $GSS && skip_env "could not run with gss"
9895
9896         stack_trap "rm -f $DIR/$tfile"
9897         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9898         $LCTL set_param fail_loc=0x80000409
9899         set_checksums 1
9900         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9901                 error "direct write: rc=$?"
9902         $LCTL set_param fail_loc=0
9903         set_checksums 0
9904
9905         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9906         $LCTL set_param fail_loc=0x80000408
9907         set_checksums 1
9908         cancel_lru_locks osc
9909         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9910                 error "direct read: rc=$?"
9911         $LCTL set_param fail_loc=0
9912         set_checksums 0
9913 }
9914 run_test 77d "checksum error on OST direct write, read"
9915
9916 test_77f() { # bug 10889
9917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9918         $GSS && skip_env "could not run with gss"
9919
9920         set_checksums 1
9921         stack_trap "rm -f $DIR/$tfile"
9922         for algo in $CKSUM_TYPES; do
9923                 cancel_lru_locks osc
9924                 set_checksum_type $algo
9925                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9926                 $LCTL set_param fail_loc=0x409
9927                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9928                         error "direct write succeeded"
9929                 $LCTL set_param fail_loc=0
9930         done
9931         set_checksum_type $ORIG_CSUM_TYPE
9932         set_checksums 0
9933 }
9934 run_test 77f "repeat checksum error on write (expect error)"
9935
9936 test_77g() { # bug 10889
9937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9938         $GSS && skip_env "could not run with gss"
9939         remote_ost_nodsh && skip "remote OST with nodsh"
9940
9941         [ ! -f $F77_TMP ] && setup_f77
9942
9943         local file=$DIR/$tfile
9944         stack_trap "rm -f $file" EXIT
9945
9946         $LFS setstripe -c 1 -i 0 $file
9947         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9948         do_facet ost1 lctl set_param fail_loc=0x8000021a
9949         set_checksums 1
9950         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9951                 error "write error: rc=$?"
9952         do_facet ost1 lctl set_param fail_loc=0
9953         set_checksums 0
9954
9955         cancel_lru_locks osc
9956         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9957         do_facet ost1 lctl set_param fail_loc=0x8000021b
9958         set_checksums 1
9959         cmp $F77_TMP $file || error "file compare failed"
9960         do_facet ost1 lctl set_param fail_loc=0
9961         set_checksums 0
9962 }
9963 run_test 77g "checksum error on OST write, read"
9964
9965 test_77k() { # LU-10906
9966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9967         $GSS && skip_env "could not run with gss"
9968
9969         local cksum_param="osc.$FSNAME*.checksums"
9970         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9971         local checksum
9972         local i
9973
9974         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9975         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9976         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9977
9978         for i in 0 1; do
9979                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9980                         error "failed to set checksum=$i on MGS"
9981                 wait_update $HOSTNAME "$get_checksum" $i
9982                 #remount
9983                 echo "remount client, checksum should be $i"
9984                 remount_client $MOUNT || error "failed to remount client"
9985                 checksum=$(eval $get_checksum)
9986                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9987         done
9988         # remove persistent param to avoid races with checksum mountopt below
9989         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9990                 error "failed to delete checksum on MGS"
9991
9992         for opt in "checksum" "nochecksum"; do
9993                 #remount with mount option
9994                 echo "remount client with option $opt, checksum should be $i"
9995                 umount_client $MOUNT || error "failed to umount client"
9996                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9997                         error "failed to mount client with option '$opt'"
9998                 checksum=$(eval $get_checksum)
9999                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10000                 i=$((i - 1))
10001         done
10002
10003         remount_client $MOUNT || error "failed to remount client"
10004 }
10005 run_test 77k "enable/disable checksum correctly"
10006
10007 test_77l() {
10008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10009         $GSS && skip_env "could not run with gss"
10010
10011         set_checksums 1
10012         stack_trap "set_checksums $ORIG_CSUM" EXIT
10013         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10014
10015         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10016
10017         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10018         for algo in $CKSUM_TYPES; do
10019                 set_checksum_type $algo || error "fail to set checksum type $algo"
10020                 osc_algo=$(get_osc_checksum_type OST0000)
10021                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10022
10023                 # no locks, no reqs to let the connection idle
10024                 cancel_lru_locks osc
10025                 lru_resize_disable osc
10026                 wait_osc_import_state client ost1 IDLE
10027
10028                 # ensure ost1 is connected
10029                 stat $DIR/$tfile >/dev/null || error "can't stat"
10030                 wait_osc_import_state client ost1 FULL
10031
10032                 osc_algo=$(get_osc_checksum_type OST0000)
10033                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10034         done
10035         return 0
10036 }
10037 run_test 77l "preferred checksum type is remembered after reconnected"
10038
10039 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10040 rm -f $F77_TMP
10041 unset F77_TMP
10042
10043 test_77m() {
10044         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10045                 skip "Need at least version 2.14.52"
10046         local param=checksum_speed
10047
10048         $LCTL get_param $param || error "reading $param failed"
10049
10050         csum_speeds=$($LCTL get_param -n $param)
10051
10052         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10053                 error "known checksum types are missing"
10054 }
10055 run_test 77m "Verify checksum_speed is correctly read"
10056
10057 check_filefrag_77n() {
10058         local nr_ext=0
10059         local starts=()
10060         local ends=()
10061
10062         while read extidx a b start end rest; do
10063                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10064                         nr_ext=$(( $nr_ext + 1 ))
10065                         starts+=( ${start%..} )
10066                         ends+=( ${end%:} )
10067                 fi
10068         done < <( filefrag -sv $1 )
10069
10070         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10071         return 1
10072 }
10073
10074 test_77n() {
10075         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10076
10077         touch $DIR/$tfile
10078         $TRUNCATE $DIR/$tfile 0
10079         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10080         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10081         check_filefrag_77n $DIR/$tfile ||
10082                 skip "$tfile blocks not contiguous around hole"
10083
10084         set_checksums 1
10085         stack_trap "set_checksums $ORIG_CSUM" EXIT
10086         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10087         stack_trap "rm -f $DIR/$tfile"
10088
10089         for algo in $CKSUM_TYPES; do
10090                 if [[ "$algo" =~ ^t10 ]]; then
10091                         set_checksum_type $algo ||
10092                                 error "fail to set checksum type $algo"
10093                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10094                                 error "fail to read $tfile with $algo"
10095                 fi
10096         done
10097         rm -f $DIR/$tfile
10098         return 0
10099 }
10100 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10101
10102 test_77o() {
10103         (( $CLIENT_VERSION >= $(version_code 2.14.54) )) ||
10104                 skip "Need at least version 2.14.54"
10105         local ofd=obdfilter
10106         local mdt=mdt
10107
10108         # print OST checksum_type
10109         echo "$ofd.$FSNAME-*.checksum_type:"
10110         do_nodes $(comma_list $(osts_nodes)) \
10111                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10112
10113         # print MDT checksum_type
10114         echo "$mdt.$FSNAME-*.checksum_type:"
10115         do_nodes $(comma_list $(mdts_nodes)) \
10116                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10117
10118         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10119                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10120
10121         (( $o_count == $OSTCOUNT )) ||
10122                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10123
10124         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10125                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10126
10127         (( $m_count == $MDSCOUNT )) ||
10128                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10129 }
10130 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10131
10132 cleanup_test_78() {
10133         trap 0
10134         rm -f $DIR/$tfile
10135 }
10136
10137 test_78() { # bug 10901
10138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10139         remote_ost || skip_env "local OST"
10140
10141         NSEQ=5
10142         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10143         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10144         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10145         echo "MemTotal: $MEMTOTAL"
10146
10147         # reserve 256MB of memory for the kernel and other running processes,
10148         # and then take 1/2 of the remaining memory for the read/write buffers.
10149         if [ $MEMTOTAL -gt 512 ] ;then
10150                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10151         else
10152                 # for those poor memory-starved high-end clusters...
10153                 MEMTOTAL=$((MEMTOTAL / 2))
10154         fi
10155         echo "Mem to use for directio: $MEMTOTAL"
10156
10157         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10158         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10159         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10160         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10161                 head -n1)
10162         echo "Smallest OST: $SMALLESTOST"
10163         [[ $SMALLESTOST -lt 10240 ]] &&
10164                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10165
10166         trap cleanup_test_78 EXIT
10167
10168         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10169                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10170
10171         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10172         echo "File size: $F78SIZE"
10173         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10174         for i in $(seq 1 $NSEQ); do
10175                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10176                 echo directIO rdwr round $i of $NSEQ
10177                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10178         done
10179
10180         cleanup_test_78
10181 }
10182 run_test 78 "handle large O_DIRECT writes correctly ============"
10183
10184 test_79() { # bug 12743
10185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10186
10187         wait_delete_completed
10188
10189         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10190         BKFREE=$(calc_osc_kbytes kbytesfree)
10191         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10192
10193         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10194         DFTOTAL=`echo $STRING | cut -d, -f1`
10195         DFUSED=`echo $STRING  | cut -d, -f2`
10196         DFAVAIL=`echo $STRING | cut -d, -f3`
10197         DFFREE=$(($DFTOTAL - $DFUSED))
10198
10199         ALLOWANCE=$((64 * $OSTCOUNT))
10200
10201         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10202            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10203                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10204         fi
10205         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10206            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10207                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10208         fi
10209         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10210            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10211                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10212         fi
10213 }
10214 run_test 79 "df report consistency check ======================="
10215
10216 test_80() { # bug 10718
10217         remote_ost_nodsh && skip "remote OST with nodsh"
10218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10219
10220         # relax strong synchronous semantics for slow backends like ZFS
10221         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10222                 local soc="obdfilter.*.sync_lock_cancel"
10223                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10224
10225                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10226                 if [ -z "$save" ]; then
10227                         soc="obdfilter.*.sync_on_lock_cancel"
10228                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10229                 fi
10230
10231                 if [ "$save" != "never" ]; then
10232                         local hosts=$(comma_list $(osts_nodes))
10233
10234                         do_nodes $hosts $LCTL set_param $soc=never
10235                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10236                 fi
10237         fi
10238
10239         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10240         sync; sleep 1; sync
10241         local before=$(date +%s)
10242         cancel_lru_locks osc
10243         local after=$(date +%s)
10244         local diff=$((after - before))
10245         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10246
10247         rm -f $DIR/$tfile
10248 }
10249 run_test 80 "Page eviction is equally fast at high offsets too"
10250
10251 test_81a() { # LU-456
10252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10253         remote_ost_nodsh && skip "remote OST with nodsh"
10254
10255         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10256         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10257         do_facet ost1 lctl set_param fail_loc=0x80000228
10258
10259         # write should trigger a retry and success
10260         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10261         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10262         RC=$?
10263         if [ $RC -ne 0 ] ; then
10264                 error "write should success, but failed for $RC"
10265         fi
10266 }
10267 run_test 81a "OST should retry write when get -ENOSPC ==============="
10268
10269 test_81b() { # LU-456
10270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10271         remote_ost_nodsh && skip "remote OST with nodsh"
10272
10273         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10274         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10275         do_facet ost1 lctl set_param fail_loc=0x228
10276
10277         # write should retry several times and return -ENOSPC finally
10278         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10279         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10280         RC=$?
10281         ENOSPC=28
10282         if [ $RC -ne $ENOSPC ] ; then
10283                 error "dd should fail for -ENOSPC, but succeed."
10284         fi
10285 }
10286 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10287
10288 test_99() {
10289         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10290
10291         test_mkdir $DIR/$tdir.cvsroot
10292         chown $RUNAS_ID $DIR/$tdir.cvsroot
10293
10294         cd $TMP
10295         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10296
10297         cd /etc/init.d
10298         # some versions of cvs import exit(1) when asked to import links or
10299         # files they can't read.  ignore those files.
10300         local toignore=$(find . -type l -printf '-I %f\n' -o \
10301                          ! -perm /4 -printf '-I %f\n')
10302         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10303                 $tdir.reposname vtag rtag
10304
10305         cd $DIR
10306         test_mkdir $DIR/$tdir.reposname
10307         chown $RUNAS_ID $DIR/$tdir.reposname
10308         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10309
10310         cd $DIR/$tdir.reposname
10311         $RUNAS touch foo99
10312         $RUNAS cvs add -m 'addmsg' foo99
10313         $RUNAS cvs update
10314         $RUNAS cvs commit -m 'nomsg' foo99
10315         rm -fr $DIR/$tdir.cvsroot
10316 }
10317 run_test 99 "cvs strange file/directory operations"
10318
10319 test_100() {
10320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10321         [[ "$NETTYPE" =~ tcp ]] ||
10322                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10323         remote_ost_nodsh && skip "remote OST with nodsh"
10324         remote_mds_nodsh && skip "remote MDS with nodsh"
10325         remote_servers ||
10326                 skip "useless for local single node setup"
10327
10328         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10329                 [ "$PROT" != "tcp" ] && continue
10330                 RPORT=$(echo $REMOTE | cut -d: -f2)
10331                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10332
10333                 rc=0
10334                 LPORT=`echo $LOCAL | cut -d: -f2`
10335                 if [ $LPORT -ge 1024 ]; then
10336                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10337                         netstat -tna
10338                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10339                 fi
10340         done
10341         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10342 }
10343 run_test 100 "check local port using privileged port ==========="
10344
10345 function get_named_value()
10346 {
10347     local tag=$1
10348
10349     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10350 }
10351
10352 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10353                    awk '/^max_cached_mb/ { print $2 }')
10354
10355 cleanup_101a() {
10356         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10357         trap 0
10358 }
10359
10360 test_101a() {
10361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10362
10363         local s
10364         local discard
10365         local nreads=10000
10366         local cache_limit=32
10367
10368         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10369         trap cleanup_101a EXIT
10370         $LCTL set_param -n llite.*.read_ahead_stats=0
10371         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10372
10373         #
10374         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10375         #
10376         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10377         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10378
10379         discard=0
10380         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10381                    get_named_value 'read.but.discarded'); do
10382                         discard=$(($discard + $s))
10383         done
10384         cleanup_101a
10385
10386         $LCTL get_param osc.*-osc*.rpc_stats
10387         $LCTL get_param llite.*.read_ahead_stats
10388
10389         # Discard is generally zero, but sometimes a few random reads line up
10390         # and trigger larger readahead, which is wasted & leads to discards.
10391         if [[ $(($discard)) -gt $nreads ]]; then
10392                 error "too many ($discard) discarded pages"
10393         fi
10394         rm -f $DIR/$tfile || true
10395 }
10396 run_test 101a "check read-ahead for random reads"
10397
10398 setup_test101bc() {
10399         test_mkdir $DIR/$tdir
10400         local ssize=$1
10401         local FILE_LENGTH=$2
10402         STRIPE_OFFSET=0
10403
10404         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10405
10406         local list=$(comma_list $(osts_nodes))
10407         set_osd_param $list '' read_cache_enable 0
10408         set_osd_param $list '' writethrough_cache_enable 0
10409
10410         trap cleanup_test101bc EXIT
10411         # prepare the read-ahead file
10412         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10413
10414         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10415                                 count=$FILE_SIZE_MB 2> /dev/null
10416
10417 }
10418
10419 cleanup_test101bc() {
10420         trap 0
10421         rm -rf $DIR/$tdir
10422         rm -f $DIR/$tfile
10423
10424         local list=$(comma_list $(osts_nodes))
10425         set_osd_param $list '' read_cache_enable 1
10426         set_osd_param $list '' writethrough_cache_enable 1
10427 }
10428
10429 calc_total() {
10430         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10431 }
10432
10433 ra_check_101() {
10434         local READ_SIZE=$1
10435         local STRIPE_SIZE=$2
10436         local FILE_LENGTH=$3
10437         local RA_INC=1048576
10438         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10439         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10440                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10441         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10442                   get_named_value 'read.but.discarded' | calc_total)
10443         if [[ $DISCARD -gt $discard_limit ]]; then
10444                 $LCTL get_param llite.*.read_ahead_stats
10445                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10446         else
10447                 echo "Read-ahead success for size ${READ_SIZE}"
10448         fi
10449 }
10450
10451 test_101b() {
10452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10453         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10454
10455         local STRIPE_SIZE=1048576
10456         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10457
10458         if [ $SLOW == "yes" ]; then
10459                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10460         else
10461                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10462         fi
10463
10464         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10465
10466         # prepare the read-ahead file
10467         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10468         cancel_lru_locks osc
10469         for BIDX in 2 4 8 16 32 64 128 256
10470         do
10471                 local BSIZE=$((BIDX*4096))
10472                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10473                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10474                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10475                 $LCTL set_param -n llite.*.read_ahead_stats=0
10476                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10477                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10478                 cancel_lru_locks osc
10479                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10480         done
10481         cleanup_test101bc
10482         true
10483 }
10484 run_test 101b "check stride-io mode read-ahead ================="
10485
10486 test_101c() {
10487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10488
10489         local STRIPE_SIZE=1048576
10490         local FILE_LENGTH=$((STRIPE_SIZE*100))
10491         local nreads=10000
10492         local rsize=65536
10493         local osc_rpc_stats
10494
10495         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10496
10497         cancel_lru_locks osc
10498         $LCTL set_param osc.*.rpc_stats=0
10499         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10500         $LCTL get_param osc.*.rpc_stats
10501         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10502                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10503                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10504                 local size
10505
10506                 if [ $lines -le 20 ]; then
10507                         echo "continue debug"
10508                         continue
10509                 fi
10510                 for size in 1 2 4 8; do
10511                         local rpc=$(echo "$stats" |
10512                                     awk '($1 == "'$size':") {print $2; exit; }')
10513                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10514                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10515                 done
10516                 echo "$osc_rpc_stats check passed!"
10517         done
10518         cleanup_test101bc
10519         true
10520 }
10521 run_test 101c "check stripe_size aligned read-ahead"
10522
10523 test_101d() {
10524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10525
10526         local file=$DIR/$tfile
10527         local sz_MB=${FILESIZE_101d:-80}
10528         local ra_MB=${READAHEAD_MB:-40}
10529
10530         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10531         [ $free_MB -lt $sz_MB ] &&
10532                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10533
10534         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10535         $LFS setstripe -c -1 $file || error "setstripe failed"
10536
10537         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10538         echo Cancel LRU locks on lustre client to flush the client cache
10539         cancel_lru_locks osc
10540
10541         echo Disable read-ahead
10542         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10543         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10544         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10545         $LCTL get_param -n llite.*.max_read_ahead_mb
10546
10547         echo "Reading the test file $file with read-ahead disabled"
10548         local sz_KB=$((sz_MB * 1024 / 4))
10549         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10550         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10551         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10552                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10553
10554         echo "Cancel LRU locks on lustre client to flush the client cache"
10555         cancel_lru_locks osc
10556         echo Enable read-ahead with ${ra_MB}MB
10557         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10558
10559         echo "Reading the test file $file with read-ahead enabled"
10560         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10561                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10562
10563         echo "read-ahead disabled time read $raOFF"
10564         echo "read-ahead enabled time read $raON"
10565
10566         rm -f $file
10567         wait_delete_completed
10568
10569         # use awk for this check instead of bash because it handles decimals
10570         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10571                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10572 }
10573 run_test 101d "file read with and without read-ahead enabled"
10574
10575 test_101e() {
10576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10577
10578         local file=$DIR/$tfile
10579         local size_KB=500  #KB
10580         local count=100
10581         local bsize=1024
10582
10583         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10584         local need_KB=$((count * size_KB))
10585         [[ $free_KB -le $need_KB ]] &&
10586                 skip_env "Need free space $need_KB, have $free_KB"
10587
10588         echo "Creating $count ${size_KB}K test files"
10589         for ((i = 0; i < $count; i++)); do
10590                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10591         done
10592
10593         echo "Cancel LRU locks on lustre client to flush the client cache"
10594         cancel_lru_locks $OSC
10595
10596         echo "Reset readahead stats"
10597         $LCTL set_param -n llite.*.read_ahead_stats=0
10598
10599         for ((i = 0; i < $count; i++)); do
10600                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10601         done
10602
10603         $LCTL get_param llite.*.max_cached_mb
10604         $LCTL get_param llite.*.read_ahead_stats
10605         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10606                      get_named_value 'misses' | calc_total)
10607
10608         for ((i = 0; i < $count; i++)); do
10609                 rm -rf $file.$i 2>/dev/null
10610         done
10611
10612         #10000 means 20% reads are missing in readahead
10613         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10614 }
10615 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10616
10617 test_101f() {
10618         which iozone || skip_env "no iozone installed"
10619
10620         local old_debug=$($LCTL get_param debug)
10621         old_debug=${old_debug#*=}
10622         $LCTL set_param debug="reada mmap"
10623
10624         # create a test file
10625         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10626
10627         echo Cancel LRU locks on lustre client to flush the client cache
10628         cancel_lru_locks osc
10629
10630         echo Reset readahead stats
10631         $LCTL set_param -n llite.*.read_ahead_stats=0
10632
10633         echo mmap read the file with small block size
10634         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10635                 > /dev/null 2>&1
10636
10637         echo checking missing pages
10638         $LCTL get_param llite.*.read_ahead_stats
10639         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10640                         get_named_value 'misses' | calc_total)
10641
10642         $LCTL set_param debug="$old_debug"
10643         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10644         rm -f $DIR/$tfile
10645 }
10646 run_test 101f "check mmap read performance"
10647
10648 test_101g_brw_size_test() {
10649         local mb=$1
10650         local pages=$((mb * 1048576 / PAGE_SIZE))
10651         local file=$DIR/$tfile
10652
10653         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10654                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10655         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10656                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10657                         return 2
10658         done
10659
10660         stack_trap "rm -f $file" EXIT
10661         $LCTL set_param -n osc.*.rpc_stats=0
10662
10663         # 10 RPCs should be enough for the test
10664         local count=10
10665         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10666                 { error "dd write ${mb} MB blocks failed"; return 3; }
10667         cancel_lru_locks osc
10668         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10669                 { error "dd write ${mb} MB blocks failed"; return 4; }
10670
10671         # calculate number of full-sized read and write RPCs
10672         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10673                 sed -n '/pages per rpc/,/^$/p' |
10674                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10675                 END { print reads,writes }'))
10676         # allow one extra full-sized read RPC for async readahead
10677         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10678                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10679         [[ ${rpcs[1]} == $count ]] ||
10680                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10681 }
10682
10683 test_101g() {
10684         remote_ost_nodsh && skip "remote OST with nodsh"
10685
10686         local rpcs
10687         local osts=$(get_facets OST)
10688         local list=$(comma_list $(osts_nodes))
10689         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10690         local brw_size="obdfilter.*.brw_size"
10691
10692         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10693
10694         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10695
10696         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10697                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10698                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10699            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10700                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10701                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10702
10703                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10704                         suffix="M"
10705
10706                 if [[ $orig_mb -lt 16 ]]; then
10707                         save_lustre_params $osts "$brw_size" > $p
10708                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10709                                 error "set 16MB RPC size failed"
10710
10711                         echo "remount client to enable new RPC size"
10712                         remount_client $MOUNT || error "remount_client failed"
10713                 fi
10714
10715                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10716                 # should be able to set brw_size=12, but no rpc_stats for that
10717                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10718         fi
10719
10720         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10721
10722         if [[ $orig_mb -lt 16 ]]; then
10723                 restore_lustre_params < $p
10724                 remount_client $MOUNT || error "remount_client restore failed"
10725         fi
10726
10727         rm -f $p $DIR/$tfile
10728 }
10729 run_test 101g "Big bulk(4/16 MiB) readahead"
10730
10731 test_101h() {
10732         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10733
10734         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10735                 error "dd 70M file failed"
10736         echo Cancel LRU locks on lustre client to flush the client cache
10737         cancel_lru_locks osc
10738
10739         echo "Reset readahead stats"
10740         $LCTL set_param -n llite.*.read_ahead_stats 0
10741
10742         echo "Read 10M of data but cross 64M bundary"
10743         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10744         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10745                      get_named_value 'misses' | calc_total)
10746         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10747         rm -f $p $DIR/$tfile
10748 }
10749 run_test 101h "Readahead should cover current read window"
10750
10751 test_101i() {
10752         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10753                 error "dd 10M file failed"
10754
10755         local max_per_file_mb=$($LCTL get_param -n \
10756                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10757         cancel_lru_locks osc
10758         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10759         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10760                 error "set max_read_ahead_per_file_mb to 1 failed"
10761
10762         echo "Reset readahead stats"
10763         $LCTL set_param llite.*.read_ahead_stats=0
10764
10765         dd if=$DIR/$tfile of=/dev/null bs=2M
10766
10767         $LCTL get_param llite.*.read_ahead_stats
10768         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10769                      awk '/misses/ { print $2 }')
10770         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10771         rm -f $DIR/$tfile
10772 }
10773 run_test 101i "allow current readahead to exceed reservation"
10774
10775 test_101j() {
10776         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10777                 error "setstripe $DIR/$tfile failed"
10778         local file_size=$((1048576 * 16))
10779         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10780         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10781
10782         echo Disable read-ahead
10783         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10784
10785         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10786         for blk in $PAGE_SIZE 1048576 $file_size; do
10787                 cancel_lru_locks osc
10788                 echo "Reset readahead stats"
10789                 $LCTL set_param -n llite.*.read_ahead_stats=0
10790                 local count=$(($file_size / $blk))
10791                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10792                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10793                              get_named_value 'failed.to.fast.read' | calc_total)
10794                 $LCTL get_param -n llite.*.read_ahead_stats
10795                 [ $miss -eq $count ] || error "expected $count got $miss"
10796         done
10797
10798         rm -f $p $DIR/$tfile
10799 }
10800 run_test 101j "A complete read block should be submitted when no RA"
10801
10802 setup_test102() {
10803         test_mkdir $DIR/$tdir
10804         chown $RUNAS_ID $DIR/$tdir
10805         STRIPE_SIZE=65536
10806         STRIPE_OFFSET=1
10807         STRIPE_COUNT=$OSTCOUNT
10808         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10809
10810         trap cleanup_test102 EXIT
10811         cd $DIR
10812         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10813         cd $DIR/$tdir
10814         for num in 1 2 3 4; do
10815                 for count in $(seq 1 $STRIPE_COUNT); do
10816                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10817                                 local size=`expr $STRIPE_SIZE \* $num`
10818                                 local file=file"$num-$idx-$count"
10819                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10820                         done
10821                 done
10822         done
10823
10824         cd $DIR
10825         $1 tar cf $TMP/f102.tar $tdir --xattrs
10826 }
10827
10828 cleanup_test102() {
10829         trap 0
10830         rm -f $TMP/f102.tar
10831         rm -rf $DIR/d0.sanity/d102
10832 }
10833
10834 test_102a() {
10835         [ "$UID" != 0 ] && skip "must run as root"
10836         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10837                 skip_env "must have user_xattr"
10838
10839         [ -z "$(which setfattr 2>/dev/null)" ] &&
10840                 skip_env "could not find setfattr"
10841
10842         local testfile=$DIR/$tfile
10843
10844         touch $testfile
10845         echo "set/get xattr..."
10846         setfattr -n trusted.name1 -v value1 $testfile ||
10847                 error "setfattr -n trusted.name1=value1 $testfile failed"
10848         getfattr -n trusted.name1 $testfile 2> /dev/null |
10849           grep "trusted.name1=.value1" ||
10850                 error "$testfile missing trusted.name1=value1"
10851
10852         setfattr -n user.author1 -v author1 $testfile ||
10853                 error "setfattr -n user.author1=author1 $testfile failed"
10854         getfattr -n user.author1 $testfile 2> /dev/null |
10855           grep "user.author1=.author1" ||
10856                 error "$testfile missing trusted.author1=author1"
10857
10858         echo "listxattr..."
10859         setfattr -n trusted.name2 -v value2 $testfile ||
10860                 error "$testfile unable to set trusted.name2"
10861         setfattr -n trusted.name3 -v value3 $testfile ||
10862                 error "$testfile unable to set trusted.name3"
10863         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10864             grep "trusted.name" | wc -l) -eq 3 ] ||
10865                 error "$testfile missing 3 trusted.name xattrs"
10866
10867         setfattr -n user.author2 -v author2 $testfile ||
10868                 error "$testfile unable to set user.author2"
10869         setfattr -n user.author3 -v author3 $testfile ||
10870                 error "$testfile unable to set user.author3"
10871         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10872             grep "user.author" | wc -l) -eq 3 ] ||
10873                 error "$testfile missing 3 user.author xattrs"
10874
10875         echo "remove xattr..."
10876         setfattr -x trusted.name1 $testfile ||
10877                 error "$testfile error deleting trusted.name1"
10878         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10879                 error "$testfile did not delete trusted.name1 xattr"
10880
10881         setfattr -x user.author1 $testfile ||
10882                 error "$testfile error deleting user.author1"
10883         echo "set lustre special xattr ..."
10884         $LFS setstripe -c1 $testfile
10885         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10886                 awk -F "=" '/trusted.lov/ { print $2 }' )
10887         setfattr -n "trusted.lov" -v $lovea $testfile ||
10888                 error "$testfile doesn't ignore setting trusted.lov again"
10889         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10890                 error "$testfile allow setting invalid trusted.lov"
10891         rm -f $testfile
10892 }
10893 run_test 102a "user xattr test =================================="
10894
10895 check_102b_layout() {
10896         local layout="$*"
10897         local testfile=$DIR/$tfile
10898
10899         echo "test layout '$layout'"
10900         $LFS setstripe $layout $testfile || error "setstripe failed"
10901         $LFS getstripe -y $testfile
10902
10903         echo "get/set/list trusted.lov xattr ..." # b=10930
10904         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10905         [[ "$value" =~ "trusted.lov" ]] ||
10906                 error "can't get trusted.lov from $testfile"
10907         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10908                 error "getstripe failed"
10909
10910         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10911
10912         value=$(cut -d= -f2 <<<$value)
10913         # LU-13168: truncated xattr should fail if short lov_user_md header
10914         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10915                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10916         for len in $lens; do
10917                 echo "setfattr $len $testfile.2"
10918                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10919                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10920         done
10921         local stripe_size=$($LFS getstripe -S $testfile.2)
10922         local stripe_count=$($LFS getstripe -c $testfile.2)
10923         [[ $stripe_size -eq 65536 ]] ||
10924                 error "stripe size $stripe_size != 65536"
10925         [[ $stripe_count -eq $stripe_count_orig ]] ||
10926                 error "stripe count $stripe_count != $stripe_count_orig"
10927         rm $testfile $testfile.2
10928 }
10929
10930 test_102b() {
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         # check plain layout
10936         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10937
10938         # and also check composite layout
10939         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10940
10941 }
10942 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10943
10944 test_102c() {
10945         [ -z "$(which setfattr 2>/dev/null)" ] &&
10946                 skip_env "could not find setfattr"
10947         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10948
10949         # b10930: get/set/list lustre.lov xattr
10950         echo "get/set/list lustre.lov xattr ..."
10951         test_mkdir $DIR/$tdir
10952         chown $RUNAS_ID $DIR/$tdir
10953         local testfile=$DIR/$tdir/$tfile
10954         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10955                 error "setstripe failed"
10956         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10957                 error "getstripe failed"
10958         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10959         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10960
10961         local testfile2=${testfile}2
10962         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10963                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10964
10965         $RUNAS $MCREATE $testfile2
10966         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10967         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10968         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10969         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10970         [ $stripe_count -eq $STRIPECOUNT ] ||
10971                 error "stripe count $stripe_count != $STRIPECOUNT"
10972 }
10973 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10974
10975 compare_stripe_info1() {
10976         local stripe_index_all_zero=true
10977
10978         for num in 1 2 3 4; do
10979                 for count in $(seq 1 $STRIPE_COUNT); do
10980                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10981                                 local size=$((STRIPE_SIZE * num))
10982                                 local file=file"$num-$offset-$count"
10983                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10984                                 [[ $stripe_size -ne $size ]] &&
10985                                     error "$file: size $stripe_size != $size"
10986                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10987                                 # allow fewer stripes to be created, ORI-601
10988                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10989                                     error "$file: count $stripe_count != $count"
10990                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10991                                 [[ $stripe_index -ne 0 ]] &&
10992                                         stripe_index_all_zero=false
10993                         done
10994                 done
10995         done
10996         $stripe_index_all_zero &&
10997                 error "all files are being extracted starting from OST index 0"
10998         return 0
10999 }
11000
11001 have_xattrs_include() {
11002         tar --help | grep -q xattrs-include &&
11003                 echo --xattrs-include="lustre.*"
11004 }
11005
11006 test_102d() {
11007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11008         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11009
11010         XINC=$(have_xattrs_include)
11011         setup_test102
11012         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11013         cd $DIR/$tdir/$tdir
11014         compare_stripe_info1
11015 }
11016 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11017
11018 test_102f() {
11019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11020         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11021
11022         XINC=$(have_xattrs_include)
11023         setup_test102
11024         test_mkdir $DIR/$tdir.restore
11025         cd $DIR
11026         tar cf - --xattrs $tdir | tar xf - \
11027                 -C $DIR/$tdir.restore --xattrs $XINC
11028         cd $DIR/$tdir.restore/$tdir
11029         compare_stripe_info1
11030 }
11031 run_test 102f "tar copy files, not keep osts"
11032
11033 grow_xattr() {
11034         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11035                 skip "must have user_xattr"
11036         [ -z "$(which setfattr 2>/dev/null)" ] &&
11037                 skip_env "could not find setfattr"
11038         [ -z "$(which getfattr 2>/dev/null)" ] &&
11039                 skip_env "could not find getfattr"
11040
11041         local xsize=${1:-1024}  # in bytes
11042         local file=$DIR/$tfile
11043         local value="$(generate_string $xsize)"
11044         local xbig=trusted.big
11045         local toobig=$2
11046
11047         touch $file
11048         log "save $xbig on $file"
11049         if [ -z "$toobig" ]
11050         then
11051                 setfattr -n $xbig -v $value $file ||
11052                         error "saving $xbig on $file failed"
11053         else
11054                 setfattr -n $xbig -v $value $file &&
11055                         error "saving $xbig on $file succeeded"
11056                 return 0
11057         fi
11058
11059         local orig=$(get_xattr_value $xbig $file)
11060         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11061
11062         local xsml=trusted.sml
11063         log "save $xsml on $file"
11064         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11065
11066         local new=$(get_xattr_value $xbig $file)
11067         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11068
11069         log "grow $xsml on $file"
11070         setfattr -n $xsml -v "$value" $file ||
11071                 error "growing $xsml on $file failed"
11072
11073         new=$(get_xattr_value $xbig $file)
11074         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11075         log "$xbig still valid after growing $xsml"
11076
11077         rm -f $file
11078 }
11079
11080 test_102h() { # bug 15777
11081         grow_xattr 1024
11082 }
11083 run_test 102h "grow xattr from inside inode to external block"
11084
11085 test_102ha() {
11086         large_xattr_enabled || skip_env "ea_inode feature disabled"
11087
11088         echo "setting xattr of max xattr size: $(max_xattr_size)"
11089         grow_xattr $(max_xattr_size)
11090
11091         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11092         echo "This should fail:"
11093         grow_xattr $(($(max_xattr_size) + 10)) 1
11094 }
11095 run_test 102ha "grow xattr from inside inode to external inode"
11096
11097 test_102i() { # bug 17038
11098         [ -z "$(which getfattr 2>/dev/null)" ] &&
11099                 skip "could not find getfattr"
11100
11101         touch $DIR/$tfile
11102         ln -s $DIR/$tfile $DIR/${tfile}link
11103         getfattr -n trusted.lov $DIR/$tfile ||
11104                 error "lgetxattr on $DIR/$tfile failed"
11105         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11106                 grep -i "no such attr" ||
11107                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11108         rm -f $DIR/$tfile $DIR/${tfile}link
11109 }
11110 run_test 102i "lgetxattr test on symbolic link ============"
11111
11112 test_102j() {
11113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11114         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11115
11116         XINC=$(have_xattrs_include)
11117         setup_test102 "$RUNAS"
11118         chown $RUNAS_ID $DIR/$tdir
11119         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11120         cd $DIR/$tdir/$tdir
11121         compare_stripe_info1 "$RUNAS"
11122 }
11123 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11124
11125 test_102k() {
11126         [ -z "$(which setfattr 2>/dev/null)" ] &&
11127                 skip "could not find setfattr"
11128
11129         touch $DIR/$tfile
11130         # b22187 just check that does not crash for regular file.
11131         setfattr -n trusted.lov $DIR/$tfile
11132         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11133         local test_kdir=$DIR/$tdir
11134         test_mkdir $test_kdir
11135         local default_size=$($LFS getstripe -S $test_kdir)
11136         local default_count=$($LFS getstripe -c $test_kdir)
11137         local default_offset=$($LFS getstripe -i $test_kdir)
11138         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11139                 error 'dir setstripe failed'
11140         setfattr -n trusted.lov $test_kdir
11141         local stripe_size=$($LFS getstripe -S $test_kdir)
11142         local stripe_count=$($LFS getstripe -c $test_kdir)
11143         local stripe_offset=$($LFS getstripe -i $test_kdir)
11144         [ $stripe_size -eq $default_size ] ||
11145                 error "stripe size $stripe_size != $default_size"
11146         [ $stripe_count -eq $default_count ] ||
11147                 error "stripe count $stripe_count != $default_count"
11148         [ $stripe_offset -eq $default_offset ] ||
11149                 error "stripe offset $stripe_offset != $default_offset"
11150         rm -rf $DIR/$tfile $test_kdir
11151 }
11152 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11153
11154 test_102l() {
11155         [ -z "$(which getfattr 2>/dev/null)" ] &&
11156                 skip "could not find getfattr"
11157
11158         # LU-532 trusted. xattr is invisible to non-root
11159         local testfile=$DIR/$tfile
11160
11161         touch $testfile
11162
11163         echo "listxattr as user..."
11164         chown $RUNAS_ID $testfile
11165         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11166             grep -q "trusted" &&
11167                 error "$testfile trusted xattrs are user visible"
11168
11169         return 0;
11170 }
11171 run_test 102l "listxattr size test =================================="
11172
11173 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11174         local path=$DIR/$tfile
11175         touch $path
11176
11177         listxattr_size_check $path || error "listattr_size_check $path failed"
11178 }
11179 run_test 102m "Ensure listxattr fails on small bufffer ========"
11180
11181 cleanup_test102
11182
11183 getxattr() { # getxattr path name
11184         # Return the base64 encoding of the value of xattr name on path.
11185         local path=$1
11186         local name=$2
11187
11188         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11189         # file: $path
11190         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11191         #
11192         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11193
11194         getfattr --absolute-names --encoding=base64 --name=$name $path |
11195                 awk -F= -v name=$name '$1 == name {
11196                         print substr($0, index($0, "=") + 1);
11197         }'
11198 }
11199
11200 test_102n() { # LU-4101 mdt: protect internal xattrs
11201         [ -z "$(which setfattr 2>/dev/null)" ] &&
11202                 skip "could not find setfattr"
11203         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11204         then
11205                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11206         fi
11207
11208         local file0=$DIR/$tfile.0
11209         local file1=$DIR/$tfile.1
11210         local xattr0=$TMP/$tfile.0
11211         local xattr1=$TMP/$tfile.1
11212         local namelist="lov lma lmv link fid version som hsm"
11213         local name
11214         local value
11215
11216         rm -rf $file0 $file1 $xattr0 $xattr1
11217         touch $file0 $file1
11218
11219         # Get 'before' xattrs of $file1.
11220         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11221
11222         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11223                 namelist+=" lfsck_namespace"
11224         for name in $namelist; do
11225                 # Try to copy xattr from $file0 to $file1.
11226                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11227
11228                 setfattr --name=trusted.$name --value="$value" $file1 ||
11229                         error "setxattr 'trusted.$name' failed"
11230
11231                 # Try to set a garbage xattr.
11232                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11233
11234                 if [[ x$name == "xlov" ]]; then
11235                         setfattr --name=trusted.lov --value="$value" $file1 &&
11236                         error "setxattr invalid 'trusted.lov' success"
11237                 else
11238                         setfattr --name=trusted.$name --value="$value" $file1 ||
11239                                 error "setxattr invalid 'trusted.$name' failed"
11240                 fi
11241
11242                 # Try to remove the xattr from $file1. We don't care if this
11243                 # appears to succeed or fail, we just don't want there to be
11244                 # any changes or crashes.
11245                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11246         done
11247
11248         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11249         then
11250                 name="lfsck_ns"
11251                 # Try to copy xattr from $file0 to $file1.
11252                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11253
11254                 setfattr --name=trusted.$name --value="$value" $file1 ||
11255                         error "setxattr 'trusted.$name' failed"
11256
11257                 # Try to set a garbage xattr.
11258                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11259
11260                 setfattr --name=trusted.$name --value="$value" $file1 ||
11261                         error "setxattr 'trusted.$name' failed"
11262
11263                 # Try to remove the xattr from $file1. We don't care if this
11264                 # appears to succeed or fail, we just don't want there to be
11265                 # any changes or crashes.
11266                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11267         fi
11268
11269         # Get 'after' xattrs of file1.
11270         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11271
11272         if ! diff $xattr0 $xattr1; then
11273                 error "before and after xattrs of '$file1' differ"
11274         fi
11275
11276         rm -rf $file0 $file1 $xattr0 $xattr1
11277
11278         return 0
11279 }
11280 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11281
11282 test_102p() { # LU-4703 setxattr did not check ownership
11283         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11284                 skip "MDS needs to be at least 2.5.56"
11285
11286         local testfile=$DIR/$tfile
11287
11288         touch $testfile
11289
11290         echo "setfacl as user..."
11291         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11292         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11293
11294         echo "setfattr as user..."
11295         setfacl -m "u:$RUNAS_ID:---" $testfile
11296         $RUNAS setfattr -x system.posix_acl_access $testfile
11297         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11298 }
11299 run_test 102p "check setxattr(2) correctly fails without permission"
11300
11301 test_102q() {
11302         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11303                 skip "MDS needs to be at least 2.6.92"
11304
11305         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11306 }
11307 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11308
11309 test_102r() {
11310         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11311                 skip "MDS needs to be at least 2.6.93"
11312
11313         touch $DIR/$tfile || error "touch"
11314         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11315         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11316         rm $DIR/$tfile || error "rm"
11317
11318         #normal directory
11319         mkdir -p $DIR/$tdir || error "mkdir"
11320         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11321         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11322         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11323                 error "$testfile error deleting user.author1"
11324         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11325                 grep "user.$(basename $tdir)" &&
11326                 error "$tdir did not delete user.$(basename $tdir)"
11327         rmdir $DIR/$tdir || error "rmdir"
11328
11329         #striped directory
11330         test_mkdir $DIR/$tdir
11331         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11332         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11333         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11334                 error "$testfile error deleting user.author1"
11335         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11336                 grep "user.$(basename $tdir)" &&
11337                 error "$tdir did not delete user.$(basename $tdir)"
11338         rmdir $DIR/$tdir || error "rm striped dir"
11339 }
11340 run_test 102r "set EAs with empty values"
11341
11342 test_102s() {
11343         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11344                 skip "MDS needs to be at least 2.11.52"
11345
11346         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11347
11348         save_lustre_params client "llite.*.xattr_cache" > $save
11349
11350         for cache in 0 1; do
11351                 lctl set_param llite.*.xattr_cache=$cache
11352
11353                 rm -f $DIR/$tfile
11354                 touch $DIR/$tfile || error "touch"
11355                 for prefix in lustre security system trusted user; do
11356                         # Note getxattr() may fail with 'Operation not
11357                         # supported' or 'No such attribute' depending
11358                         # on prefix and cache.
11359                         getfattr -n $prefix.n102s $DIR/$tfile &&
11360                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11361                 done
11362         done
11363
11364         restore_lustre_params < $save
11365 }
11366 run_test 102s "getting nonexistent xattrs should fail"
11367
11368 test_102t() {
11369         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11370                 skip "MDS needs to be at least 2.11.52"
11371
11372         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11373
11374         save_lustre_params client "llite.*.xattr_cache" > $save
11375
11376         for cache in 0 1; do
11377                 lctl set_param llite.*.xattr_cache=$cache
11378
11379                 for buf_size in 0 256; do
11380                         rm -f $DIR/$tfile
11381                         touch $DIR/$tfile || error "touch"
11382                         setfattr -n user.multiop $DIR/$tfile
11383                         $MULTIOP $DIR/$tfile oa$buf_size ||
11384                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11385                 done
11386         done
11387
11388         restore_lustre_params < $save
11389 }
11390 run_test 102t "zero length xattr values handled correctly"
11391
11392 run_acl_subtest()
11393 {
11394     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11395     return $?
11396 }
11397
11398 test_103a() {
11399         [ "$UID" != 0 ] && skip "must run as root"
11400         $GSS && skip_env "could not run under gss"
11401         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11402                 skip_env "must have acl enabled"
11403         [ -z "$(which setfacl 2>/dev/null)" ] &&
11404                 skip_env "could not find setfacl"
11405         remote_mds_nodsh && skip "remote MDS with nodsh"
11406
11407         gpasswd -a daemon bin                           # LU-5641
11408         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11409
11410         declare -a identity_old
11411
11412         for num in $(seq $MDSCOUNT); do
11413                 switch_identity $num true || identity_old[$num]=$?
11414         done
11415
11416         SAVE_UMASK=$(umask)
11417         umask 0022
11418         mkdir -p $DIR/$tdir
11419         cd $DIR/$tdir
11420
11421         echo "performing cp ..."
11422         run_acl_subtest cp || error "run_acl_subtest cp failed"
11423         echo "performing getfacl-noacl..."
11424         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11425         echo "performing misc..."
11426         run_acl_subtest misc || error  "misc test failed"
11427         echo "performing permissions..."
11428         run_acl_subtest permissions || error "permissions failed"
11429         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11430         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11431                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11432                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11433         then
11434                 echo "performing permissions xattr..."
11435                 run_acl_subtest permissions_xattr ||
11436                         error "permissions_xattr failed"
11437         fi
11438         echo "performing setfacl..."
11439         run_acl_subtest setfacl || error  "setfacl test failed"
11440
11441         # inheritance test got from HP
11442         echo "performing inheritance..."
11443         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11444         chmod +x make-tree || error "chmod +x failed"
11445         run_acl_subtest inheritance || error "inheritance test failed"
11446         rm -f make-tree
11447
11448         echo "LU-974 ignore umask when acl is enabled..."
11449         run_acl_subtest 974 || error "LU-974 umask test failed"
11450         if [ $MDSCOUNT -ge 2 ]; then
11451                 run_acl_subtest 974_remote ||
11452                         error "LU-974 umask test failed under remote dir"
11453         fi
11454
11455         echo "LU-2561 newly created file is same size as directory..."
11456         if [ "$mds1_FSTYPE" != "zfs" ]; then
11457                 run_acl_subtest 2561 || error "LU-2561 test failed"
11458         else
11459                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11460         fi
11461
11462         run_acl_subtest 4924 || error "LU-4924 test failed"
11463
11464         cd $SAVE_PWD
11465         umask $SAVE_UMASK
11466
11467         for num in $(seq $MDSCOUNT); do
11468                 if [ "${identity_old[$num]}" = 1 ]; then
11469                         switch_identity $num false || identity_old[$num]=$?
11470                 fi
11471         done
11472 }
11473 run_test 103a "acl test"
11474
11475 test_103b() {
11476         declare -a pids
11477         local U
11478
11479         for U in {0..511}; do
11480                 {
11481                 local O=$(printf "%04o" $U)
11482
11483                 umask $(printf "%04o" $((511 ^ $O)))
11484                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11485                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11486
11487                 (( $S == ($O & 0666) )) ||
11488                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11489
11490                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11491                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11492                 (( $S == ($O & 0666) )) ||
11493                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11494
11495                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11496                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11497                 (( $S == ($O & 0666) )) ||
11498                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11499                 rm -f $DIR/$tfile.[smp]$0
11500                 } &
11501                 local pid=$!
11502
11503                 # limit the concurrently running threads to 64. LU-11878
11504                 local idx=$((U % 64))
11505                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11506                 pids[idx]=$pid
11507         done
11508         wait
11509 }
11510 run_test 103b "umask lfs setstripe"
11511
11512 test_103c() {
11513         mkdir -p $DIR/$tdir
11514         cp -rp $DIR/$tdir $DIR/$tdir.bak
11515
11516         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11517                 error "$DIR/$tdir shouldn't contain default ACL"
11518         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11519                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11520         true
11521 }
11522 run_test 103c "'cp -rp' won't set empty acl"
11523
11524 test_103e() {
11525         local numacl
11526         local fileacl
11527         local saved_debug=$($LCTL get_param -n debug)
11528
11529         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11530                 skip "MDS needs to be at least 2.14.0"
11531
11532         large_xattr_enabled || skip_env "ea_inode feature disabled"
11533
11534         mkdir -p $DIR/$tdir
11535         # add big LOV EA to cause reply buffer overflow earlier
11536         $LFS setstripe -C 1000 $DIR/$tdir
11537         lctl set_param mdc.*-mdc*.stats=clear
11538
11539         $LCTL set_param debug=0
11540         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11541         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11542
11543         # add a large number of default ACLs (expect 8000+ for 2.13+)
11544         for U in {2..7000}; do
11545                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11546                         error "Able to add just $U default ACLs"
11547         done
11548         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11549         echo "$numacl default ACLs created"
11550
11551         stat $DIR/$tdir || error "Cannot stat directory"
11552         # check file creation
11553         touch $DIR/$tdir/$tfile ||
11554                 error "failed to create $tfile with $numacl default ACLs"
11555         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11556         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11557         echo "$fileacl ACLs were inherited"
11558         (( $fileacl == $numacl )) ||
11559                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11560         # check that new ACLs creation adds new ACLs to inherited ACLs
11561         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11562                 error "Cannot set new ACL"
11563         numacl=$((numacl + 1))
11564         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11565         (( $fileacl == $numacl )) ||
11566                 error "failed to add new ACL: $fileacl != $numacl as expected"
11567         # adds more ACLs to a file to reach their maximum at 8000+
11568         numacl=0
11569         for U in {20000..25000}; do
11570                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11571                 numacl=$((numacl + 1))
11572         done
11573         echo "Added $numacl more ACLs to the file"
11574         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11575         echo "Total $fileacl ACLs in file"
11576         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11577         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11578         rmdir $DIR/$tdir || error "Cannot remove directory"
11579 }
11580 run_test 103e "inheritance of big amount of default ACLs"
11581
11582 test_103f() {
11583         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11584                 skip "MDS needs to be at least 2.14.51"
11585
11586         large_xattr_enabled || skip_env "ea_inode feature disabled"
11587
11588         # enable changelog to consume more internal MDD buffers
11589         changelog_register
11590
11591         mkdir -p $DIR/$tdir
11592         # add big LOV EA
11593         $LFS setstripe -C 1000 $DIR/$tdir
11594         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11595         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11596         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11597         rmdir $DIR/$tdir || error "Cannot remove directory"
11598 }
11599 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11600
11601 test_104a() {
11602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11603
11604         touch $DIR/$tfile
11605         lfs df || error "lfs df failed"
11606         lfs df -ih || error "lfs df -ih failed"
11607         lfs df -h $DIR || error "lfs df -h $DIR failed"
11608         lfs df -i $DIR || error "lfs df -i $DIR failed"
11609         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11610         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11611
11612         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11613         lctl --device %$OSC deactivate
11614         lfs df || error "lfs df with deactivated OSC failed"
11615         lctl --device %$OSC activate
11616         # wait the osc back to normal
11617         wait_osc_import_ready client ost
11618
11619         lfs df || error "lfs df with reactivated OSC failed"
11620         rm -f $DIR/$tfile
11621 }
11622 run_test 104a "lfs df [-ih] [path] test ========================="
11623
11624 test_104b() {
11625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11626         [ $RUNAS_ID -eq $UID ] &&
11627                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11628
11629         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11630                         grep "Permission denied" | wc -l)))
11631         if [ $denied_cnt -ne 0 ]; then
11632                 error "lfs check servers test failed"
11633         fi
11634 }
11635 run_test 104b "$RUNAS lfs check servers test ===================="
11636
11637 #
11638 # Verify $1 is within range of $2.
11639 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11640 # $1 is <= 2% of $2. Else Fail.
11641 #
11642 value_in_range() {
11643         # Strip all units (M, G, T)
11644         actual=$(echo $1 | tr -d A-Z)
11645         expect=$(echo $2 | tr -d A-Z)
11646
11647         expect_lo=$(($expect * 98 / 100)) # 2% below
11648         expect_hi=$(($expect * 102 / 100)) # 2% above
11649
11650         # permit 2% drift above and below
11651         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11652 }
11653
11654 test_104c() {
11655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11656         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11657
11658         local ost_param="osd-zfs.$FSNAME-OST0000."
11659         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11660         local ofacets=$(get_facets OST)
11661         local mfacets=$(get_facets MDS)
11662         local saved_ost_blocks=
11663         local saved_mdt_blocks=
11664
11665         echo "Before recordsize change"
11666         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11667         df=($(df -h | grep "/mnt/lustre"$))
11668
11669         # For checking.
11670         echo "lfs output : ${lfs_df[*]}"
11671         echo "df  output : ${df[*]}"
11672
11673         for facet in ${ofacets//,/ }; do
11674                 if [ -z $saved_ost_blocks ]; then
11675                         saved_ost_blocks=$(do_facet $facet \
11676                                 lctl get_param -n $ost_param.blocksize)
11677                         echo "OST Blocksize: $saved_ost_blocks"
11678                 fi
11679                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11680                 do_facet $facet zfs set recordsize=32768 $ost
11681         done
11682
11683         # BS too small. Sufficient for functional testing.
11684         for facet in ${mfacets//,/ }; do
11685                 if [ -z $saved_mdt_blocks ]; then
11686                         saved_mdt_blocks=$(do_facet $facet \
11687                                 lctl get_param -n $mdt_param.blocksize)
11688                         echo "MDT Blocksize: $saved_mdt_blocks"
11689                 fi
11690                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11691                 do_facet $facet zfs set recordsize=32768 $mdt
11692         done
11693
11694         # Give new values chance to reflect change
11695         sleep 2
11696
11697         echo "After recordsize change"
11698         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11699         df_after=($(df -h | grep "/mnt/lustre"$))
11700
11701         # For checking.
11702         echo "lfs output : ${lfs_df_after[*]}"
11703         echo "df  output : ${df_after[*]}"
11704
11705         # Verify lfs df
11706         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11707                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11708         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11709                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11710         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11711                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11712
11713         # Verify df
11714         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11715                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11716         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11717                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11718         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11719                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11720
11721         # Restore MDT recordize back to original
11722         for facet in ${mfacets//,/ }; do
11723                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11724                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11725         done
11726
11727         # Restore OST recordize back to original
11728         for facet in ${ofacets//,/ }; do
11729                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11730                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11731         done
11732
11733         return 0
11734 }
11735 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11736
11737 test_105a() {
11738         # doesn't work on 2.4 kernels
11739         touch $DIR/$tfile
11740         if $(flock_is_enabled); then
11741                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11742         else
11743                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11744         fi
11745         rm -f $DIR/$tfile
11746 }
11747 run_test 105a "flock when mounted without -o flock test ========"
11748
11749 test_105b() {
11750         touch $DIR/$tfile
11751         if $(flock_is_enabled); then
11752                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11753         else
11754                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11755         fi
11756         rm -f $DIR/$tfile
11757 }
11758 run_test 105b "fcntl when mounted without -o flock test ========"
11759
11760 test_105c() {
11761         touch $DIR/$tfile
11762         if $(flock_is_enabled); then
11763                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11764         else
11765                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11766         fi
11767         rm -f $DIR/$tfile
11768 }
11769 run_test 105c "lockf when mounted without -o flock test"
11770
11771 test_105d() { # bug 15924
11772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11773
11774         test_mkdir $DIR/$tdir
11775         flock_is_enabled || skip_env "mount w/o flock enabled"
11776         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11777         $LCTL set_param fail_loc=0x80000315
11778         flocks_test 2 $DIR/$tdir
11779 }
11780 run_test 105d "flock race (should not freeze) ========"
11781
11782 test_105e() { # bug 22660 && 22040
11783         flock_is_enabled || skip_env "mount w/o flock enabled"
11784
11785         touch $DIR/$tfile
11786         flocks_test 3 $DIR/$tfile
11787 }
11788 run_test 105e "Two conflicting flocks from same process"
11789
11790 test_106() { #bug 10921
11791         test_mkdir $DIR/$tdir
11792         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11793         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11794 }
11795 run_test 106 "attempt exec of dir followed by chown of that dir"
11796
11797 test_107() {
11798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11799
11800         CDIR=`pwd`
11801         local file=core
11802
11803         cd $DIR
11804         rm -f $file
11805
11806         local save_pattern=$(sysctl -n kernel.core_pattern)
11807         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11808         sysctl -w kernel.core_pattern=$file
11809         sysctl -w kernel.core_uses_pid=0
11810
11811         ulimit -c unlimited
11812         sleep 60 &
11813         SLEEPPID=$!
11814
11815         sleep 1
11816
11817         kill -s 11 $SLEEPPID
11818         wait $SLEEPPID
11819         if [ -e $file ]; then
11820                 size=`stat -c%s $file`
11821                 [ $size -eq 0 ] && error "Fail to create core file $file"
11822         else
11823                 error "Fail to create core file $file"
11824         fi
11825         rm -f $file
11826         sysctl -w kernel.core_pattern=$save_pattern
11827         sysctl -w kernel.core_uses_pid=$save_uses_pid
11828         cd $CDIR
11829 }
11830 run_test 107 "Coredump on SIG"
11831
11832 test_110() {
11833         test_mkdir $DIR/$tdir
11834         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11835         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11836                 error "mkdir with 256 char should fail, but did not"
11837         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11838                 error "create with 255 char failed"
11839         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11840                 error "create with 256 char should fail, but did not"
11841
11842         ls -l $DIR/$tdir
11843         rm -rf $DIR/$tdir
11844 }
11845 run_test 110 "filename length checking"
11846
11847 #
11848 # Purpose: To verify dynamic thread (OSS) creation.
11849 #
11850 test_115() {
11851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11852         remote_ost_nodsh && skip "remote OST with nodsh"
11853
11854         # Lustre does not stop service threads once they are started.
11855         # Reset number of running threads to default.
11856         stopall
11857         setupall
11858
11859         local OSTIO_pre
11860         local save_params="$TMP/sanity-$TESTNAME.parameters"
11861
11862         # Get ll_ost_io count before I/O
11863         OSTIO_pre=$(do_facet ost1 \
11864                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11865         # Exit if lustre is not running (ll_ost_io not running).
11866         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11867
11868         echo "Starting with $OSTIO_pre threads"
11869         local thread_max=$((OSTIO_pre * 2))
11870         local rpc_in_flight=$((thread_max * 2))
11871         # this is limited to OSC_MAX_RIF_MAX (256)
11872         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
11873         thread_max=$((rpc_in_flight / 2))
11874         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
11875                 return
11876
11877         # Number of I/O Process proposed to be started.
11878         local nfiles
11879         local facets=$(get_facets OST)
11880
11881         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11882         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11883
11884         # Set in_flight to $rpc_in_flight
11885         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11886                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11887         nfiles=${rpc_in_flight}
11888         # Set ost thread_max to $thread_max
11889         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11890
11891         # 5 Minutes should be sufficient for max number of OSS
11892         # threads(thread_max) to be created.
11893         local timeout=300
11894
11895         # Start I/O.
11896         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11897         test_mkdir $DIR/$tdir
11898         for i in $(seq $nfiles); do
11899                 local file=$DIR/$tdir/${tfile}-$i
11900                 $LFS setstripe -c -1 -i 0 $file
11901                 ($WTL $file $timeout)&
11902         done
11903
11904         # I/O Started - Wait for thread_started to reach thread_max or report
11905         # error if thread_started is more than thread_max.
11906         echo "Waiting for thread_started to reach thread_max"
11907         local thread_started=0
11908         local end_time=$((SECONDS + timeout))
11909
11910         while [ $SECONDS -le $end_time ] ; do
11911                 echo -n "."
11912                 # Get ost i/o thread_started count.
11913                 thread_started=$(do_facet ost1 \
11914                         "$LCTL get_param \
11915                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11916                 # Break out if thread_started is equal/greater than thread_max
11917                 if [[ $thread_started -ge $thread_max ]]; then
11918                         echo ll_ost_io thread_started $thread_started, \
11919                                 equal/greater than thread_max $thread_max
11920                         break
11921                 fi
11922                 sleep 1
11923         done
11924
11925         # Cleanup - We have the numbers, Kill i/o jobs if running.
11926         jobcount=($(jobs -p))
11927         for i in $(seq 0 $((${#jobcount[@]}-1)))
11928         do
11929                 kill -9 ${jobcount[$i]}
11930                 if [ $? -ne 0 ] ; then
11931                         echo Warning: \
11932                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11933                 fi
11934         done
11935
11936         # Cleanup files left by WTL binary.
11937         for i in $(seq $nfiles); do
11938                 local file=$DIR/$tdir/${tfile}-$i
11939                 rm -rf $file
11940                 if [ $? -ne 0 ] ; then
11941                         echo "Warning: Failed to delete file $file"
11942                 fi
11943         done
11944
11945         restore_lustre_params <$save_params
11946         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11947
11948         # Error out if no new thread has started or Thread started is greater
11949         # than thread max.
11950         if [[ $thread_started -le $OSTIO_pre ||
11951                         $thread_started -gt $thread_max ]]; then
11952                 error "ll_ost_io: thread_started $thread_started" \
11953                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11954                       "No new thread started or thread started greater " \
11955                       "than thread_max."
11956         fi
11957 }
11958 run_test 115 "verify dynamic thread creation===================="
11959
11960 free_min_max () {
11961         wait_delete_completed
11962         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11963         echo "OST kbytes available: ${AVAIL[@]}"
11964         MAXV=${AVAIL[0]}
11965         MAXI=0
11966         MINV=${AVAIL[0]}
11967         MINI=0
11968         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11969                 #echo OST $i: ${AVAIL[i]}kb
11970                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11971                         MAXV=${AVAIL[i]}
11972                         MAXI=$i
11973                 fi
11974                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11975                         MINV=${AVAIL[i]}
11976                         MINI=$i
11977                 fi
11978         done
11979         echo "Min free space: OST $MINI: $MINV"
11980         echo "Max free space: OST $MAXI: $MAXV"
11981 }
11982
11983 test_116a() { # was previously test_116()
11984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11985         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11986         remote_mds_nodsh && skip "remote MDS with nodsh"
11987
11988         echo -n "Free space priority "
11989         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11990                 head -n1
11991         declare -a AVAIL
11992         free_min_max
11993
11994         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11995         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11996         stack_trap simple_cleanup_common
11997
11998         # Check if we need to generate uneven OSTs
11999         test_mkdir -p $DIR/$tdir/OST${MINI}
12000         local FILL=$((MINV / 4))
12001         local DIFF=$((MAXV - MINV))
12002         local DIFF2=$((DIFF * 100 / MINV))
12003
12004         local threshold=$(do_facet $SINGLEMDS \
12005                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12006         threshold=${threshold%%%}
12007         echo -n "Check for uneven OSTs: "
12008         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12009
12010         if [[ $DIFF2 -gt $threshold ]]; then
12011                 echo "ok"
12012                 echo "Don't need to fill OST$MINI"
12013         else
12014                 # generate uneven OSTs. Write 2% over the QOS threshold value
12015                 echo "no"
12016                 DIFF=$((threshold - DIFF2 + 2))
12017                 DIFF2=$((MINV * DIFF / 100))
12018                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12019                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12020                         error "setstripe failed"
12021                 DIFF=$((DIFF2 / 2048))
12022                 i=0
12023                 while [ $i -lt $DIFF ]; do
12024                         i=$((i + 1))
12025                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12026                                 bs=2M count=1 2>/dev/null
12027                         echo -n .
12028                 done
12029                 echo .
12030                 sync
12031                 sleep_maxage
12032                 free_min_max
12033         fi
12034
12035         DIFF=$((MAXV - MINV))
12036         DIFF2=$((DIFF * 100 / MINV))
12037         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12038         if [ $DIFF2 -gt $threshold ]; then
12039                 echo "ok"
12040         else
12041                 skip "QOS imbalance criteria not met"
12042         fi
12043
12044         MINI1=$MINI
12045         MINV1=$MINV
12046         MAXI1=$MAXI
12047         MAXV1=$MAXV
12048
12049         # now fill using QOS
12050         $LFS setstripe -c 1 $DIR/$tdir
12051         FILL=$((FILL / 200))
12052         if [ $FILL -gt 600 ]; then
12053                 FILL=600
12054         fi
12055         echo "writing $FILL files to QOS-assigned OSTs"
12056         i=0
12057         while [ $i -lt $FILL ]; do
12058                 i=$((i + 1))
12059                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12060                         count=1 2>/dev/null
12061                 echo -n .
12062         done
12063         echo "wrote $i 200k files"
12064         sync
12065         sleep_maxage
12066
12067         echo "Note: free space may not be updated, so measurements might be off"
12068         free_min_max
12069         DIFF2=$((MAXV - MINV))
12070         echo "free space delta: orig $DIFF final $DIFF2"
12071         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12072         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12073         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12074         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12075         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12076         if [[ $DIFF -gt 0 ]]; then
12077                 FILL=$((DIFF2 * 100 / DIFF - 100))
12078                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12079         fi
12080
12081         # Figure out which files were written where
12082         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12083                awk '/'$MINI1': / {print $2; exit}')
12084         echo $UUID
12085         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12086         echo "$MINC files created on smaller OST $MINI1"
12087         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12088                awk '/'$MAXI1': / {print $2; exit}')
12089         echo $UUID
12090         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12091         echo "$MAXC files created on larger OST $MAXI1"
12092         if [[ $MINC -gt 0 ]]; then
12093                 FILL=$((MAXC * 100 / MINC - 100))
12094                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12095         fi
12096         [[ $MAXC -gt $MINC ]] ||
12097                 error_ignore LU-9 "stripe QOS didn't balance free space"
12098 }
12099 run_test 116a "stripe QOS: free space balance ==================="
12100
12101 test_116b() { # LU-2093
12102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12103         remote_mds_nodsh && skip "remote MDS with nodsh"
12104
12105 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12106         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12107                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12108         [ -z "$old_rr" ] && skip "no QOS"
12109         do_facet $SINGLEMDS lctl set_param \
12110                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12111         mkdir -p $DIR/$tdir
12112         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12113         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12114         do_facet $SINGLEMDS lctl set_param fail_loc=0
12115         rm -rf $DIR/$tdir
12116         do_facet $SINGLEMDS lctl set_param \
12117                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12118 }
12119 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12120
12121 test_117() # bug 10891
12122 {
12123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12124
12125         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12126         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12127         lctl set_param fail_loc=0x21e
12128         > $DIR/$tfile || error "truncate failed"
12129         lctl set_param fail_loc=0
12130         echo "Truncate succeeded."
12131         rm -f $DIR/$tfile
12132 }
12133 run_test 117 "verify osd extend =========="
12134
12135 NO_SLOW_RESENDCOUNT=4
12136 export OLD_RESENDCOUNT=""
12137 set_resend_count () {
12138         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12139         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12140         lctl set_param -n $PROC_RESENDCOUNT $1
12141         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12142 }
12143
12144 # for reduce test_118* time (b=14842)
12145 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12146
12147 # Reset async IO behavior after error case
12148 reset_async() {
12149         FILE=$DIR/reset_async
12150
12151         # Ensure all OSCs are cleared
12152         $LFS setstripe -c -1 $FILE
12153         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12154         sync
12155         rm $FILE
12156 }
12157
12158 test_118a() #bug 11710
12159 {
12160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12161
12162         reset_async
12163
12164         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12165         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12166         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12167
12168         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12169                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12170                 return 1;
12171         fi
12172         rm -f $DIR/$tfile
12173 }
12174 run_test 118a "verify O_SYNC works =========="
12175
12176 test_118b()
12177 {
12178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12179         remote_ost_nodsh && skip "remote OST with nodsh"
12180
12181         reset_async
12182
12183         #define OBD_FAIL_SRV_ENOENT 0x217
12184         set_nodes_failloc "$(osts_nodes)" 0x217
12185         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12186         RC=$?
12187         set_nodes_failloc "$(osts_nodes)" 0
12188         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12189         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12190                     grep -c writeback)
12191
12192         if [[ $RC -eq 0 ]]; then
12193                 error "Must return error due to dropped pages, rc=$RC"
12194                 return 1;
12195         fi
12196
12197         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12198                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12199                 return 1;
12200         fi
12201
12202         echo "Dirty pages not leaked on ENOENT"
12203
12204         # Due to the above error the OSC will issue all RPCs syncronously
12205         # until a subsequent RPC completes successfully without error.
12206         $MULTIOP $DIR/$tfile Ow4096yc
12207         rm -f $DIR/$tfile
12208
12209         return 0
12210 }
12211 run_test 118b "Reclaim dirty pages on fatal error =========="
12212
12213 test_118c()
12214 {
12215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12216
12217         # for 118c, restore the original resend count, LU-1940
12218         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12219                                 set_resend_count $OLD_RESENDCOUNT
12220         remote_ost_nodsh && skip "remote OST with nodsh"
12221
12222         reset_async
12223
12224         #define OBD_FAIL_OST_EROFS               0x216
12225         set_nodes_failloc "$(osts_nodes)" 0x216
12226
12227         # multiop should block due to fsync until pages are written
12228         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12229         MULTIPID=$!
12230         sleep 1
12231
12232         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12233                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12234         fi
12235
12236         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12237                     grep -c writeback)
12238         if [[ $WRITEBACK -eq 0 ]]; then
12239                 error "No page in writeback, writeback=$WRITEBACK"
12240         fi
12241
12242         set_nodes_failloc "$(osts_nodes)" 0
12243         wait $MULTIPID
12244         RC=$?
12245         if [[ $RC -ne 0 ]]; then
12246                 error "Multiop fsync failed, rc=$RC"
12247         fi
12248
12249         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12250         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12251                     grep -c writeback)
12252         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12253                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12254         fi
12255
12256         rm -f $DIR/$tfile
12257         echo "Dirty pages flushed via fsync on EROFS"
12258         return 0
12259 }
12260 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12261
12262 # continue to use small resend count to reduce test_118* time (b=14842)
12263 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12264
12265 test_118d()
12266 {
12267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12268         remote_ost_nodsh && skip "remote OST with nodsh"
12269
12270         reset_async
12271
12272         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12273         set_nodes_failloc "$(osts_nodes)" 0x214
12274         # multiop should block due to fsync until pages are written
12275         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12276         MULTIPID=$!
12277         sleep 1
12278
12279         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12280                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12281         fi
12282
12283         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12284                     grep -c writeback)
12285         if [[ $WRITEBACK -eq 0 ]]; then
12286                 error "No page in writeback, writeback=$WRITEBACK"
12287         fi
12288
12289         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12290         set_nodes_failloc "$(osts_nodes)" 0
12291
12292         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12293         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12294                     grep -c writeback)
12295         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12296                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12297         fi
12298
12299         rm -f $DIR/$tfile
12300         echo "Dirty pages gaurenteed flushed via fsync"
12301         return 0
12302 }
12303 run_test 118d "Fsync validation inject a delay of the bulk =========="
12304
12305 test_118f() {
12306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12307
12308         reset_async
12309
12310         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12311         lctl set_param fail_loc=0x8000040a
12312
12313         # Should simulate EINVAL error which is fatal
12314         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12315         RC=$?
12316         if [[ $RC -eq 0 ]]; then
12317                 error "Must return error due to dropped pages, rc=$RC"
12318         fi
12319
12320         lctl set_param fail_loc=0x0
12321
12322         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12323         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12324         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12325                     grep -c writeback)
12326         if [[ $LOCKED -ne 0 ]]; then
12327                 error "Locked pages remain in cache, locked=$LOCKED"
12328         fi
12329
12330         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12331                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12332         fi
12333
12334         rm -f $DIR/$tfile
12335         echo "No pages locked after fsync"
12336
12337         reset_async
12338         return 0
12339 }
12340 run_test 118f "Simulate unrecoverable OSC side error =========="
12341
12342 test_118g() {
12343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12344
12345         reset_async
12346
12347         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12348         lctl set_param fail_loc=0x406
12349
12350         # simulate local -ENOMEM
12351         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12352         RC=$?
12353
12354         lctl set_param fail_loc=0
12355         if [[ $RC -eq 0 ]]; then
12356                 error "Must return error due to dropped pages, rc=$RC"
12357         fi
12358
12359         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12360         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12361         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12362                         grep -c writeback)
12363         if [[ $LOCKED -ne 0 ]]; then
12364                 error "Locked pages remain in cache, locked=$LOCKED"
12365         fi
12366
12367         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12368                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12369         fi
12370
12371         rm -f $DIR/$tfile
12372         echo "No pages locked after fsync"
12373
12374         reset_async
12375         return 0
12376 }
12377 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12378
12379 test_118h() {
12380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12381         remote_ost_nodsh && skip "remote OST with nodsh"
12382
12383         reset_async
12384
12385         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12386         set_nodes_failloc "$(osts_nodes)" 0x20e
12387         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12388         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12389         RC=$?
12390
12391         set_nodes_failloc "$(osts_nodes)" 0
12392         if [[ $RC -eq 0 ]]; then
12393                 error "Must return error due to dropped pages, rc=$RC"
12394         fi
12395
12396         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12397         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12398         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12399                     grep -c writeback)
12400         if [[ $LOCKED -ne 0 ]]; then
12401                 error "Locked pages remain in cache, locked=$LOCKED"
12402         fi
12403
12404         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12405                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12406         fi
12407
12408         rm -f $DIR/$tfile
12409         echo "No pages locked after fsync"
12410
12411         return 0
12412 }
12413 run_test 118h "Verify timeout in handling recoverables errors  =========="
12414
12415 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12416
12417 test_118i() {
12418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12419         remote_ost_nodsh && skip "remote OST with nodsh"
12420
12421         reset_async
12422
12423         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12424         set_nodes_failloc "$(osts_nodes)" 0x20e
12425
12426         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12427         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12428         PID=$!
12429         sleep 5
12430         set_nodes_failloc "$(osts_nodes)" 0
12431
12432         wait $PID
12433         RC=$?
12434         if [[ $RC -ne 0 ]]; then
12435                 error "got error, but should be not, rc=$RC"
12436         fi
12437
12438         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12439         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12440         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12441         if [[ $LOCKED -ne 0 ]]; then
12442                 error "Locked pages remain in cache, locked=$LOCKED"
12443         fi
12444
12445         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12446                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12447         fi
12448
12449         rm -f $DIR/$tfile
12450         echo "No pages locked after fsync"
12451
12452         return 0
12453 }
12454 run_test 118i "Fix error before timeout in recoverable error  =========="
12455
12456 [ "$SLOW" = "no" ] && set_resend_count 4
12457
12458 test_118j() {
12459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12460         remote_ost_nodsh && skip "remote OST with nodsh"
12461
12462         reset_async
12463
12464         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12465         set_nodes_failloc "$(osts_nodes)" 0x220
12466
12467         # return -EIO from OST
12468         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12469         RC=$?
12470         set_nodes_failloc "$(osts_nodes)" 0x0
12471         if [[ $RC -eq 0 ]]; then
12472                 error "Must return error due to dropped pages, rc=$RC"
12473         fi
12474
12475         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12476         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12477         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12478         if [[ $LOCKED -ne 0 ]]; then
12479                 error "Locked pages remain in cache, locked=$LOCKED"
12480         fi
12481
12482         # in recoverable error on OST we want resend and stay until it finished
12483         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12484                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12485         fi
12486
12487         rm -f $DIR/$tfile
12488         echo "No pages locked after fsync"
12489
12490         return 0
12491 }
12492 run_test 118j "Simulate unrecoverable OST side error =========="
12493
12494 test_118k()
12495 {
12496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12497         remote_ost_nodsh && skip "remote OSTs with nodsh"
12498
12499         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12500         set_nodes_failloc "$(osts_nodes)" 0x20e
12501         test_mkdir $DIR/$tdir
12502
12503         for ((i=0;i<10;i++)); do
12504                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12505                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12506                 SLEEPPID=$!
12507                 sleep 0.500s
12508                 kill $SLEEPPID
12509                 wait $SLEEPPID
12510         done
12511
12512         set_nodes_failloc "$(osts_nodes)" 0
12513         rm -rf $DIR/$tdir
12514 }
12515 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12516
12517 test_118l() # LU-646
12518 {
12519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12520
12521         test_mkdir $DIR/$tdir
12522         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12523         rm -rf $DIR/$tdir
12524 }
12525 run_test 118l "fsync dir"
12526
12527 test_118m() # LU-3066
12528 {
12529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12530
12531         test_mkdir $DIR/$tdir
12532         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12533         rm -rf $DIR/$tdir
12534 }
12535 run_test 118m "fdatasync dir ========="
12536
12537 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12538
12539 test_118n()
12540 {
12541         local begin
12542         local end
12543
12544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12545         remote_ost_nodsh && skip "remote OSTs with nodsh"
12546
12547         # Sleep to avoid a cached response.
12548         #define OBD_STATFS_CACHE_SECONDS 1
12549         sleep 2
12550
12551         # Inject a 10 second delay in the OST_STATFS handler.
12552         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12553         set_nodes_failloc "$(osts_nodes)" 0x242
12554
12555         begin=$SECONDS
12556         stat --file-system $MOUNT > /dev/null
12557         end=$SECONDS
12558
12559         set_nodes_failloc "$(osts_nodes)" 0
12560
12561         if ((end - begin > 20)); then
12562             error "statfs took $((end - begin)) seconds, expected 10"
12563         fi
12564 }
12565 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12566
12567 test_119a() # bug 11737
12568 {
12569         BSIZE=$((512 * 1024))
12570         directio write $DIR/$tfile 0 1 $BSIZE
12571         # We ask to read two blocks, which is more than a file size.
12572         # directio will indicate an error when requested and actual
12573         # sizes aren't equeal (a normal situation in this case) and
12574         # print actual read amount.
12575         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12576         if [ "$NOB" != "$BSIZE" ]; then
12577                 error "read $NOB bytes instead of $BSIZE"
12578         fi
12579         rm -f $DIR/$tfile
12580 }
12581 run_test 119a "Short directIO read must return actual read amount"
12582
12583 test_119b() # bug 11737
12584 {
12585         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12586
12587         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12588         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12589         sync
12590         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12591                 error "direct read failed"
12592         rm -f $DIR/$tfile
12593 }
12594 run_test 119b "Sparse directIO read must return actual read amount"
12595
12596 test_119c() # bug 13099
12597 {
12598         BSIZE=1048576
12599         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12600         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12601         rm -f $DIR/$tfile
12602 }
12603 run_test 119c "Testing for direct read hitting hole"
12604
12605 test_119d() # bug 15950
12606 {
12607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12608
12609         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12610         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12611         BSIZE=1048576
12612         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12613         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12614         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12615         lctl set_param fail_loc=0x40d
12616         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12617         pid_dio=$!
12618         sleep 1
12619         cat $DIR/$tfile > /dev/null &
12620         lctl set_param fail_loc=0
12621         pid_reads=$!
12622         wait $pid_dio
12623         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12624         sleep 2
12625         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12626         error "the read rpcs have not completed in 2s"
12627         rm -f $DIR/$tfile
12628         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12629 }
12630 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12631
12632 test_120a() {
12633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12634         remote_mds_nodsh && skip "remote MDS with nodsh"
12635         test_mkdir -i0 -c1 $DIR/$tdir
12636         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12637                 skip_env "no early lock cancel on server"
12638
12639         lru_resize_disable mdc
12640         lru_resize_disable osc
12641         cancel_lru_locks mdc
12642         # asynchronous object destroy at MDT could cause bl ast to client
12643         cancel_lru_locks osc
12644
12645         stat $DIR/$tdir > /dev/null
12646         can1=$(do_facet mds1 \
12647                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12648                awk '/ldlm_cancel/ {print $2}')
12649         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12650                awk '/ldlm_bl_callback/ {print $2}')
12651         test_mkdir -i0 -c1 $DIR/$tdir/d1
12652         can2=$(do_facet mds1 \
12653                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12654                awk '/ldlm_cancel/ {print $2}')
12655         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12656                awk '/ldlm_bl_callback/ {print $2}')
12657         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12658         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12659         lru_resize_enable mdc
12660         lru_resize_enable osc
12661 }
12662 run_test 120a "Early Lock Cancel: mkdir test"
12663
12664 test_120b() {
12665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12666         remote_mds_nodsh && skip "remote MDS with nodsh"
12667         test_mkdir $DIR/$tdir
12668         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12669                 skip_env "no early lock cancel on server"
12670
12671         lru_resize_disable mdc
12672         lru_resize_disable osc
12673         cancel_lru_locks mdc
12674         stat $DIR/$tdir > /dev/null
12675         can1=$(do_facet $SINGLEMDS \
12676                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12677                awk '/ldlm_cancel/ {print $2}')
12678         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12679                awk '/ldlm_bl_callback/ {print $2}')
12680         touch $DIR/$tdir/f1
12681         can2=$(do_facet $SINGLEMDS \
12682                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12683                awk '/ldlm_cancel/ {print $2}')
12684         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12685                awk '/ldlm_bl_callback/ {print $2}')
12686         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12687         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12688         lru_resize_enable mdc
12689         lru_resize_enable osc
12690 }
12691 run_test 120b "Early Lock Cancel: create test"
12692
12693 test_120c() {
12694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12695         remote_mds_nodsh && skip "remote MDS with nodsh"
12696         test_mkdir -i0 -c1 $DIR/$tdir
12697         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12698                 skip "no early lock cancel on server"
12699
12700         lru_resize_disable mdc
12701         lru_resize_disable osc
12702         test_mkdir -i0 -c1 $DIR/$tdir/d1
12703         test_mkdir -i0 -c1 $DIR/$tdir/d2
12704         touch $DIR/$tdir/d1/f1
12705         cancel_lru_locks mdc
12706         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12707         can1=$(do_facet mds1 \
12708                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12709                awk '/ldlm_cancel/ {print $2}')
12710         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12711                awk '/ldlm_bl_callback/ {print $2}')
12712         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12713         can2=$(do_facet mds1 \
12714                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12715                awk '/ldlm_cancel/ {print $2}')
12716         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12717                awk '/ldlm_bl_callback/ {print $2}')
12718         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12719         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12720         lru_resize_enable mdc
12721         lru_resize_enable osc
12722 }
12723 run_test 120c "Early Lock Cancel: link test"
12724
12725 test_120d() {
12726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12727         remote_mds_nodsh && skip "remote MDS with nodsh"
12728         test_mkdir -i0 -c1 $DIR/$tdir
12729         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12730                 skip_env "no early lock cancel on server"
12731
12732         lru_resize_disable mdc
12733         lru_resize_disable osc
12734         touch $DIR/$tdir
12735         cancel_lru_locks mdc
12736         stat $DIR/$tdir > /dev/null
12737         can1=$(do_facet mds1 \
12738                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12739                awk '/ldlm_cancel/ {print $2}')
12740         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12741                awk '/ldlm_bl_callback/ {print $2}')
12742         chmod a+x $DIR/$tdir
12743         can2=$(do_facet mds1 \
12744                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12745                awk '/ldlm_cancel/ {print $2}')
12746         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12747                awk '/ldlm_bl_callback/ {print $2}')
12748         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12749         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12750         lru_resize_enable mdc
12751         lru_resize_enable osc
12752 }
12753 run_test 120d "Early Lock Cancel: setattr test"
12754
12755 test_120e() {
12756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12757         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12758                 skip_env "no early lock cancel on server"
12759         remote_mds_nodsh && skip "remote MDS with nodsh"
12760
12761         local dlmtrace_set=false
12762
12763         test_mkdir -i0 -c1 $DIR/$tdir
12764         lru_resize_disable mdc
12765         lru_resize_disable osc
12766         ! $LCTL get_param debug | grep -q dlmtrace &&
12767                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12768         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12769         cancel_lru_locks mdc
12770         cancel_lru_locks osc
12771         dd if=$DIR/$tdir/f1 of=/dev/null
12772         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12773         # XXX client can not do early lock cancel of OST lock
12774         # during unlink (LU-4206), so cancel osc lock now.
12775         sleep 2
12776         cancel_lru_locks osc
12777         can1=$(do_facet mds1 \
12778                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12779                awk '/ldlm_cancel/ {print $2}')
12780         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12781                awk '/ldlm_bl_callback/ {print $2}')
12782         unlink $DIR/$tdir/f1
12783         sleep 5
12784         can2=$(do_facet mds1 \
12785                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12786                awk '/ldlm_cancel/ {print $2}')
12787         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12788                awk '/ldlm_bl_callback/ {print $2}')
12789         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12790                 $LCTL dk $TMP/cancel.debug.txt
12791         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12792                 $LCTL dk $TMP/blocking.debug.txt
12793         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12794         lru_resize_enable mdc
12795         lru_resize_enable osc
12796 }
12797 run_test 120e "Early Lock Cancel: unlink test"
12798
12799 test_120f() {
12800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12801         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12802                 skip_env "no early lock cancel on server"
12803         remote_mds_nodsh && skip "remote MDS with nodsh"
12804
12805         test_mkdir -i0 -c1 $DIR/$tdir
12806         lru_resize_disable mdc
12807         lru_resize_disable osc
12808         test_mkdir -i0 -c1 $DIR/$tdir/d1
12809         test_mkdir -i0 -c1 $DIR/$tdir/d2
12810         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12811         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12812         cancel_lru_locks mdc
12813         cancel_lru_locks osc
12814         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12815         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12816         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12817         # XXX client can not do early lock cancel of OST lock
12818         # during rename (LU-4206), so cancel osc lock now.
12819         sleep 2
12820         cancel_lru_locks osc
12821         can1=$(do_facet mds1 \
12822                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12823                awk '/ldlm_cancel/ {print $2}')
12824         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12825                awk '/ldlm_bl_callback/ {print $2}')
12826         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12827         sleep 5
12828         can2=$(do_facet mds1 \
12829                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12830                awk '/ldlm_cancel/ {print $2}')
12831         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12832                awk '/ldlm_bl_callback/ {print $2}')
12833         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12834         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12835         lru_resize_enable mdc
12836         lru_resize_enable osc
12837 }
12838 run_test 120f "Early Lock Cancel: rename test"
12839
12840 test_120g() {
12841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12842         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12843                 skip_env "no early lock cancel on server"
12844         remote_mds_nodsh && skip "remote MDS with nodsh"
12845
12846         lru_resize_disable mdc
12847         lru_resize_disable osc
12848         count=10000
12849         echo create $count files
12850         test_mkdir $DIR/$tdir
12851         cancel_lru_locks mdc
12852         cancel_lru_locks osc
12853         t0=$(date +%s)
12854
12855         can0=$(do_facet $SINGLEMDS \
12856                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12857                awk '/ldlm_cancel/ {print $2}')
12858         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12859                awk '/ldlm_bl_callback/ {print $2}')
12860         createmany -o $DIR/$tdir/f $count
12861         sync
12862         can1=$(do_facet $SINGLEMDS \
12863                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12864                awk '/ldlm_cancel/ {print $2}')
12865         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12866                awk '/ldlm_bl_callback/ {print $2}')
12867         t1=$(date +%s)
12868         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12869         echo rm $count files
12870         rm -r $DIR/$tdir
12871         sync
12872         can2=$(do_facet $SINGLEMDS \
12873                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12874                awk '/ldlm_cancel/ {print $2}')
12875         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12876                awk '/ldlm_bl_callback/ {print $2}')
12877         t2=$(date +%s)
12878         echo total: $count removes in $((t2-t1))
12879         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12880         sleep 2
12881         # wait for commitment of removal
12882         lru_resize_enable mdc
12883         lru_resize_enable osc
12884 }
12885 run_test 120g "Early Lock Cancel: performance test"
12886
12887 test_121() { #bug #10589
12888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12889
12890         rm -rf $DIR/$tfile
12891         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12892 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12893         lctl set_param fail_loc=0x310
12894         cancel_lru_locks osc > /dev/null
12895         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12896         lctl set_param fail_loc=0
12897         [[ $reads -eq $writes ]] ||
12898                 error "read $reads blocks, must be $writes blocks"
12899 }
12900 run_test 121 "read cancel race ========="
12901
12902 test_123a_base() { # was test 123, statahead(bug 11401)
12903         local lsx="$1"
12904
12905         SLOWOK=0
12906         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12907                 log "testing UP system. Performance may be lower than expected."
12908                 SLOWOK=1
12909         fi
12910
12911         rm -rf $DIR/$tdir
12912         test_mkdir $DIR/$tdir
12913         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12914         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12915         MULT=10
12916         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12917                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12918
12919                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12920                 lctl set_param -n llite.*.statahead_max 0
12921                 lctl get_param llite.*.statahead_max
12922                 cancel_lru_locks mdc
12923                 cancel_lru_locks osc
12924                 stime=$(date +%s)
12925                 time $lsx $DIR/$tdir | wc -l
12926                 etime=$(date +%s)
12927                 delta=$((etime - stime))
12928                 log "$lsx $i files without statahead: $delta sec"
12929                 lctl set_param llite.*.statahead_max=$max
12930
12931                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12932                         grep "statahead wrong:" | awk '{print $3}')
12933                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12934                 cancel_lru_locks mdc
12935                 cancel_lru_locks osc
12936                 stime=$(date +%s)
12937                 time $lsx $DIR/$tdir | wc -l
12938                 etime=$(date +%s)
12939                 delta_sa=$((etime - stime))
12940                 log "$lsx $i files with statahead: $delta_sa sec"
12941                 lctl get_param -n llite.*.statahead_stats
12942                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12943                         grep "statahead wrong:" | awk '{print $3}')
12944
12945                 [[ $swrong -lt $ewrong ]] &&
12946                         log "statahead was stopped, maybe too many locks held!"
12947                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12948
12949                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12950                         max=$(lctl get_param -n llite.*.statahead_max |
12951                                 head -n 1)
12952                         lctl set_param -n llite.*.statahead_max 0
12953                         lctl get_param llite.*.statahead_max
12954                         cancel_lru_locks mdc
12955                         cancel_lru_locks osc
12956                         stime=$(date +%s)
12957                         time $lsx $DIR/$tdir | wc -l
12958                         etime=$(date +%s)
12959                         delta=$((etime - stime))
12960                         log "$lsx $i files again without statahead: $delta sec"
12961                         lctl set_param llite.*.statahead_max=$max
12962                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12963                                 if [  $SLOWOK -eq 0 ]; then
12964                                         error "$lsx $i files is slower with statahead!"
12965                                 else
12966                                         log "$lsx $i files is slower with statahead!"
12967                                 fi
12968                                 break
12969                         fi
12970                 fi
12971
12972                 [ $delta -gt 20 ] && break
12973                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12974                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12975         done
12976         log "$lsx done"
12977
12978         stime=$(date +%s)
12979         rm -r $DIR/$tdir
12980         sync
12981         etime=$(date +%s)
12982         delta=$((etime - stime))
12983         log "rm -r $DIR/$tdir/: $delta seconds"
12984         log "rm done"
12985         lctl get_param -n llite.*.statahead_stats
12986 }
12987
12988 test_123aa() {
12989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12990
12991         test_123a_base "ls -l"
12992 }
12993 run_test 123aa "verify statahead work"
12994
12995 test_123ab() {
12996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12997
12998         statx_supported || skip_env "Test must be statx() syscall supported"
12999
13000         test_123a_base "$STATX -l"
13001 }
13002 run_test 123ab "verify statahead work by using statx"
13003
13004 test_123ac() {
13005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13006
13007         statx_supported || skip_env "Test must be statx() syscall supported"
13008
13009         local rpcs_before
13010         local rpcs_after
13011         local agl_before
13012         local agl_after
13013
13014         cancel_lru_locks $OSC
13015         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13016         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13017                 awk '/agl.total:/ {print $3}')
13018         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13019         test_123a_base "$STATX --cached=always -D"
13020         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13021                 awk '/agl.total:/ {print $3}')
13022         [ $agl_before -eq $agl_after ] ||
13023                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13024         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13025         [ $rpcs_after -eq $rpcs_before ] ||
13026                 error "$STATX should not send glimpse RPCs to $OSC"
13027 }
13028 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13029
13030 test_123b () { # statahead(bug 15027)
13031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13032
13033         test_mkdir $DIR/$tdir
13034         createmany -o $DIR/$tdir/$tfile-%d 1000
13035
13036         cancel_lru_locks mdc
13037         cancel_lru_locks osc
13038
13039 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13040         lctl set_param fail_loc=0x80000803
13041         ls -lR $DIR/$tdir > /dev/null
13042         log "ls done"
13043         lctl set_param fail_loc=0x0
13044         lctl get_param -n llite.*.statahead_stats
13045         rm -r $DIR/$tdir
13046         sync
13047
13048 }
13049 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13050
13051 test_123c() {
13052         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13053
13054         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13055         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13056         touch $DIR/$tdir.1/{1..3}
13057         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13058
13059         remount_client $MOUNT
13060
13061         $MULTIOP $DIR/$tdir.0 Q
13062
13063         # let statahead to complete
13064         ls -l $DIR/$tdir.0 > /dev/null
13065
13066         testid=$(echo $TESTNAME | tr '_' ' ')
13067         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13068                 error "statahead warning" || true
13069 }
13070 run_test 123c "Can not initialize inode warning on DNE statahead"
13071
13072 test_124a() {
13073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13074         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13075                 skip_env "no lru resize on server"
13076
13077         local NR=2000
13078
13079         test_mkdir $DIR/$tdir
13080
13081         log "create $NR files at $DIR/$tdir"
13082         createmany -o $DIR/$tdir/f $NR ||
13083                 error "failed to create $NR files in $DIR/$tdir"
13084
13085         cancel_lru_locks mdc
13086         ls -l $DIR/$tdir > /dev/null
13087
13088         local NSDIR=""
13089         local LRU_SIZE=0
13090         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13091                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13092                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13093                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13094                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13095                         log "NSDIR=$NSDIR"
13096                         log "NS=$(basename $NSDIR)"
13097                         break
13098                 fi
13099         done
13100
13101         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13102                 skip "Not enough cached locks created!"
13103         fi
13104         log "LRU=$LRU_SIZE"
13105
13106         local SLEEP=30
13107
13108         # We know that lru resize allows one client to hold $LIMIT locks
13109         # for 10h. After that locks begin to be killed by client.
13110         local MAX_HRS=10
13111         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13112         log "LIMIT=$LIMIT"
13113         if [ $LIMIT -lt $LRU_SIZE ]; then
13114                 skip "Limit is too small $LIMIT"
13115         fi
13116
13117         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13118         # killing locks. Some time was spent for creating locks. This means
13119         # that up to the moment of sleep finish we must have killed some of
13120         # them (10-100 locks). This depends on how fast ther were created.
13121         # Many of them were touched in almost the same moment and thus will
13122         # be killed in groups.
13123         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13124
13125         # Use $LRU_SIZE_B here to take into account real number of locks
13126         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13127         local LRU_SIZE_B=$LRU_SIZE
13128         log "LVF=$LVF"
13129         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13130         log "OLD_LVF=$OLD_LVF"
13131         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13132
13133         # Let's make sure that we really have some margin. Client checks
13134         # cached locks every 10 sec.
13135         SLEEP=$((SLEEP+20))
13136         log "Sleep ${SLEEP} sec"
13137         local SEC=0
13138         while ((SEC<$SLEEP)); do
13139                 echo -n "..."
13140                 sleep 5
13141                 SEC=$((SEC+5))
13142                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13143                 echo -n "$LRU_SIZE"
13144         done
13145         echo ""
13146         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13147         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13148
13149         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13150                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13151                 unlinkmany $DIR/$tdir/f $NR
13152                 return
13153         }
13154
13155         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13156         log "unlink $NR files at $DIR/$tdir"
13157         unlinkmany $DIR/$tdir/f $NR
13158 }
13159 run_test 124a "lru resize ======================================="
13160
13161 get_max_pool_limit()
13162 {
13163         local limit=$($LCTL get_param \
13164                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13165         local max=0
13166         for l in $limit; do
13167                 if [[ $l -gt $max ]]; then
13168                         max=$l
13169                 fi
13170         done
13171         echo $max
13172 }
13173
13174 test_124b() {
13175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13176         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13177                 skip_env "no lru resize on server"
13178
13179         LIMIT=$(get_max_pool_limit)
13180
13181         NR=$(($(default_lru_size)*20))
13182         if [[ $NR -gt $LIMIT ]]; then
13183                 log "Limit lock number by $LIMIT locks"
13184                 NR=$LIMIT
13185         fi
13186
13187         IFree=$(mdsrate_inodes_available)
13188         if [ $IFree -lt $NR ]; then
13189                 log "Limit lock number by $IFree inodes"
13190                 NR=$IFree
13191         fi
13192
13193         lru_resize_disable mdc
13194         test_mkdir -p $DIR/$tdir/disable_lru_resize
13195
13196         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13197         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13198         cancel_lru_locks mdc
13199         stime=`date +%s`
13200         PID=""
13201         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13202         PID="$PID $!"
13203         sleep 2
13204         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13205         PID="$PID $!"
13206         sleep 2
13207         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13208         PID="$PID $!"
13209         wait $PID
13210         etime=`date +%s`
13211         nolruresize_delta=$((etime-stime))
13212         log "ls -la time: $nolruresize_delta seconds"
13213         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13214         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13215
13216         lru_resize_enable mdc
13217         test_mkdir -p $DIR/$tdir/enable_lru_resize
13218
13219         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13220         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13221         cancel_lru_locks mdc
13222         stime=`date +%s`
13223         PID=""
13224         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13225         PID="$PID $!"
13226         sleep 2
13227         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13228         PID="$PID $!"
13229         sleep 2
13230         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13231         PID="$PID $!"
13232         wait $PID
13233         etime=`date +%s`
13234         lruresize_delta=$((etime-stime))
13235         log "ls -la time: $lruresize_delta seconds"
13236         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13237
13238         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13239                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13240         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13241                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13242         else
13243                 log "lru resize performs the same with no lru resize"
13244         fi
13245         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13246 }
13247 run_test 124b "lru resize (performance test) ======================="
13248
13249 test_124c() {
13250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13251         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13252                 skip_env "no lru resize on server"
13253
13254         # cache ununsed locks on client
13255         local nr=100
13256         cancel_lru_locks mdc
13257         test_mkdir $DIR/$tdir
13258         createmany -o $DIR/$tdir/f $nr ||
13259                 error "failed to create $nr files in $DIR/$tdir"
13260         ls -l $DIR/$tdir > /dev/null
13261
13262         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13263         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13264         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13265         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13266         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13267
13268         # set lru_max_age to 1 sec
13269         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13270         echo "sleep $((recalc_p * 2)) seconds..."
13271         sleep $((recalc_p * 2))
13272
13273         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13274         # restore lru_max_age
13275         $LCTL set_param -n $nsdir.lru_max_age $max_age
13276         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13277         unlinkmany $DIR/$tdir/f $nr
13278 }
13279 run_test 124c "LRUR cancel very aged locks"
13280
13281 test_124d() {
13282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13283         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13284                 skip_env "no lru resize on server"
13285
13286         # cache ununsed locks on client
13287         local nr=100
13288
13289         lru_resize_disable mdc
13290         stack_trap "lru_resize_enable mdc" EXIT
13291
13292         cancel_lru_locks mdc
13293
13294         # asynchronous object destroy at MDT could cause bl ast to client
13295         test_mkdir $DIR/$tdir
13296         createmany -o $DIR/$tdir/f $nr ||
13297                 error "failed to create $nr files in $DIR/$tdir"
13298         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13299
13300         ls -l $DIR/$tdir > /dev/null
13301
13302         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13303         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13304         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13305         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13306
13307         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13308
13309         # set lru_max_age to 1 sec
13310         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13311         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13312
13313         echo "sleep $((recalc_p * 2)) seconds..."
13314         sleep $((recalc_p * 2))
13315
13316         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13317
13318         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13319 }
13320 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13321
13322 test_125() { # 13358
13323         $LCTL get_param -n llite.*.client_type | grep -q local ||
13324                 skip "must run as local client"
13325         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13326                 skip_env "must have acl enabled"
13327         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13328
13329         test_mkdir $DIR/$tdir
13330         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13331         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13332         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13333 }
13334 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13335
13336 test_126() { # bug 12829/13455
13337         $GSS && skip_env "must run as gss disabled"
13338         $LCTL get_param -n llite.*.client_type | grep -q local ||
13339                 skip "must run as local client"
13340         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13341
13342         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13343         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13344         rm -f $DIR/$tfile
13345         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13346 }
13347 run_test 126 "check that the fsgid provided by the client is taken into account"
13348
13349 test_127a() { # bug 15521
13350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13351         local name count samp unit min max sum sumsq
13352
13353         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13354         echo "stats before reset"
13355         $LCTL get_param osc.*.stats
13356         $LCTL set_param osc.*.stats=0
13357         local fsize=$((2048 * 1024))
13358
13359         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13360         cancel_lru_locks osc
13361         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13362
13363         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13364         stack_trap "rm -f $TMP/$tfile.tmp"
13365         while read name count samp unit min max sum sumsq; do
13366                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13367                 [ ! $min ] && error "Missing min value for $name proc entry"
13368                 eval $name=$count || error "Wrong proc format"
13369
13370                 case $name in
13371                 read_bytes|write_bytes)
13372                         [[ "$unit" =~ "bytes" ]] ||
13373                                 error "unit is not 'bytes': $unit"
13374                         (( $min >= 4096 )) || error "min is too small: $min"
13375                         (( $min <= $fsize )) || error "min is too big: $min"
13376                         (( $max >= 4096 )) || error "max is too small: $max"
13377                         (( $max <= $fsize )) || error "max is too big: $max"
13378                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13379                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13380                                 error "sumsquare is too small: $sumsq"
13381                         (( $sumsq <= $fsize * $fsize )) ||
13382                                 error "sumsquare is too big: $sumsq"
13383                         ;;
13384                 ost_read|ost_write)
13385                         [[ "$unit" =~ "usec" ]] ||
13386                                 error "unit is not 'usec': $unit"
13387                         ;;
13388                 *)      ;;
13389                 esac
13390         done < $DIR/$tfile.tmp
13391
13392         #check that we actually got some stats
13393         [ "$read_bytes" ] || error "Missing read_bytes stats"
13394         [ "$write_bytes" ] || error "Missing write_bytes stats"
13395         [ "$read_bytes" != 0 ] || error "no read done"
13396         [ "$write_bytes" != 0 ] || error "no write done"
13397 }
13398 run_test 127a "verify the client stats are sane"
13399
13400 test_127b() { # bug LU-333
13401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13402         local name count samp unit min max sum sumsq
13403
13404         echo "stats before reset"
13405         $LCTL get_param llite.*.stats
13406         $LCTL set_param llite.*.stats=0
13407
13408         # perform 2 reads and writes so MAX is different from SUM.
13409         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13410         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13411         cancel_lru_locks osc
13412         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13413         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13414
13415         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13416         stack_trap "rm -f $TMP/$tfile.tmp"
13417         while read name count samp unit min max sum sumsq; do
13418                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13419                 eval $name=$count || error "Wrong proc format"
13420
13421                 case $name in
13422                 read_bytes|write_bytes)
13423                         [[ "$unit" =~ "bytes" ]] ||
13424                                 error "unit is not 'bytes': $unit"
13425                         (( $count == 2 )) || error "count is not 2: $count"
13426                         (( $min == $PAGE_SIZE )) ||
13427                                 error "min is not $PAGE_SIZE: $min"
13428                         (( $max == $PAGE_SIZE )) ||
13429                                 error "max is not $PAGE_SIZE: $max"
13430                         (( $sum == $PAGE_SIZE * 2 )) ||
13431                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13432                         ;;
13433                 read|write)
13434                         [[ "$unit" =~ "usec" ]] ||
13435                                 error "unit is not 'usec': $unit"
13436                         ;;
13437                 *)      ;;
13438                 esac
13439         done < $TMP/$tfile.tmp
13440
13441         #check that we actually got some stats
13442         [ "$read_bytes" ] || error "Missing read_bytes stats"
13443         [ "$write_bytes" ] || error "Missing write_bytes stats"
13444         [ "$read_bytes" != 0 ] || error "no read done"
13445         [ "$write_bytes" != 0 ] || error "no write done"
13446 }
13447 run_test 127b "verify the llite client stats are sane"
13448
13449 test_127c() { # LU-12394
13450         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13451         local size
13452         local bsize
13453         local reads
13454         local writes
13455         local count
13456
13457         $LCTL set_param llite.*.extents_stats=1
13458         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13459
13460         # Use two stripes so there is enough space in default config
13461         $LFS setstripe -c 2 $DIR/$tfile
13462
13463         # Extent stats start at 0-4K and go in power of two buckets
13464         # LL_HIST_START = 12 --> 2^12 = 4K
13465         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13466         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13467         # small configs
13468         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13469                 do
13470                 # Write and read, 2x each, second time at a non-zero offset
13471                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13472                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13473                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13474                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13475                 rm -f $DIR/$tfile
13476         done
13477
13478         $LCTL get_param llite.*.extents_stats
13479
13480         count=2
13481         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13482                 do
13483                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13484                                 grep -m 1 $bsize)
13485                 reads=$(echo $bucket | awk '{print $5}')
13486                 writes=$(echo $bucket | awk '{print $9}')
13487                 [ "$reads" -eq $count ] ||
13488                         error "$reads reads in < $bsize bucket, expect $count"
13489                 [ "$writes" -eq $count ] ||
13490                         error "$writes writes in < $bsize bucket, expect $count"
13491         done
13492
13493         # Test mmap write and read
13494         $LCTL set_param llite.*.extents_stats=c
13495         size=512
13496         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13497         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13498         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13499
13500         $LCTL get_param llite.*.extents_stats
13501
13502         count=$(((size*1024) / PAGE_SIZE))
13503
13504         bsize=$((2 * PAGE_SIZE / 1024))K
13505
13506         bucket=$($LCTL get_param -n llite.*.extents_stats |
13507                         grep -m 1 $bsize)
13508         reads=$(echo $bucket | awk '{print $5}')
13509         writes=$(echo $bucket | awk '{print $9}')
13510         # mmap writes fault in the page first, creating an additonal read
13511         [ "$reads" -eq $((2 * count)) ] ||
13512                 error "$reads reads in < $bsize bucket, expect $count"
13513         [ "$writes" -eq $count ] ||
13514                 error "$writes writes in < $bsize bucket, expect $count"
13515 }
13516 run_test 127c "test llite extent stats with regular & mmap i/o"
13517
13518 test_128() { # bug 15212
13519         touch $DIR/$tfile
13520         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13521                 find $DIR/$tfile
13522                 find $DIR/$tfile
13523         EOF
13524
13525         result=$(grep error $TMP/$tfile.log)
13526         rm -f $DIR/$tfile $TMP/$tfile.log
13527         [ -z "$result" ] ||
13528                 error "consecutive find's under interactive lfs failed"
13529 }
13530 run_test 128 "interactive lfs for 2 consecutive find's"
13531
13532 set_dir_limits () {
13533         local mntdev
13534         local canondev
13535         local node
13536
13537         local ldproc=/proc/fs/ldiskfs
13538         local facets=$(get_facets MDS)
13539
13540         for facet in ${facets//,/ }; do
13541                 canondev=$(ldiskfs_canon \
13542                            *.$(convert_facet2label $facet).mntdev $facet)
13543                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13544                         ldproc=/sys/fs/ldiskfs
13545                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13546                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13547         done
13548 }
13549
13550 check_mds_dmesg() {
13551         local facets=$(get_facets MDS)
13552         for facet in ${facets//,/ }; do
13553                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13554         done
13555         return 1
13556 }
13557
13558 test_129() {
13559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13560         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13561                 skip "Need MDS version with at least 2.5.56"
13562         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13563                 skip_env "ldiskfs only test"
13564         fi
13565         remote_mds_nodsh && skip "remote MDS with nodsh"
13566
13567         local ENOSPC=28
13568         local has_warning=false
13569
13570         rm -rf $DIR/$tdir
13571         mkdir -p $DIR/$tdir
13572
13573         # block size of mds1
13574         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13575         set_dir_limits $maxsize $((maxsize * 6 / 8))
13576         stack_trap "set_dir_limits 0 0"
13577         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13578         local dirsize=$(stat -c%s "$DIR/$tdir")
13579         local nfiles=0
13580         while (( $dirsize <= $maxsize )); do
13581                 $MCREATE $DIR/$tdir/file_base_$nfiles
13582                 rc=$?
13583                 # check two errors:
13584                 # ENOSPC for ext4 max_dir_size, which has been used since
13585                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13586                 if (( rc == ENOSPC )); then
13587                         set_dir_limits 0 0
13588                         echo "rc=$rc returned as expected after $nfiles files"
13589
13590                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13591                                 error "create failed w/o dir size limit"
13592
13593                         # messages may be rate limited if test is run repeatedly
13594                         check_mds_dmesg '"is approaching max"' ||
13595                                 echo "warning message should be output"
13596                         check_mds_dmesg '"has reached max"' ||
13597                                 echo "reached message should be output"
13598
13599                         dirsize=$(stat -c%s "$DIR/$tdir")
13600
13601                         [[ $dirsize -ge $maxsize ]] && return 0
13602                         error "dirsize $dirsize < $maxsize after $nfiles files"
13603                 elif (( rc != 0 )); then
13604                         break
13605                 fi
13606                 nfiles=$((nfiles + 1))
13607                 dirsize=$(stat -c%s "$DIR/$tdir")
13608         done
13609
13610         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13611 }
13612 run_test 129 "test directory size limit ========================"
13613
13614 OLDIFS="$IFS"
13615 cleanup_130() {
13616         trap 0
13617         IFS="$OLDIFS"
13618 }
13619
13620 test_130a() {
13621         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13622         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13623
13624         trap cleanup_130 EXIT RETURN
13625
13626         local fm_file=$DIR/$tfile
13627         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13628         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13629                 error "dd failed for $fm_file"
13630
13631         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13632         filefrag -ves $fm_file
13633         RC=$?
13634         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13635                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13636         [ $RC != 0 ] && error "filefrag $fm_file failed"
13637
13638         filefrag_op=$(filefrag -ve -k $fm_file |
13639                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13640         lun=$($LFS getstripe -i $fm_file)
13641
13642         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13643         IFS=$'\n'
13644         tot_len=0
13645         for line in $filefrag_op
13646         do
13647                 frag_lun=`echo $line | cut -d: -f5`
13648                 ext_len=`echo $line | cut -d: -f4`
13649                 if (( $frag_lun != $lun )); then
13650                         cleanup_130
13651                         error "FIEMAP on 1-stripe file($fm_file) failed"
13652                         return
13653                 fi
13654                 (( tot_len += ext_len ))
13655         done
13656
13657         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13658                 cleanup_130
13659                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13660                 return
13661         fi
13662
13663         cleanup_130
13664
13665         echo "FIEMAP on single striped file succeeded"
13666 }
13667 run_test 130a "FIEMAP (1-stripe file)"
13668
13669 test_130b() {
13670         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13671
13672         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13673         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13674
13675         trap cleanup_130 EXIT RETURN
13676
13677         local fm_file=$DIR/$tfile
13678         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13679                         error "setstripe on $fm_file"
13680         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13681                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13682
13683         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13684                 error "dd failed on $fm_file"
13685
13686         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13687         filefrag_op=$(filefrag -ve -k $fm_file |
13688                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13689
13690         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13691                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13692
13693         IFS=$'\n'
13694         tot_len=0
13695         num_luns=1
13696         for line in $filefrag_op
13697         do
13698                 frag_lun=$(echo $line | cut -d: -f5 |
13699                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13700                 ext_len=$(echo $line | cut -d: -f4)
13701                 if (( $frag_lun != $last_lun )); then
13702                         if (( tot_len != 1024 )); then
13703                                 cleanup_130
13704                                 error "FIEMAP on $fm_file failed; returned " \
13705                                 "len $tot_len for OST $last_lun instead of 1024"
13706                                 return
13707                         else
13708                                 (( num_luns += 1 ))
13709                                 tot_len=0
13710                         fi
13711                 fi
13712                 (( tot_len += ext_len ))
13713                 last_lun=$frag_lun
13714         done
13715         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13716                 cleanup_130
13717                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13718                         "luns or wrong len for OST $last_lun"
13719                 return
13720         fi
13721
13722         cleanup_130
13723
13724         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13725 }
13726 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13727
13728 test_130c() {
13729         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13730
13731         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13732         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13733
13734         trap cleanup_130 EXIT RETURN
13735
13736         local fm_file=$DIR/$tfile
13737         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13738         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13739                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13740
13741         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13742                         error "dd failed on $fm_file"
13743
13744         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13745         filefrag_op=$(filefrag -ve -k $fm_file |
13746                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13747
13748         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13749                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13750
13751         IFS=$'\n'
13752         tot_len=0
13753         num_luns=1
13754         for line in $filefrag_op
13755         do
13756                 frag_lun=$(echo $line | cut -d: -f5 |
13757                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13758                 ext_len=$(echo $line | cut -d: -f4)
13759                 if (( $frag_lun != $last_lun )); then
13760                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13761                         if (( logical != 512 )); then
13762                                 cleanup_130
13763                                 error "FIEMAP on $fm_file failed; returned " \
13764                                 "logical start for lun $logical instead of 512"
13765                                 return
13766                         fi
13767                         if (( tot_len != 512 )); then
13768                                 cleanup_130
13769                                 error "FIEMAP on $fm_file failed; returned " \
13770                                 "len $tot_len for OST $last_lun instead of 1024"
13771                                 return
13772                         else
13773                                 (( num_luns += 1 ))
13774                                 tot_len=0
13775                         fi
13776                 fi
13777                 (( tot_len += ext_len ))
13778                 last_lun=$frag_lun
13779         done
13780         if (( num_luns != 2 || tot_len != 512 )); then
13781                 cleanup_130
13782                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13783                         "luns or wrong len for OST $last_lun"
13784                 return
13785         fi
13786
13787         cleanup_130
13788
13789         echo "FIEMAP on 2-stripe file with hole succeeded"
13790 }
13791 run_test 130c "FIEMAP (2-stripe file with hole)"
13792
13793 test_130d() {
13794         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13795
13796         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13797         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13798
13799         trap cleanup_130 EXIT RETURN
13800
13801         local fm_file=$DIR/$tfile
13802         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13803                         error "setstripe on $fm_file"
13804         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13805                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13806
13807         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13808         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13809                 error "dd failed on $fm_file"
13810
13811         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13812         filefrag_op=$(filefrag -ve -k $fm_file |
13813                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13814
13815         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13816                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13817
13818         IFS=$'\n'
13819         tot_len=0
13820         num_luns=1
13821         for line in $filefrag_op
13822         do
13823                 frag_lun=$(echo $line | cut -d: -f5 |
13824                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13825                 ext_len=$(echo $line | cut -d: -f4)
13826                 if (( $frag_lun != $last_lun )); then
13827                         if (( tot_len != 1024 )); then
13828                                 cleanup_130
13829                                 error "FIEMAP on $fm_file failed; returned " \
13830                                 "len $tot_len for OST $last_lun instead of 1024"
13831                                 return
13832                         else
13833                                 (( num_luns += 1 ))
13834                                 tot_len=0
13835                         fi
13836                 fi
13837                 (( tot_len += ext_len ))
13838                 last_lun=$frag_lun
13839         done
13840         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13841                 cleanup_130
13842                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13843                         "luns or wrong len for OST $last_lun"
13844                 return
13845         fi
13846
13847         cleanup_130
13848
13849         echo "FIEMAP on N-stripe file succeeded"
13850 }
13851 run_test 130d "FIEMAP (N-stripe file)"
13852
13853 test_130e() {
13854         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13855
13856         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13857         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13858
13859         trap cleanup_130 EXIT RETURN
13860
13861         local fm_file=$DIR/$tfile
13862         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13863
13864         NUM_BLKS=512
13865         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13866         for ((i = 0; i < $NUM_BLKS; i++)); do
13867                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13868                         conv=notrunc > /dev/null 2>&1
13869         done
13870
13871         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13872         filefrag_op=$(filefrag -ve -k $fm_file |
13873                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13874
13875         last_lun=$(echo $filefrag_op | cut -d: -f5)
13876
13877         IFS=$'\n'
13878         tot_len=0
13879         num_luns=1
13880         for line in $filefrag_op; do
13881                 frag_lun=$(echo $line | cut -d: -f5)
13882                 ext_len=$(echo $line | cut -d: -f4)
13883                 if [[ "$frag_lun" != "$last_lun" ]]; then
13884                         if (( tot_len != $EXPECTED_LEN )); then
13885                                 cleanup_130
13886                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13887                         else
13888                                 (( num_luns += 1 ))
13889                                 tot_len=0
13890                         fi
13891                 fi
13892                 (( tot_len += ext_len ))
13893                 last_lun=$frag_lun
13894         done
13895         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13896                 cleanup_130
13897                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13898         fi
13899
13900         echo "FIEMAP with continuation calls succeeded"
13901 }
13902 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13903
13904 test_130f() {
13905         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13906         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13907
13908         local fm_file=$DIR/$tfile
13909         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13910                 error "multiop create with lov_delay_create on $fm_file"
13911
13912         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13913         filefrag_extents=$(filefrag -vek $fm_file |
13914                            awk '/extents? found/ { print $2 }')
13915         if [[ "$filefrag_extents" != "0" ]]; then
13916                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13917         fi
13918
13919         rm -f $fm_file
13920 }
13921 run_test 130f "FIEMAP (unstriped file)"
13922
13923 test_130g() {
13924         local file=$DIR/$tfile
13925         local nr=$((OSTCOUNT * 100))
13926
13927         $LFS setstripe -C $nr $file ||
13928                 error "failed to setstripe -C $nr $file"
13929
13930         dd if=/dev/zero of=$file count=$nr bs=1M
13931         sync
13932         nr=$($LFS getstripe -c $file)
13933
13934         local extents=$(filefrag -v $file |
13935                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13936
13937         echo "filefrag list $extents extents in file with stripecount $nr"
13938         if (( extents < nr )); then
13939                 $LFS getstripe $file
13940                 filefrag -v $file
13941                 error "filefrag printed $extents < $nr extents"
13942         fi
13943
13944         rm -f $file
13945 }
13946 run_test 130g "FIEMAP (overstripe file)"
13947
13948 # Test for writev/readv
13949 test_131a() {
13950         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13951                 error "writev test failed"
13952         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13953                 error "readv failed"
13954         rm -f $DIR/$tfile
13955 }
13956 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13957
13958 test_131b() {
13959         local fsize=$((524288 + 1048576 + 1572864))
13960         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13961                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13962                         error "append writev test failed"
13963
13964         ((fsize += 1572864 + 1048576))
13965         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13966                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13967                         error "append writev test failed"
13968         rm -f $DIR/$tfile
13969 }
13970 run_test 131b "test append writev"
13971
13972 test_131c() {
13973         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13974         error "NOT PASS"
13975 }
13976 run_test 131c "test read/write on file w/o objects"
13977
13978 test_131d() {
13979         rwv -f $DIR/$tfile -w -n 1 1572864
13980         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13981         if [ "$NOB" != 1572864 ]; then
13982                 error "Short read filed: read $NOB bytes instead of 1572864"
13983         fi
13984         rm -f $DIR/$tfile
13985 }
13986 run_test 131d "test short read"
13987
13988 test_131e() {
13989         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13990         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13991         error "read hitting hole failed"
13992         rm -f $DIR/$tfile
13993 }
13994 run_test 131e "test read hitting hole"
13995
13996 check_stats() {
13997         local facet=$1
13998         local op=$2
13999         local want=${3:-0}
14000         local res
14001
14002         case $facet in
14003         mds*) res=$(do_facet $facet \
14004                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
14005                  ;;
14006         ost*) res=$(do_facet $facet \
14007                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
14008                  ;;
14009         *) error "Wrong facet '$facet'" ;;
14010         esac
14011         [ "$res" ] || error "The counter for $op on $facet was not incremented"
14012         # if the argument $3 is zero, it means any stat increment is ok.
14013         if [[ $want -gt 0 ]]; then
14014                 local count=$(echo $res | awk '{ print $2 }')
14015                 [[ $count -ne $want ]] &&
14016                         error "The $op counter on $facet is $count, not $want"
14017         fi
14018 }
14019
14020 test_133a() {
14021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14022         remote_ost_nodsh && skip "remote OST with nodsh"
14023         remote_mds_nodsh && skip "remote MDS with nodsh"
14024         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14025                 skip_env "MDS doesn't support rename stats"
14026
14027         local testdir=$DIR/${tdir}/stats_testdir
14028
14029         mkdir -p $DIR/${tdir}
14030
14031         # clear stats.
14032         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14033         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14034
14035         # verify mdt stats first.
14036         mkdir ${testdir} || error "mkdir failed"
14037         check_stats $SINGLEMDS "mkdir" 1
14038         touch ${testdir}/${tfile} || error "touch failed"
14039         check_stats $SINGLEMDS "open" 1
14040         check_stats $SINGLEMDS "close" 1
14041         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14042                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14043                 check_stats $SINGLEMDS "mknod" 2
14044         }
14045         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14046         check_stats $SINGLEMDS "unlink" 1
14047         rm -f ${testdir}/${tfile} || error "file remove failed"
14048         check_stats $SINGLEMDS "unlink" 2
14049
14050         # remove working dir and check mdt stats again.
14051         rmdir ${testdir} || error "rmdir failed"
14052         check_stats $SINGLEMDS "rmdir" 1
14053
14054         local testdir1=$DIR/${tdir}/stats_testdir1
14055         mkdir -p ${testdir}
14056         mkdir -p ${testdir1}
14057         touch ${testdir1}/test1
14058         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14059         check_stats $SINGLEMDS "crossdir_rename" 1
14060
14061         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14062         check_stats $SINGLEMDS "samedir_rename" 1
14063
14064         rm -rf $DIR/${tdir}
14065 }
14066 run_test 133a "Verifying MDT stats ========================================"
14067
14068 test_133b() {
14069         local res
14070
14071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14072         remote_ost_nodsh && skip "remote OST with nodsh"
14073         remote_mds_nodsh && skip "remote MDS with nodsh"
14074
14075         local testdir=$DIR/${tdir}/stats_testdir
14076
14077         mkdir -p ${testdir} || error "mkdir failed"
14078         touch ${testdir}/${tfile} || error "touch failed"
14079         cancel_lru_locks mdc
14080
14081         # clear stats.
14082         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14083         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14084
14085         # extra mdt stats verification.
14086         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14087         check_stats $SINGLEMDS "setattr" 1
14088         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14089         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14090         then            # LU-1740
14091                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14092                 check_stats $SINGLEMDS "getattr" 1
14093         fi
14094         rm -rf $DIR/${tdir}
14095
14096         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14097         # so the check below is not reliable
14098         [ $MDSCOUNT -eq 1 ] || return 0
14099
14100         # Sleep to avoid a cached response.
14101         #define OBD_STATFS_CACHE_SECONDS 1
14102         sleep 2
14103         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14104         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14105         $LFS df || error "lfs failed"
14106         check_stats $SINGLEMDS "statfs" 1
14107
14108         # check aggregated statfs (LU-10018)
14109         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14110                 return 0
14111         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14112                 return 0
14113         sleep 2
14114         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14115         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14116         df $DIR
14117         check_stats $SINGLEMDS "statfs" 1
14118
14119         # We want to check that the client didn't send OST_STATFS to
14120         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14121         # extra care is needed here.
14122         if remote_mds; then
14123                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14124                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14125
14126                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14127                 [ "$res" ] && error "OST got STATFS"
14128         fi
14129
14130         return 0
14131 }
14132 run_test 133b "Verifying extra MDT stats =================================="
14133
14134 test_133c() {
14135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14136         remote_ost_nodsh && skip "remote OST with nodsh"
14137         remote_mds_nodsh && skip "remote MDS with nodsh"
14138
14139         local testdir=$DIR/$tdir/stats_testdir
14140
14141         test_mkdir -p $testdir
14142
14143         # verify obdfilter stats.
14144         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14145         sync
14146         cancel_lru_locks osc
14147         wait_delete_completed
14148
14149         # clear stats.
14150         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14151         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14152
14153         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14154                 error "dd failed"
14155         sync
14156         cancel_lru_locks osc
14157         check_stats ost1 "write" 1
14158
14159         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14160         check_stats ost1 "read" 1
14161
14162         > $testdir/$tfile || error "truncate failed"
14163         check_stats ost1 "punch" 1
14164
14165         rm -f $testdir/$tfile || error "file remove failed"
14166         wait_delete_completed
14167         check_stats ost1 "destroy" 1
14168
14169         rm -rf $DIR/$tdir
14170 }
14171 run_test 133c "Verifying OST stats ========================================"
14172
14173 order_2() {
14174         local value=$1
14175         local orig=$value
14176         local order=1
14177
14178         while [ $value -ge 2 ]; do
14179                 order=$((order*2))
14180                 value=$((value/2))
14181         done
14182
14183         if [ $orig -gt $order ]; then
14184                 order=$((order*2))
14185         fi
14186         echo $order
14187 }
14188
14189 size_in_KMGT() {
14190     local value=$1
14191     local size=('K' 'M' 'G' 'T');
14192     local i=0
14193     local size_string=$value
14194
14195     while [ $value -ge 1024 ]; do
14196         if [ $i -gt 3 ]; then
14197             #T is the biggest unit we get here, if that is bigger,
14198             #just return XXXT
14199             size_string=${value}T
14200             break
14201         fi
14202         value=$((value >> 10))
14203         if [ $value -lt 1024 ]; then
14204             size_string=${value}${size[$i]}
14205             break
14206         fi
14207         i=$((i + 1))
14208     done
14209
14210     echo $size_string
14211 }
14212
14213 get_rename_size() {
14214         local size=$1
14215         local context=${2:-.}
14216         local sample=$(do_facet $SINGLEMDS $LCTL \
14217                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14218                 grep -A1 $context |
14219                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14220         echo $sample
14221 }
14222
14223 test_133d() {
14224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14225         remote_ost_nodsh && skip "remote OST with nodsh"
14226         remote_mds_nodsh && skip "remote MDS with nodsh"
14227         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14228                 skip_env "MDS doesn't support rename stats"
14229
14230         local testdir1=$DIR/${tdir}/stats_testdir1
14231         local testdir2=$DIR/${tdir}/stats_testdir2
14232         mkdir -p $DIR/${tdir}
14233
14234         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14235
14236         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14237         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14238
14239         createmany -o $testdir1/test 512 || error "createmany failed"
14240
14241         # check samedir rename size
14242         mv ${testdir1}/test0 ${testdir1}/test_0
14243
14244         local testdir1_size=$(ls -l $DIR/${tdir} |
14245                 awk '/stats_testdir1/ {print $5}')
14246         local testdir2_size=$(ls -l $DIR/${tdir} |
14247                 awk '/stats_testdir2/ {print $5}')
14248
14249         testdir1_size=$(order_2 $testdir1_size)
14250         testdir2_size=$(order_2 $testdir2_size)
14251
14252         testdir1_size=$(size_in_KMGT $testdir1_size)
14253         testdir2_size=$(size_in_KMGT $testdir2_size)
14254
14255         echo "source rename dir size: ${testdir1_size}"
14256         echo "target rename dir size: ${testdir2_size}"
14257
14258         local cmd="do_facet $SINGLEMDS $LCTL "
14259         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14260
14261         eval $cmd || error "$cmd failed"
14262         local samedir=$($cmd | grep 'same_dir')
14263         local same_sample=$(get_rename_size $testdir1_size)
14264         [ -z "$samedir" ] && error "samedir_rename_size count error"
14265         [[ $same_sample -eq 1 ]] ||
14266                 error "samedir_rename_size error $same_sample"
14267         echo "Check same dir rename stats success"
14268
14269         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14270
14271         # check crossdir rename size
14272         mv ${testdir1}/test_0 ${testdir2}/test_0
14273
14274         testdir1_size=$(ls -l $DIR/${tdir} |
14275                 awk '/stats_testdir1/ {print $5}')
14276         testdir2_size=$(ls -l $DIR/${tdir} |
14277                 awk '/stats_testdir2/ {print $5}')
14278
14279         testdir1_size=$(order_2 $testdir1_size)
14280         testdir2_size=$(order_2 $testdir2_size)
14281
14282         testdir1_size=$(size_in_KMGT $testdir1_size)
14283         testdir2_size=$(size_in_KMGT $testdir2_size)
14284
14285         echo "source rename dir size: ${testdir1_size}"
14286         echo "target rename dir size: ${testdir2_size}"
14287
14288         eval $cmd || error "$cmd failed"
14289         local crossdir=$($cmd | grep 'crossdir')
14290         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14291         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14292         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14293         [[ $src_sample -eq 1 ]] ||
14294                 error "crossdir_rename_size error $src_sample"
14295         [[ $tgt_sample -eq 1 ]] ||
14296                 error "crossdir_rename_size error $tgt_sample"
14297         echo "Check cross dir rename stats success"
14298         rm -rf $DIR/${tdir}
14299 }
14300 run_test 133d "Verifying rename_stats ========================================"
14301
14302 test_133e() {
14303         remote_mds_nodsh && skip "remote MDS with nodsh"
14304         remote_ost_nodsh && skip "remote OST with nodsh"
14305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14306
14307         local testdir=$DIR/${tdir}/stats_testdir
14308         local ctr f0 f1 bs=32768 count=42 sum
14309
14310         mkdir -p ${testdir} || error "mkdir failed"
14311
14312         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14313
14314         for ctr in {write,read}_bytes; do
14315                 sync
14316                 cancel_lru_locks osc
14317
14318                 do_facet ost1 $LCTL set_param -n \
14319                         "obdfilter.*.exports.clear=clear"
14320
14321                 if [ $ctr = write_bytes ]; then
14322                         f0=/dev/zero
14323                         f1=${testdir}/${tfile}
14324                 else
14325                         f0=${testdir}/${tfile}
14326                         f1=/dev/null
14327                 fi
14328
14329                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14330                         error "dd failed"
14331                 sync
14332                 cancel_lru_locks osc
14333
14334                 sum=$(do_facet ost1 $LCTL get_param \
14335                         "obdfilter.*.exports.*.stats" |
14336                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14337                                 $1 == ctr { sum += $7 }
14338                                 END { printf("%0.0f", sum) }')
14339
14340                 if ((sum != bs * count)); then
14341                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14342                 fi
14343         done
14344
14345         rm -rf $DIR/${tdir}
14346 }
14347 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14348
14349 test_133f() {
14350         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14351                 skip "too old lustre for get_param -R ($facet_ver)"
14352
14353         # verifying readability.
14354         $LCTL get_param -R '*' &> /dev/null
14355
14356         # Verifing writability with badarea_io.
14357         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14358         local skipped_params='force_lbug|changelog_mask|daemon_file'
14359         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14360                 egrep -v "$skipped_params" |
14361                 xargs -n 1 find $proc_dirs -name |
14362                 xargs -n 1 badarea_io ||
14363                 error "client badarea_io failed"
14364
14365         # remount the FS in case writes/reads /proc break the FS
14366         cleanup || error "failed to unmount"
14367         setup || error "failed to setup"
14368 }
14369 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14370
14371 test_133g() {
14372         remote_mds_nodsh && skip "remote MDS with nodsh"
14373         remote_ost_nodsh && skip "remote OST with nodsh"
14374
14375         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14376         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14377         local facet
14378         for facet in mds1 ost1; do
14379                 local facet_ver=$(lustre_version_code $facet)
14380                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14381                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14382                 else
14383                         log "$facet: too old lustre for get_param -R"
14384                 fi
14385                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14386                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14387                                 tr -d = | egrep -v $skipped_params |
14388                                 xargs -n 1 find $proc_dirs -name |
14389                                 xargs -n 1 badarea_io" ||
14390                                         error "$facet badarea_io failed"
14391                 else
14392                         skip_noexit "$facet: too old lustre for get_param -R"
14393                 fi
14394         done
14395
14396         # remount the FS in case writes/reads /proc break the FS
14397         cleanup || error "failed to unmount"
14398         setup || error "failed to setup"
14399 }
14400 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14401
14402 test_133h() {
14403         remote_mds_nodsh && skip "remote MDS with nodsh"
14404         remote_ost_nodsh && skip "remote OST with nodsh"
14405         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14406                 skip "Need MDS version at least 2.9.54"
14407
14408         local facet
14409         for facet in client mds1 ost1; do
14410                 # Get the list of files that are missing the terminating newline
14411                 local plist=$(do_facet $facet
14412                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14413                 local ent
14414                 for ent in $plist; do
14415                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14416                                 awk -v FS='\v' -v RS='\v\v' \
14417                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14418                                         print FILENAME}'" 2>/dev/null)
14419                         [ -z $missing ] || {
14420                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14421                                 error "file does not end with newline: $facet-$ent"
14422                         }
14423                 done
14424         done
14425 }
14426 run_test 133h "Proc files should end with newlines"
14427
14428 test_134a() {
14429         remote_mds_nodsh && skip "remote MDS with nodsh"
14430         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14431                 skip "Need MDS version at least 2.7.54"
14432
14433         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14434         cancel_lru_locks mdc
14435
14436         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14437         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14438         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14439
14440         local nr=1000
14441         createmany -o $DIR/$tdir/f $nr ||
14442                 error "failed to create $nr files in $DIR/$tdir"
14443         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14444
14445         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14446         do_facet mds1 $LCTL set_param fail_loc=0x327
14447         do_facet mds1 $LCTL set_param fail_val=500
14448         touch $DIR/$tdir/m
14449
14450         echo "sleep 10 seconds ..."
14451         sleep 10
14452         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14453
14454         do_facet mds1 $LCTL set_param fail_loc=0
14455         do_facet mds1 $LCTL set_param fail_val=0
14456         [ $lck_cnt -lt $unused ] ||
14457                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14458
14459         rm $DIR/$tdir/m
14460         unlinkmany $DIR/$tdir/f $nr
14461 }
14462 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14463
14464 test_134b() {
14465         remote_mds_nodsh && skip "remote MDS with nodsh"
14466         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14467                 skip "Need MDS version at least 2.7.54"
14468
14469         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14470         cancel_lru_locks mdc
14471
14472         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14473                         ldlm.lock_reclaim_threshold_mb)
14474         # disable reclaim temporarily
14475         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14476
14477         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14478         do_facet mds1 $LCTL set_param fail_loc=0x328
14479         do_facet mds1 $LCTL set_param fail_val=500
14480
14481         $LCTL set_param debug=+trace
14482
14483         local nr=600
14484         createmany -o $DIR/$tdir/f $nr &
14485         local create_pid=$!
14486
14487         echo "Sleep $TIMEOUT seconds ..."
14488         sleep $TIMEOUT
14489         if ! ps -p $create_pid  > /dev/null 2>&1; then
14490                 do_facet mds1 $LCTL set_param fail_loc=0
14491                 do_facet mds1 $LCTL set_param fail_val=0
14492                 do_facet mds1 $LCTL set_param \
14493                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14494                 error "createmany finished incorrectly!"
14495         fi
14496         do_facet mds1 $LCTL set_param fail_loc=0
14497         do_facet mds1 $LCTL set_param fail_val=0
14498         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14499         wait $create_pid || return 1
14500
14501         unlinkmany $DIR/$tdir/f $nr
14502 }
14503 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14504
14505 test_135() {
14506         remote_mds_nodsh && skip "remote MDS with nodsh"
14507         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14508                 skip "Need MDS version at least 2.13.50"
14509         local fname
14510
14511         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14512
14513 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14514         #set only one record at plain llog
14515         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14516
14517         #fill already existed plain llog each 64767
14518         #wrapping whole catalog
14519         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14520
14521         createmany -o $DIR/$tdir/$tfile_ 64700
14522         for (( i = 0; i < 64700; i = i + 2 ))
14523         do
14524                 rm $DIR/$tdir/$tfile_$i &
14525                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14526                 local pid=$!
14527                 wait $pid
14528         done
14529
14530         #waiting osp synchronization
14531         wait_delete_completed
14532 }
14533 run_test 135 "Race catalog processing"
14534
14535 test_136() {
14536         remote_mds_nodsh && skip "remote MDS with nodsh"
14537         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14538                 skip "Need MDS version at least 2.13.50"
14539         local fname
14540
14541         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14542         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14543         #set only one record at plain llog
14544 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14545         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14546
14547         #fill already existed 2 plain llogs each 64767
14548         #wrapping whole catalog
14549         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14550         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14551         wait_delete_completed
14552
14553         createmany -o $DIR/$tdir/$tfile_ 10
14554         sleep 25
14555
14556         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14557         for (( i = 0; i < 10; i = i + 3 ))
14558         do
14559                 rm $DIR/$tdir/$tfile_$i &
14560                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14561                 local pid=$!
14562                 wait $pid
14563                 sleep 7
14564                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14565         done
14566
14567         #waiting osp synchronization
14568         wait_delete_completed
14569 }
14570 run_test 136 "Race catalog processing 2"
14571
14572 test_140() { #bug-17379
14573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14574
14575         test_mkdir $DIR/$tdir
14576         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14577         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14578
14579         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14580         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14581         local i=0
14582         while i=$((i + 1)); do
14583                 test_mkdir $i
14584                 cd $i || error "Changing to $i"
14585                 ln -s ../stat stat || error "Creating stat symlink"
14586                 # Read the symlink until ELOOP present,
14587                 # not LBUGing the system is considered success,
14588                 # we didn't overrun the stack.
14589                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14590                 if [ $ret -ne 0 ]; then
14591                         if [ $ret -eq 40 ]; then
14592                                 break  # -ELOOP
14593                         else
14594                                 error "Open stat symlink"
14595                                         return
14596                         fi
14597                 fi
14598         done
14599         i=$((i - 1))
14600         echo "The symlink depth = $i"
14601         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14602                 error "Invalid symlink depth"
14603
14604         # Test recursive symlink
14605         ln -s symlink_self symlink_self
14606         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14607         echo "open symlink_self returns $ret"
14608         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14609 }
14610 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14611
14612 test_150a() {
14613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14614
14615         local TF="$TMP/$tfile"
14616
14617         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14618         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14619         cp $TF $DIR/$tfile
14620         cancel_lru_locks $OSC
14621         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14622         remount_client $MOUNT
14623         df -P $MOUNT
14624         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14625
14626         $TRUNCATE $TF 6000
14627         $TRUNCATE $DIR/$tfile 6000
14628         cancel_lru_locks $OSC
14629         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14630
14631         echo "12345" >>$TF
14632         echo "12345" >>$DIR/$tfile
14633         cancel_lru_locks $OSC
14634         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14635
14636         echo "12345" >>$TF
14637         echo "12345" >>$DIR/$tfile
14638         cancel_lru_locks $OSC
14639         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14640 }
14641 run_test 150a "truncate/append tests"
14642
14643 test_150b() {
14644         check_set_fallocate_or_skip
14645
14646         touch $DIR/$tfile
14647         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14648         check_fallocate $DIR/$tfile || error "fallocate failed"
14649 }
14650 run_test 150b "Verify fallocate (prealloc) functionality"
14651
14652 test_150bb() {
14653         check_set_fallocate_or_skip
14654
14655         touch $DIR/$tfile
14656         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14657         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14658         > $DIR/$tfile
14659         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14660         # precomputed md5sum for 20MB of zeroes
14661         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14662         local sum=($(md5sum $DIR/$tfile))
14663
14664         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14665
14666         check_set_fallocate 1
14667
14668         > $DIR/$tfile
14669         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14670         sum=($(md5sum $DIR/$tfile))
14671
14672         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14673 }
14674 run_test 150bb "Verify fallocate modes both zero space"
14675
14676 test_150c() {
14677         check_set_fallocate_or_skip
14678         local striping="-c2"
14679
14680         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14681         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14682         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14683         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14684         local want=$((OSTCOUNT * 1048576))
14685
14686         # Must allocate all requested space, not more than 5% extra
14687         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14688                 error "bytes $bytes is not $want"
14689
14690         rm -f $DIR/$tfile
14691
14692         echo "verify fallocate on PFL file"
14693
14694         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14695
14696         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14697                 error "Create $DIR/$tfile failed"
14698         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14699                         error "fallocate failed"
14700         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14701         want=$((512 * 1048576))
14702
14703         # Must allocate all requested space, not more than 5% extra
14704         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14705                 error "bytes $bytes is not $want"
14706 }
14707 run_test 150c "Verify fallocate Size and Blocks"
14708
14709 test_150d() {
14710         check_set_fallocate_or_skip
14711         local striping="-c2"
14712
14713         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14714
14715         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14716         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14717                 error "setstripe failed"
14718         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14719         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14720         local want=$((OSTCOUNT * 1048576))
14721
14722         # Must allocate all requested space, not more than 5% extra
14723         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14724                 error "bytes $bytes is not $want"
14725 }
14726 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14727
14728 test_150e() {
14729         check_set_fallocate_or_skip
14730
14731         echo "df before:"
14732         $LFS df
14733         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14734         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14735                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14736
14737         # Find OST with Minimum Size
14738         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14739                        sort -un | head -1)
14740
14741         # Get 100MB per OST of the available space to reduce run time
14742         # else 60% of the available space if we are running SLOW tests
14743         if [ $SLOW == "no" ]; then
14744                 local space=$((1024 * 100 * OSTCOUNT))
14745         else
14746                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14747         fi
14748
14749         fallocate -l${space}k $DIR/$tfile ||
14750                 error "fallocate ${space}k $DIR/$tfile failed"
14751         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14752
14753         # get size immediately after fallocate. This should be correctly
14754         # updated
14755         local size=$(stat -c '%s' $DIR/$tfile)
14756         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14757
14758         # Sleep for a while for statfs to get updated. And not pull from cache.
14759         sleep 2
14760
14761         echo "df after fallocate:"
14762         $LFS df
14763
14764         (( size / 1024 == space )) || error "size $size != requested $space"
14765         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14766                 error "used $used < space $space"
14767
14768         rm $DIR/$tfile || error "rm failed"
14769         sync
14770         wait_delete_completed
14771
14772         echo "df after unlink:"
14773         $LFS df
14774 }
14775 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14776
14777 test_150f() {
14778         local size
14779         local blocks
14780         local want_size_before=20480 # in bytes
14781         local want_blocks_before=40 # 512 sized blocks
14782         local want_blocks_after=24  # 512 sized blocks
14783         local length=$(((want_blocks_before - want_blocks_after) * 512))
14784
14785         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14786                 skip "need at least 2.14.0 for fallocate punch"
14787
14788         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14789                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14790         fi
14791
14792         check_set_fallocate_or_skip
14793         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14794
14795         [[ "x$DOM" == "xyes" ]] &&
14796                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14797
14798         echo "Verify fallocate punch: Range within the file range"
14799         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14800                 error "dd failed for bs 4096 and count 5"
14801
14802         # Call fallocate with punch range which is within the file range
14803         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14804                 error "fallocate failed: offset 4096 and length $length"
14805         # client must see changes immediately after fallocate
14806         size=$(stat -c '%s' $DIR/$tfile)
14807         blocks=$(stat -c '%b' $DIR/$tfile)
14808
14809         # Verify punch worked.
14810         (( blocks == want_blocks_after )) ||
14811                 error "punch failed: blocks $blocks != $want_blocks_after"
14812
14813         (( size == want_size_before )) ||
14814                 error "punch failed: size $size != $want_size_before"
14815
14816         # Verify there is hole in file
14817         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14818         # precomputed md5sum
14819         local expect="4a9a834a2db02452929c0a348273b4aa"
14820
14821         cksum=($(md5sum $DIR/$tfile))
14822         [[ "${cksum[0]}" == "$expect" ]] ||
14823                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14824
14825         # Start second sub-case for fallocate punch.
14826         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14827         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14828                 error "dd failed for bs 4096 and count 5"
14829
14830         # Punch range less than block size will have no change in block count
14831         want_blocks_after=40  # 512 sized blocks
14832
14833         # Punch overlaps two blocks and less than blocksize
14834         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14835                 error "fallocate failed: offset 4000 length 3000"
14836         size=$(stat -c '%s' $DIR/$tfile)
14837         blocks=$(stat -c '%b' $DIR/$tfile)
14838
14839         # Verify punch worked.
14840         (( blocks == want_blocks_after )) ||
14841                 error "punch failed: blocks $blocks != $want_blocks_after"
14842
14843         (( size == want_size_before )) ||
14844                 error "punch failed: size $size != $want_size_before"
14845
14846         # Verify if range is really zero'ed out. We expect Zeros.
14847         # precomputed md5sum
14848         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14849         cksum=($(md5sum $DIR/$tfile))
14850         [[ "${cksum[0]}" == "$expect" ]] ||
14851                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14852 }
14853 run_test 150f "Verify fallocate punch functionality"
14854
14855 test_150g() {
14856         local space
14857         local size
14858         local blocks
14859         local blocks_after
14860         local size_after
14861         local BS=4096 # Block size in bytes
14862
14863         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14864                 skip "need at least 2.14.0 for fallocate punch"
14865
14866         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14867                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14868         fi
14869
14870         check_set_fallocate_or_skip
14871         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14872
14873         if [[ "x$DOM" == "xyes" ]]; then
14874                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14875                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14876         else
14877                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14878                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14879         fi
14880
14881         # Get 100MB per OST of the available space to reduce run time
14882         # else 60% of the available space if we are running SLOW tests
14883         if [ $SLOW == "no" ]; then
14884                 space=$((1024 * 100 * OSTCOUNT))
14885         else
14886                 # Find OST with Minimum Size
14887                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14888                         sort -un | head -1)
14889                 echo "min size OST: $space"
14890                 space=$(((space * 60)/100 * OSTCOUNT))
14891         fi
14892         # space in 1k units, round to 4k blocks
14893         local blkcount=$((space * 1024 / $BS))
14894
14895         echo "Verify fallocate punch: Very large Range"
14896         fallocate -l${space}k $DIR/$tfile ||
14897                 error "fallocate ${space}k $DIR/$tfile failed"
14898         # write 1M at the end, start and in the middle
14899         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14900                 error "dd failed: bs $BS count 256"
14901         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14902                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14903         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14904                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14905
14906         # Gather stats.
14907         size=$(stat -c '%s' $DIR/$tfile)
14908
14909         # gather punch length.
14910         local punch_size=$((size - (BS * 2)))
14911
14912         echo "punch_size = $punch_size"
14913         echo "size - punch_size: $((size - punch_size))"
14914         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14915
14916         # Call fallocate to punch all except 2 blocks. We leave the
14917         # first and the last block
14918         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14919         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14920                 error "fallocate failed: offset $BS length $punch_size"
14921
14922         size_after=$(stat -c '%s' $DIR/$tfile)
14923         blocks_after=$(stat -c '%b' $DIR/$tfile)
14924
14925         # Verify punch worked.
14926         # Size should be kept
14927         (( size == size_after )) ||
14928                 error "punch failed: size $size != $size_after"
14929
14930         # two 4k data blocks to remain plus possible 1 extra extent block
14931         (( blocks_after <= ((BS / 512) * 3) )) ||
14932                 error "too many blocks remains: $blocks_after"
14933
14934         # Verify that file has hole between the first and the last blocks
14935         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14936         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14937
14938         echo "Hole at [$hole_start, $hole_end)"
14939         (( hole_start == BS )) ||
14940                 error "no hole at offset $BS after punch"
14941
14942         (( hole_end == BS + punch_size )) ||
14943                 error "data at offset $hole_end < $((BS + punch_size))"
14944 }
14945 run_test 150g "Verify fallocate punch on large range"
14946
14947 #LU-2902 roc_hit was not able to read all values from lproc
14948 function roc_hit_init() {
14949         local list=$(comma_list $(osts_nodes))
14950         local dir=$DIR/$tdir-check
14951         local file=$dir/$tfile
14952         local BEFORE
14953         local AFTER
14954         local idx
14955
14956         test_mkdir $dir
14957         #use setstripe to do a write to every ost
14958         for i in $(seq 0 $((OSTCOUNT-1))); do
14959                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14960                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14961                 idx=$(printf %04x $i)
14962                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14963                         awk '$1 == "cache_access" {sum += $7}
14964                                 END { printf("%0.0f", sum) }')
14965
14966                 cancel_lru_locks osc
14967                 cat $file >/dev/null
14968
14969                 AFTER=$(get_osd_param $list *OST*$idx stats |
14970                         awk '$1 == "cache_access" {sum += $7}
14971                                 END { printf("%0.0f", sum) }')
14972
14973                 echo BEFORE:$BEFORE AFTER:$AFTER
14974                 if ! let "AFTER - BEFORE == 4"; then
14975                         rm -rf $dir
14976                         error "roc_hit is not safe to use"
14977                 fi
14978                 rm $file
14979         done
14980
14981         rm -rf $dir
14982 }
14983
14984 function roc_hit() {
14985         local list=$(comma_list $(osts_nodes))
14986         echo $(get_osd_param $list '' stats |
14987                 awk '$1 == "cache_hit" {sum += $7}
14988                         END { printf("%0.0f", sum) }')
14989 }
14990
14991 function set_cache() {
14992         local on=1
14993
14994         if [ "$2" == "off" ]; then
14995                 on=0;
14996         fi
14997         local list=$(comma_list $(osts_nodes))
14998         set_osd_param $list '' $1_cache_enable $on
14999
15000         cancel_lru_locks osc
15001 }
15002
15003 test_151() {
15004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15005         remote_ost_nodsh && skip "remote OST with nodsh"
15006
15007         local CPAGES=3
15008         local list=$(comma_list $(osts_nodes))
15009
15010         # check whether obdfilter is cache capable at all
15011         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15012                 skip "not cache-capable obdfilter"
15013         fi
15014
15015         # check cache is enabled on all obdfilters
15016         if get_osd_param $list '' read_cache_enable | grep 0; then
15017                 skip "oss cache is disabled"
15018         fi
15019
15020         set_osd_param $list '' writethrough_cache_enable 1
15021
15022         # check write cache is enabled on all obdfilters
15023         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15024                 skip "oss write cache is NOT enabled"
15025         fi
15026
15027         roc_hit_init
15028
15029         #define OBD_FAIL_OBD_NO_LRU  0x609
15030         do_nodes $list $LCTL set_param fail_loc=0x609
15031
15032         # pages should be in the case right after write
15033         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15034                 error "dd failed"
15035
15036         local BEFORE=$(roc_hit)
15037         cancel_lru_locks osc
15038         cat $DIR/$tfile >/dev/null
15039         local AFTER=$(roc_hit)
15040
15041         do_nodes $list $LCTL set_param fail_loc=0
15042
15043         if ! let "AFTER - BEFORE == CPAGES"; then
15044                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15045         fi
15046
15047         cancel_lru_locks osc
15048         # invalidates OST cache
15049         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15050         set_osd_param $list '' read_cache_enable 0
15051         cat $DIR/$tfile >/dev/null
15052
15053         # now data shouldn't be found in the cache
15054         BEFORE=$(roc_hit)
15055         cancel_lru_locks osc
15056         cat $DIR/$tfile >/dev/null
15057         AFTER=$(roc_hit)
15058         if let "AFTER - BEFORE != 0"; then
15059                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15060         fi
15061
15062         set_osd_param $list '' read_cache_enable 1
15063         rm -f $DIR/$tfile
15064 }
15065 run_test 151 "test cache on oss and controls ==============================="
15066
15067 test_152() {
15068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15069
15070         local TF="$TMP/$tfile"
15071
15072         # simulate ENOMEM during write
15073 #define OBD_FAIL_OST_NOMEM      0x226
15074         lctl set_param fail_loc=0x80000226
15075         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15076         cp $TF $DIR/$tfile
15077         sync || error "sync failed"
15078         lctl set_param fail_loc=0
15079
15080         # discard client's cache
15081         cancel_lru_locks osc
15082
15083         # simulate ENOMEM during read
15084         lctl set_param fail_loc=0x80000226
15085         cmp $TF $DIR/$tfile || error "cmp failed"
15086         lctl set_param fail_loc=0
15087
15088         rm -f $TF
15089 }
15090 run_test 152 "test read/write with enomem ============================"
15091
15092 test_153() {
15093         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15094 }
15095 run_test 153 "test if fdatasync does not crash ======================="
15096
15097 dot_lustre_fid_permission_check() {
15098         local fid=$1
15099         local ffid=$MOUNT/.lustre/fid/$fid
15100         local test_dir=$2
15101
15102         echo "stat fid $fid"
15103         stat $ffid > /dev/null || error "stat $ffid failed."
15104         echo "touch fid $fid"
15105         touch $ffid || error "touch $ffid failed."
15106         echo "write to fid $fid"
15107         cat /etc/hosts > $ffid || error "write $ffid failed."
15108         echo "read fid $fid"
15109         diff /etc/hosts $ffid || error "read $ffid failed."
15110         echo "append write to fid $fid"
15111         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15112         echo "rename fid $fid"
15113         mv $ffid $test_dir/$tfile.1 &&
15114                 error "rename $ffid to $tfile.1 should fail."
15115         touch $test_dir/$tfile.1
15116         mv $test_dir/$tfile.1 $ffid &&
15117                 error "rename $tfile.1 to $ffid should fail."
15118         rm -f $test_dir/$tfile.1
15119         echo "truncate fid $fid"
15120         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15121         echo "link fid $fid"
15122         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15123         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15124                 echo "setfacl fid $fid"
15125                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15126                 echo "getfacl fid $fid"
15127                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15128         fi
15129         echo "unlink fid $fid"
15130         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15131         echo "mknod fid $fid"
15132         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15133
15134         fid=[0xf00000400:0x1:0x0]
15135         ffid=$MOUNT/.lustre/fid/$fid
15136
15137         echo "stat non-exist fid $fid"
15138         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15139         echo "write to non-exist fid $fid"
15140         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15141         echo "link new fid $fid"
15142         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15143
15144         mkdir -p $test_dir/$tdir
15145         touch $test_dir/$tdir/$tfile
15146         fid=$($LFS path2fid $test_dir/$tdir)
15147         rc=$?
15148         [ $rc -ne 0 ] &&
15149                 error "error: could not get fid for $test_dir/$dir/$tfile."
15150
15151         ffid=$MOUNT/.lustre/fid/$fid
15152
15153         echo "ls $fid"
15154         ls $ffid > /dev/null || error "ls $ffid failed."
15155         echo "touch $fid/$tfile.1"
15156         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15157
15158         echo "touch $MOUNT/.lustre/fid/$tfile"
15159         touch $MOUNT/.lustre/fid/$tfile && \
15160                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15161
15162         echo "setxattr to $MOUNT/.lustre/fid"
15163         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15164
15165         echo "listxattr for $MOUNT/.lustre/fid"
15166         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15167
15168         echo "delxattr from $MOUNT/.lustre/fid"
15169         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15170
15171         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15172         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15173                 error "touch invalid fid should fail."
15174
15175         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15176         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15177                 error "touch non-normal fid should fail."
15178
15179         echo "rename $tdir to $MOUNT/.lustre/fid"
15180         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15181                 error "rename to $MOUNT/.lustre/fid should fail."
15182
15183         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15184         then            # LU-3547
15185                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15186                 local new_obf_mode=777
15187
15188                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15189                 chmod $new_obf_mode $DIR/.lustre/fid ||
15190                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15191
15192                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15193                 [ $obf_mode -eq $new_obf_mode ] ||
15194                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15195
15196                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15197                 chmod $old_obf_mode $DIR/.lustre/fid ||
15198                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15199         fi
15200
15201         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15202         fid=$($LFS path2fid $test_dir/$tfile-2)
15203
15204         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15205         then # LU-5424
15206                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15207                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15208                         error "create lov data thru .lustre failed"
15209         fi
15210         echo "cp /etc/passwd $test_dir/$tfile-2"
15211         cp /etc/passwd $test_dir/$tfile-2 ||
15212                 error "copy to $test_dir/$tfile-2 failed."
15213         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15214         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15215                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15216
15217         rm -rf $test_dir/tfile.lnk
15218         rm -rf $test_dir/$tfile-2
15219 }
15220
15221 test_154A() {
15222         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15223                 skip "Need MDS version at least 2.4.1"
15224
15225         local tf=$DIR/$tfile
15226         touch $tf
15227
15228         local fid=$($LFS path2fid $tf)
15229         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15230
15231         # check that we get the same pathname back
15232         local rootpath
15233         local found
15234         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15235                 echo "$rootpath $fid"
15236                 found=$($LFS fid2path $rootpath "$fid")
15237                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15238                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15239         done
15240
15241         # check wrong root path format
15242         rootpath=$MOUNT"_wrong"
15243         found=$($LFS fid2path $rootpath "$fid")
15244         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15245 }
15246 run_test 154A "lfs path2fid and fid2path basic checks"
15247
15248 test_154B() {
15249         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15250                 skip "Need MDS version at least 2.4.1"
15251
15252         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15253         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15254         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15255         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15256
15257         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15258         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15259
15260         # check that we get the same pathname
15261         echo "PFID: $PFID, name: $name"
15262         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15263         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15264         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15265                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15266
15267         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15268 }
15269 run_test 154B "verify the ll_decode_linkea tool"
15270
15271 test_154a() {
15272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15273         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15274         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15275                 skip "Need MDS version at least 2.2.51"
15276         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15277
15278         cp /etc/hosts $DIR/$tfile
15279
15280         fid=$($LFS path2fid $DIR/$tfile)
15281         rc=$?
15282         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15283
15284         dot_lustre_fid_permission_check "$fid" $DIR ||
15285                 error "dot lustre permission check $fid failed"
15286
15287         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15288
15289         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15290
15291         touch $MOUNT/.lustre/file &&
15292                 error "creation is not allowed under .lustre"
15293
15294         mkdir $MOUNT/.lustre/dir &&
15295                 error "mkdir is not allowed under .lustre"
15296
15297         rm -rf $DIR/$tfile
15298 }
15299 run_test 154a "Open-by-FID"
15300
15301 test_154b() {
15302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15303         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15304         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15305         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15306                 skip "Need MDS version at least 2.2.51"
15307
15308         local remote_dir=$DIR/$tdir/remote_dir
15309         local MDTIDX=1
15310         local rc=0
15311
15312         mkdir -p $DIR/$tdir
15313         $LFS mkdir -i $MDTIDX $remote_dir ||
15314                 error "create remote directory failed"
15315
15316         cp /etc/hosts $remote_dir/$tfile
15317
15318         fid=$($LFS path2fid $remote_dir/$tfile)
15319         rc=$?
15320         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15321
15322         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15323                 error "dot lustre permission check $fid failed"
15324         rm -rf $DIR/$tdir
15325 }
15326 run_test 154b "Open-by-FID for remote directory"
15327
15328 test_154c() {
15329         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15330                 skip "Need MDS version at least 2.4.1"
15331
15332         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15333         local FID1=$($LFS path2fid $DIR/$tfile.1)
15334         local FID2=$($LFS path2fid $DIR/$tfile.2)
15335         local FID3=$($LFS path2fid $DIR/$tfile.3)
15336
15337         local N=1
15338         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15339                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15340                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15341                 local want=FID$N
15342                 [ "$FID" = "${!want}" ] ||
15343                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15344                 N=$((N + 1))
15345         done
15346
15347         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15348         do
15349                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15350                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15351                 N=$((N + 1))
15352         done
15353 }
15354 run_test 154c "lfs path2fid and fid2path multiple arguments"
15355
15356 test_154d() {
15357         remote_mds_nodsh && skip "remote MDS with nodsh"
15358         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15359                 skip "Need MDS version at least 2.5.53"
15360
15361         if remote_mds; then
15362                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15363         else
15364                 nid="0@lo"
15365         fi
15366         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15367         local fd
15368         local cmd
15369
15370         rm -f $DIR/$tfile
15371         touch $DIR/$tfile
15372
15373         local fid=$($LFS path2fid $DIR/$tfile)
15374         # Open the file
15375         fd=$(free_fd)
15376         cmd="exec $fd<$DIR/$tfile"
15377         eval $cmd
15378         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15379         echo "$fid_list" | grep "$fid"
15380         rc=$?
15381
15382         cmd="exec $fd>/dev/null"
15383         eval $cmd
15384         if [ $rc -ne 0 ]; then
15385                 error "FID $fid not found in open files list $fid_list"
15386         fi
15387 }
15388 run_test 154d "Verify open file fid"
15389
15390 test_154e()
15391 {
15392         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15393                 skip "Need MDS version at least 2.6.50"
15394
15395         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15396                 error ".lustre returned by readdir"
15397         fi
15398 }
15399 run_test 154e ".lustre is not returned by readdir"
15400
15401 test_154f() {
15402         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15403
15404         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15405         mkdir_on_mdt0 $DIR/$tdir
15406         # test dirs inherit from its stripe
15407         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15408         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15409         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15410         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15411         touch $DIR/f
15412
15413         # get fid of parents
15414         local FID0=$($LFS path2fid $DIR/$tdir)
15415         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15416         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15417         local FID3=$($LFS path2fid $DIR)
15418
15419         # check that path2fid --parents returns expected <parent_fid>/name
15420         # 1) test for a directory (single parent)
15421         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15422         [ "$parent" == "$FID0/foo1" ] ||
15423                 error "expected parent: $FID0/foo1, got: $parent"
15424
15425         # 2) test for a file with nlink > 1 (multiple parents)
15426         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15427         echo "$parent" | grep -F "$FID1/$tfile" ||
15428                 error "$FID1/$tfile not returned in parent list"
15429         echo "$parent" | grep -F "$FID2/link" ||
15430                 error "$FID2/link not returned in parent list"
15431
15432         # 3) get parent by fid
15433         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15434         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15435         echo "$parent" | grep -F "$FID1/$tfile" ||
15436                 error "$FID1/$tfile not returned in parent list (by fid)"
15437         echo "$parent" | grep -F "$FID2/link" ||
15438                 error "$FID2/link not returned in parent list (by fid)"
15439
15440         # 4) test for entry in root directory
15441         parent=$($LFS path2fid --parents $DIR/f)
15442         echo "$parent" | grep -F "$FID3/f" ||
15443                 error "$FID3/f not returned in parent list"
15444
15445         # 5) test it on root directory
15446         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15447                 error "$MOUNT should not have parents"
15448
15449         # enable xattr caching and check that linkea is correctly updated
15450         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15451         save_lustre_params client "llite.*.xattr_cache" > $save
15452         lctl set_param llite.*.xattr_cache 1
15453
15454         # 6.1) linkea update on rename
15455         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15456
15457         # get parents by fid
15458         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15459         # foo1 should no longer be returned in parent list
15460         echo "$parent" | grep -F "$FID1" &&
15461                 error "$FID1 should no longer be in parent list"
15462         # the new path should appear
15463         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15464                 error "$FID2/$tfile.moved is not in parent list"
15465
15466         # 6.2) linkea update on unlink
15467         rm -f $DIR/$tdir/foo2/link
15468         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15469         # foo2/link should no longer be returned in parent list
15470         echo "$parent" | grep -F "$FID2/link" &&
15471                 error "$FID2/link should no longer be in parent list"
15472         true
15473
15474         rm -f $DIR/f
15475         restore_lustre_params < $save
15476         rm -f $save
15477 }
15478 run_test 154f "get parent fids by reading link ea"
15479
15480 test_154g()
15481 {
15482         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15483         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15484            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15485                 skip "Need MDS version at least 2.6.92"
15486
15487         mkdir_on_mdt0 $DIR/$tdir
15488         llapi_fid_test -d $DIR/$tdir
15489 }
15490 run_test 154g "various llapi FID tests"
15491
15492 test_155_small_load() {
15493     local temp=$TMP/$tfile
15494     local file=$DIR/$tfile
15495
15496     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15497         error "dd of=$temp bs=6096 count=1 failed"
15498     cp $temp $file
15499     cancel_lru_locks $OSC
15500     cmp $temp $file || error "$temp $file differ"
15501
15502     $TRUNCATE $temp 6000
15503     $TRUNCATE $file 6000
15504     cmp $temp $file || error "$temp $file differ (truncate1)"
15505
15506     echo "12345" >>$temp
15507     echo "12345" >>$file
15508     cmp $temp $file || error "$temp $file differ (append1)"
15509
15510     echo "12345" >>$temp
15511     echo "12345" >>$file
15512     cmp $temp $file || error "$temp $file differ (append2)"
15513
15514     rm -f $temp $file
15515     true
15516 }
15517
15518 test_155_big_load() {
15519         remote_ost_nodsh && skip "remote OST with nodsh"
15520
15521         local temp=$TMP/$tfile
15522         local file=$DIR/$tfile
15523
15524         free_min_max
15525         local cache_size=$(do_facet ost$((MAXI+1)) \
15526                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15527         local large_file_size=$((cache_size * 2))
15528
15529         echo "OSS cache size: $cache_size KB"
15530         echo "Large file size: $large_file_size KB"
15531
15532         [ $MAXV -le $large_file_size ] &&
15533                 skip_env "max available OST size needs > $large_file_size KB"
15534
15535         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15536
15537         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15538                 error "dd of=$temp bs=$large_file_size count=1k failed"
15539         cp $temp $file
15540         ls -lh $temp $file
15541         cancel_lru_locks osc
15542         cmp $temp $file || error "$temp $file differ"
15543
15544         rm -f $temp $file
15545         true
15546 }
15547
15548 save_writethrough() {
15549         local facets=$(get_facets OST)
15550
15551         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15552 }
15553
15554 test_155a() {
15555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15556
15557         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15558
15559         save_writethrough $p
15560
15561         set_cache read on
15562         set_cache writethrough on
15563         test_155_small_load
15564         restore_lustre_params < $p
15565         rm -f $p
15566 }
15567 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15568
15569 test_155b() {
15570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15571
15572         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15573
15574         save_writethrough $p
15575
15576         set_cache read on
15577         set_cache writethrough off
15578         test_155_small_load
15579         restore_lustre_params < $p
15580         rm -f $p
15581 }
15582 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15583
15584 test_155c() {
15585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15586
15587         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15588
15589         save_writethrough $p
15590
15591         set_cache read off
15592         set_cache writethrough on
15593         test_155_small_load
15594         restore_lustre_params < $p
15595         rm -f $p
15596 }
15597 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15598
15599 test_155d() {
15600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15601
15602         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15603
15604         save_writethrough $p
15605
15606         set_cache read off
15607         set_cache writethrough off
15608         test_155_small_load
15609         restore_lustre_params < $p
15610         rm -f $p
15611 }
15612 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15613
15614 test_155e() {
15615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15616
15617         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15618
15619         save_writethrough $p
15620
15621         set_cache read on
15622         set_cache writethrough on
15623         test_155_big_load
15624         restore_lustre_params < $p
15625         rm -f $p
15626 }
15627 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15628
15629 test_155f() {
15630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15631
15632         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15633
15634         save_writethrough $p
15635
15636         set_cache read on
15637         set_cache writethrough off
15638         test_155_big_load
15639         restore_lustre_params < $p
15640         rm -f $p
15641 }
15642 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15643
15644 test_155g() {
15645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15646
15647         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15648
15649         save_writethrough $p
15650
15651         set_cache read off
15652         set_cache writethrough on
15653         test_155_big_load
15654         restore_lustre_params < $p
15655         rm -f $p
15656 }
15657 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15658
15659 test_155h() {
15660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15661
15662         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15663
15664         save_writethrough $p
15665
15666         set_cache read off
15667         set_cache writethrough off
15668         test_155_big_load
15669         restore_lustre_params < $p
15670         rm -f $p
15671 }
15672 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15673
15674 test_156() {
15675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15676         remote_ost_nodsh && skip "remote OST with nodsh"
15677         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15678                 skip "stats not implemented on old servers"
15679         [ "$ost1_FSTYPE" = "zfs" ] &&
15680                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15681
15682         local CPAGES=3
15683         local BEFORE
15684         local AFTER
15685         local file="$DIR/$tfile"
15686         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15687
15688         save_writethrough $p
15689         roc_hit_init
15690
15691         log "Turn on read and write cache"
15692         set_cache read on
15693         set_cache writethrough on
15694
15695         log "Write data and read it back."
15696         log "Read should be satisfied from the cache."
15697         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15698         BEFORE=$(roc_hit)
15699         cancel_lru_locks osc
15700         cat $file >/dev/null
15701         AFTER=$(roc_hit)
15702         if ! let "AFTER - BEFORE == CPAGES"; then
15703                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15704         else
15705                 log "cache hits: before: $BEFORE, after: $AFTER"
15706         fi
15707
15708         log "Read again; it should be satisfied from the cache."
15709         BEFORE=$AFTER
15710         cancel_lru_locks osc
15711         cat $file >/dev/null
15712         AFTER=$(roc_hit)
15713         if ! let "AFTER - BEFORE == CPAGES"; then
15714                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15715         else
15716                 log "cache hits:: before: $BEFORE, after: $AFTER"
15717         fi
15718
15719         log "Turn off the read cache and turn on the write cache"
15720         set_cache read off
15721         set_cache writethrough on
15722
15723         log "Read again; it should be satisfied from the cache."
15724         BEFORE=$(roc_hit)
15725         cancel_lru_locks osc
15726         cat $file >/dev/null
15727         AFTER=$(roc_hit)
15728         if ! let "AFTER - BEFORE == CPAGES"; then
15729                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15730         else
15731                 log "cache hits:: before: $BEFORE, after: $AFTER"
15732         fi
15733
15734         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15735                 # > 2.12.56 uses pagecache if cached
15736                 log "Read again; it should not be satisfied from the cache."
15737                 BEFORE=$AFTER
15738                 cancel_lru_locks osc
15739                 cat $file >/dev/null
15740                 AFTER=$(roc_hit)
15741                 if ! let "AFTER - BEFORE == 0"; then
15742                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15743                 else
15744                         log "cache hits:: before: $BEFORE, after: $AFTER"
15745                 fi
15746         fi
15747
15748         log "Write data and read it back."
15749         log "Read should be satisfied from the cache."
15750         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15751         BEFORE=$(roc_hit)
15752         cancel_lru_locks osc
15753         cat $file >/dev/null
15754         AFTER=$(roc_hit)
15755         if ! let "AFTER - BEFORE == CPAGES"; then
15756                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15757         else
15758                 log "cache hits:: before: $BEFORE, after: $AFTER"
15759         fi
15760
15761         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15762                 # > 2.12.56 uses pagecache if cached
15763                 log "Read again; it should not be satisfied from the cache."
15764                 BEFORE=$AFTER
15765                 cancel_lru_locks osc
15766                 cat $file >/dev/null
15767                 AFTER=$(roc_hit)
15768                 if ! let "AFTER - BEFORE == 0"; then
15769                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15770                 else
15771                         log "cache hits:: before: $BEFORE, after: $AFTER"
15772                 fi
15773         fi
15774
15775         log "Turn off read and write cache"
15776         set_cache read off
15777         set_cache writethrough off
15778
15779         log "Write data and read it back"
15780         log "It should not be satisfied from the cache."
15781         rm -f $file
15782         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15783         cancel_lru_locks osc
15784         BEFORE=$(roc_hit)
15785         cat $file >/dev/null
15786         AFTER=$(roc_hit)
15787         if ! let "AFTER - BEFORE == 0"; then
15788                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15789         else
15790                 log "cache hits:: before: $BEFORE, after: $AFTER"
15791         fi
15792
15793         log "Turn on the read cache and turn off the write cache"
15794         set_cache read on
15795         set_cache writethrough off
15796
15797         log "Write data and read it back"
15798         log "It should not be satisfied from the cache."
15799         rm -f $file
15800         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15801         BEFORE=$(roc_hit)
15802         cancel_lru_locks osc
15803         cat $file >/dev/null
15804         AFTER=$(roc_hit)
15805         if ! let "AFTER - BEFORE == 0"; then
15806                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15807         else
15808                 log "cache hits:: before: $BEFORE, after: $AFTER"
15809         fi
15810
15811         log "Read again; it should be satisfied from the cache."
15812         BEFORE=$(roc_hit)
15813         cancel_lru_locks osc
15814         cat $file >/dev/null
15815         AFTER=$(roc_hit)
15816         if ! let "AFTER - BEFORE == CPAGES"; then
15817                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15818         else
15819                 log "cache hits:: before: $BEFORE, after: $AFTER"
15820         fi
15821
15822         restore_lustre_params < $p
15823         rm -f $p $file
15824 }
15825 run_test 156 "Verification of tunables"
15826
15827 test_160a() {
15828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15829         remote_mds_nodsh && skip "remote MDS with nodsh"
15830         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15831                 skip "Need MDS version at least 2.2.0"
15832
15833         changelog_register || error "changelog_register failed"
15834         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15835         changelog_users $SINGLEMDS | grep -q $cl_user ||
15836                 error "User $cl_user not found in changelog_users"
15837
15838         mkdir_on_mdt0 $DIR/$tdir
15839
15840         # change something
15841         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15842         changelog_clear 0 || error "changelog_clear failed"
15843         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15844         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15845         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15846         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15847         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15848         rm $DIR/$tdir/pics/desktop.jpg
15849
15850         echo "verifying changelog mask"
15851         changelog_chmask "-MKDIR"
15852         changelog_chmask "-CLOSE"
15853
15854         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15855         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15856
15857         changelog_chmask "+MKDIR"
15858         changelog_chmask "+CLOSE"
15859
15860         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15861         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15862
15863         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15864         CLOSES=$(changelog_dump | grep -c "CLOSE")
15865         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15866         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15867
15868         # verify contents
15869         echo "verifying target fid"
15870         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15871         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15872         [ "$fidc" == "$fidf" ] ||
15873                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15874         echo "verifying parent fid"
15875         # The FID returned from the Changelog may be the directory shard on
15876         # a different MDT, and not the FID returned by path2fid on the parent.
15877         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15878         # since this is what will matter when recreating this file in the tree.
15879         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15880         local pathp=$($LFS fid2path $MOUNT "$fidp")
15881         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15882                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15883
15884         echo "getting records for $cl_user"
15885         changelog_users $SINGLEMDS
15886         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15887         local nclr=3
15888         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15889                 error "changelog_clear failed"
15890         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15891         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15892         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15893                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15894
15895         local min0_rec=$(changelog_users $SINGLEMDS |
15896                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15897         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15898                           awk '{ print $1; exit; }')
15899
15900         changelog_dump | tail -n 5
15901         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15902         [ $first_rec == $((min0_rec + 1)) ] ||
15903                 error "first index should be $min0_rec + 1 not $first_rec"
15904
15905         # LU-3446 changelog index reset on MDT restart
15906         local cur_rec1=$(changelog_users $SINGLEMDS |
15907                          awk '/^current.index:/ { print $NF }')
15908         changelog_clear 0 ||
15909                 error "clear all changelog records for $cl_user failed"
15910         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15911         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15912                 error "Fail to start $SINGLEMDS"
15913         local cur_rec2=$(changelog_users $SINGLEMDS |
15914                          awk '/^current.index:/ { print $NF }')
15915         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15916         [ $cur_rec1 == $cur_rec2 ] ||
15917                 error "current index should be $cur_rec1 not $cur_rec2"
15918
15919         echo "verifying users from this test are deregistered"
15920         changelog_deregister || error "changelog_deregister failed"
15921         changelog_users $SINGLEMDS | grep -q $cl_user &&
15922                 error "User '$cl_user' still in changelog_users"
15923
15924         # lctl get_param -n mdd.*.changelog_users
15925         # current_index: 144
15926         # ID    index (idle seconds)
15927         # cl3   144   (2) mask=<list>
15928         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15929                 # this is the normal case where all users were deregistered
15930                 # make sure no new records are added when no users are present
15931                 local last_rec1=$(changelog_users $SINGLEMDS |
15932                                   awk '/^current.index:/ { print $NF }')
15933                 touch $DIR/$tdir/chloe
15934                 local last_rec2=$(changelog_users $SINGLEMDS |
15935                                   awk '/^current.index:/ { print $NF }')
15936                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15937                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15938         else
15939                 # any changelog users must be leftovers from a previous test
15940                 changelog_users $SINGLEMDS
15941                 echo "other changelog users; can't verify off"
15942         fi
15943 }
15944 run_test 160a "changelog sanity"
15945
15946 test_160b() { # LU-3587
15947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15948         remote_mds_nodsh && skip "remote MDS with nodsh"
15949         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15950                 skip "Need MDS version at least 2.2.0"
15951
15952         changelog_register || error "changelog_register failed"
15953         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15954         changelog_users $SINGLEMDS | grep -q $cl_user ||
15955                 error "User '$cl_user' not found in changelog_users"
15956
15957         local longname1=$(str_repeat a 255)
15958         local longname2=$(str_repeat b 255)
15959
15960         cd $DIR
15961         echo "creating very long named file"
15962         touch $longname1 || error "create of '$longname1' failed"
15963         echo "renaming very long named file"
15964         mv $longname1 $longname2
15965
15966         changelog_dump | grep RENME | tail -n 5
15967         rm -f $longname2
15968 }
15969 run_test 160b "Verify that very long rename doesn't crash in changelog"
15970
15971 test_160c() {
15972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15973         remote_mds_nodsh && skip "remote MDS with nodsh"
15974
15975         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15976                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15977                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15978                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15979
15980         local rc=0
15981
15982         # Registration step
15983         changelog_register || error "changelog_register failed"
15984
15985         rm -rf $DIR/$tdir
15986         mkdir -p $DIR/$tdir
15987         $MCREATE $DIR/$tdir/foo_160c
15988         changelog_chmask "-TRUNC"
15989         $TRUNCATE $DIR/$tdir/foo_160c 200
15990         changelog_chmask "+TRUNC"
15991         $TRUNCATE $DIR/$tdir/foo_160c 199
15992         changelog_dump | tail -n 5
15993         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15994         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15995 }
15996 run_test 160c "verify that changelog log catch the truncate event"
15997
15998 test_160d() {
15999         remote_mds_nodsh && skip "remote MDS with nodsh"
16000         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16002         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16003                 skip "Need MDS version at least 2.7.60"
16004
16005         # Registration step
16006         changelog_register || error "changelog_register failed"
16007
16008         mkdir -p $DIR/$tdir/migrate_dir
16009         changelog_clear 0 || error "changelog_clear failed"
16010
16011         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16012         changelog_dump | tail -n 5
16013         local migrates=$(changelog_dump | grep -c "MIGRT")
16014         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16015 }
16016 run_test 160d "verify that changelog log catch the migrate event"
16017
16018 test_160e() {
16019         remote_mds_nodsh && skip "remote MDS with nodsh"
16020
16021         # Create a user
16022         changelog_register || error "changelog_register failed"
16023
16024         local MDT0=$(facet_svc $SINGLEMDS)
16025         local rc
16026
16027         # No user (expect fail)
16028         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16029         rc=$?
16030         if [ $rc -eq 0 ]; then
16031                 error "Should fail without user"
16032         elif [ $rc -ne 4 ]; then
16033                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16034         fi
16035
16036         # Delete a future user (expect fail)
16037         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16038         rc=$?
16039         if [ $rc -eq 0 ]; then
16040                 error "Deleted non-existant user cl77"
16041         elif [ $rc -ne 2 ]; then
16042                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16043         fi
16044
16045         # Clear to a bad index (1 billion should be safe)
16046         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16047         rc=$?
16048
16049         if [ $rc -eq 0 ]; then
16050                 error "Successfully cleared to invalid CL index"
16051         elif [ $rc -ne 22 ]; then
16052                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16053         fi
16054 }
16055 run_test 160e "changelog negative testing (should return errors)"
16056
16057 test_160f() {
16058         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16059         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16060                 skip "Need MDS version at least 2.10.56"
16061
16062         local mdts=$(comma_list $(mdts_nodes))
16063
16064         # Create a user
16065         changelog_register || error "first changelog_register failed"
16066         changelog_register || error "second changelog_register failed"
16067         local cl_users
16068         declare -A cl_user1
16069         declare -A cl_user2
16070         local user_rec1
16071         local user_rec2
16072         local i
16073
16074         # generate some changelog records to accumulate on each MDT
16075         # use all_char because created files should be evenly distributed
16076         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16077                 error "test_mkdir $tdir failed"
16078         log "$(date +%s): creating first files"
16079         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16080                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16081                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16082         done
16083
16084         # check changelogs have been generated
16085         local start=$SECONDS
16086         local idle_time=$((MDSCOUNT * 5 + 5))
16087         local nbcl=$(changelog_dump | wc -l)
16088         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16089
16090         for param in "changelog_max_idle_time=$idle_time" \
16091                      "changelog_gc=1" \
16092                      "changelog_min_gc_interval=2" \
16093                      "changelog_min_free_cat_entries=3"; do
16094                 local MDT0=$(facet_svc $SINGLEMDS)
16095                 local var="${param%=*}"
16096                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16097
16098                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16099                 do_nodes $mdts $LCTL set_param mdd.*.$param
16100         done
16101
16102         # force cl_user2 to be idle (1st part), but also cancel the
16103         # cl_user1 records so that it is not evicted later in the test.
16104         local sleep1=$((idle_time / 2))
16105         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16106         sleep $sleep1
16107
16108         # simulate changelog catalog almost full
16109         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16110         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16111
16112         for i in $(seq $MDSCOUNT); do
16113                 cl_users=(${CL_USERS[mds$i]})
16114                 cl_user1[mds$i]="${cl_users[0]}"
16115                 cl_user2[mds$i]="${cl_users[1]}"
16116
16117                 [ -n "${cl_user1[mds$i]}" ] ||
16118                         error "mds$i: no user registered"
16119                 [ -n "${cl_user2[mds$i]}" ] ||
16120                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16121
16122                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16123                 [ -n "$user_rec1" ] ||
16124                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16125                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16126                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16127                 [ -n "$user_rec2" ] ||
16128                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16129                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16130                      "$user_rec1 + 2 == $user_rec2"
16131                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16132                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16133                               "$user_rec1 + 2, but is $user_rec2"
16134                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16135                 [ -n "$user_rec2" ] ||
16136                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16137                 [ $user_rec1 == $user_rec2 ] ||
16138                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16139                               "$user_rec1, but is $user_rec2"
16140         done
16141
16142         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16143         local sleep2=$((idle_time - (SECONDS - start) + 1))
16144         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16145         sleep $sleep2
16146
16147         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16148         # cl_user1 should be OK because it recently processed records.
16149         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16150         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16151                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16152                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16153         done
16154
16155         # ensure gc thread is done
16156         for i in $(mdts_nodes); do
16157                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16158                         error "$i: GC-thread not done"
16159         done
16160
16161         local first_rec
16162         for (( i = 1; i <= MDSCOUNT; i++ )); do
16163                 # check cl_user1 still registered
16164                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16165                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16166                 # check cl_user2 unregistered
16167                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16168                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16169
16170                 # check changelogs are present and starting at $user_rec1 + 1
16171                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16172                 [ -n "$user_rec1" ] ||
16173                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16174                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16175                             awk '{ print $1; exit; }')
16176
16177                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16178                 [ $((user_rec1 + 1)) == $first_rec ] ||
16179                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16180         done
16181 }
16182 run_test 160f "changelog garbage collect (timestamped users)"
16183
16184 test_160g() {
16185         remote_mds_nodsh && skip "remote MDS with nodsh"
16186         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16187                 skip "Need MDS version at least 2.14.55"
16188
16189         local mdts=$(comma_list $(mdts_nodes))
16190
16191         # Create a user
16192         changelog_register || error "first changelog_register failed"
16193         changelog_register || error "second changelog_register failed"
16194         local cl_users
16195         declare -A cl_user1
16196         declare -A cl_user2
16197         local user_rec1
16198         local user_rec2
16199         local i
16200
16201         # generate some changelog records to accumulate on each MDT
16202         # use all_char because created files should be evenly distributed
16203         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16204                 error "test_mkdir $tdir failed"
16205         for ((i = 0; i < MDSCOUNT; i++)); do
16206                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16207                         error "create $DIR/$tdir/d$i.1 failed"
16208         done
16209
16210         # check changelogs have been generated
16211         local nbcl=$(changelog_dump | wc -l)
16212         (( $nbcl > 0 )) || error "no changelogs found"
16213
16214         # reduce the max_idle_indexes value to make sure we exceed it
16215         for param in "changelog_max_idle_indexes=2" \
16216                      "changelog_gc=1" \
16217                      "changelog_min_gc_interval=2"; do
16218                 local MDT0=$(facet_svc $SINGLEMDS)
16219                 local var="${param%=*}"
16220                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16221
16222                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16223                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16224                         error "unable to set mdd.*.$param"
16225         done
16226
16227         local start=$SECONDS
16228         for i in $(seq $MDSCOUNT); do
16229                 cl_users=(${CL_USERS[mds$i]})
16230                 cl_user1[mds$i]="${cl_users[0]}"
16231                 cl_user2[mds$i]="${cl_users[1]}"
16232
16233                 [ -n "${cl_user1[mds$i]}" ] ||
16234                         error "mds$i: user1 is not registered"
16235                 [ -n "${cl_user2[mds$i]}" ] ||
16236                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16237
16238                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16239                 [ -n "$user_rec1" ] ||
16240                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16241                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16242                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16243                 [ -n "$user_rec2" ] ||
16244                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16245                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16246                      "$user_rec1 + 2 == $user_rec2"
16247                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16248                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16249                               "expected $user_rec1 + 2, but is $user_rec2"
16250                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16251                 [ -n "$user_rec2" ] ||
16252                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16253                 [ $user_rec1 == $user_rec2 ] ||
16254                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16255                               "expected $user_rec1, but is $user_rec2"
16256         done
16257
16258         # ensure we are past the previous changelog_min_gc_interval set above
16259         local sleep2=$((start + 2 - SECONDS))
16260         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16261         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16262         # cl_user1 should be OK because it recently processed records.
16263         for ((i = 0; i < MDSCOUNT; i++)); do
16264                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16265                         error "create $DIR/$tdir/d$i.3 failed"
16266         done
16267
16268         # ensure gc thread is done
16269         for i in $(mdts_nodes); do
16270                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16271                         error "$i: GC-thread not done"
16272         done
16273
16274         local first_rec
16275         for (( i = 1; i <= MDSCOUNT; i++ )); do
16276                 # check cl_user1 still registered
16277                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16278                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16279                 # check cl_user2 unregistered
16280                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16281                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16282
16283                 # check changelogs are present and starting at $user_rec1 + 1
16284                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16285                 [ -n "$user_rec1" ] ||
16286                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16287                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16288                             awk '{ print $1; exit; }')
16289
16290                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16291                 [ $((user_rec1 + 1)) == $first_rec ] ||
16292                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16293         done
16294 }
16295 run_test 160g "changelog garbage collect on idle records"
16296
16297 test_160h() {
16298         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16299         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16300                 skip "Need MDS version at least 2.10.56"
16301
16302         local mdts=$(comma_list $(mdts_nodes))
16303
16304         # Create a user
16305         changelog_register || error "first changelog_register failed"
16306         changelog_register || error "second changelog_register failed"
16307         local cl_users
16308         declare -A cl_user1
16309         declare -A cl_user2
16310         local user_rec1
16311         local user_rec2
16312         local i
16313
16314         # generate some changelog records to accumulate on each MDT
16315         # use all_char because created files should be evenly distributed
16316         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16317                 error "test_mkdir $tdir failed"
16318         for ((i = 0; i < MDSCOUNT; i++)); do
16319                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16320                         error "create $DIR/$tdir/d$i.1 failed"
16321         done
16322
16323         # check changelogs have been generated
16324         local nbcl=$(changelog_dump | wc -l)
16325         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16326
16327         for param in "changelog_max_idle_time=10" \
16328                      "changelog_gc=1" \
16329                      "changelog_min_gc_interval=2"; do
16330                 local MDT0=$(facet_svc $SINGLEMDS)
16331                 local var="${param%=*}"
16332                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16333
16334                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16335                 do_nodes $mdts $LCTL set_param mdd.*.$param
16336         done
16337
16338         # force cl_user2 to be idle (1st part)
16339         sleep 9
16340
16341         for i in $(seq $MDSCOUNT); do
16342                 cl_users=(${CL_USERS[mds$i]})
16343                 cl_user1[mds$i]="${cl_users[0]}"
16344                 cl_user2[mds$i]="${cl_users[1]}"
16345
16346                 [ -n "${cl_user1[mds$i]}" ] ||
16347                         error "mds$i: no user registered"
16348                 [ -n "${cl_user2[mds$i]}" ] ||
16349                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16350
16351                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16352                 [ -n "$user_rec1" ] ||
16353                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16354                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16355                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16356                 [ -n "$user_rec2" ] ||
16357                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16358                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16359                      "$user_rec1 + 2 == $user_rec2"
16360                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16361                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16362                               "$user_rec1 + 2, but is $user_rec2"
16363                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16364                 [ -n "$user_rec2" ] ||
16365                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16366                 [ $user_rec1 == $user_rec2 ] ||
16367                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16368                               "$user_rec1, but is $user_rec2"
16369         done
16370
16371         # force cl_user2 to be idle (2nd part) and to reach
16372         # changelog_max_idle_time
16373         sleep 2
16374
16375         # force each GC-thread start and block then
16376         # one per MDT/MDD, set fail_val accordingly
16377         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16378         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16379
16380         # generate more changelogs to trigger fail_loc
16381         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16382                 error "create $DIR/$tdir/${tfile}bis failed"
16383
16384         # stop MDT to stop GC-thread, should be done in back-ground as it will
16385         # block waiting for the thread to be released and exit
16386         declare -A stop_pids
16387         for i in $(seq $MDSCOUNT); do
16388                 stop mds$i &
16389                 stop_pids[mds$i]=$!
16390         done
16391
16392         for i in $(mdts_nodes); do
16393                 local facet
16394                 local nb=0
16395                 local facets=$(facets_up_on_host $i)
16396
16397                 for facet in ${facets//,/ }; do
16398                         if [[ $facet == mds* ]]; then
16399                                 nb=$((nb + 1))
16400                         fi
16401                 done
16402                 # ensure each MDS's gc threads are still present and all in "R"
16403                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16404                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16405                         error "$i: expected $nb GC-thread"
16406                 wait_update $i \
16407                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16408                         "R" 20 ||
16409                         error "$i: GC-thread not found in R-state"
16410                 # check umounts of each MDT on MDS have reached kthread_stop()
16411                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16412                         error "$i: expected $nb umount"
16413                 wait_update $i \
16414                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16415                         error "$i: umount not found in D-state"
16416         done
16417
16418         # release all GC-threads
16419         do_nodes $mdts $LCTL set_param fail_loc=0
16420
16421         # wait for MDT stop to complete
16422         for i in $(seq $MDSCOUNT); do
16423                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16424         done
16425
16426         # XXX
16427         # may try to check if any orphan changelog records are present
16428         # via ldiskfs/zfs and llog_reader...
16429
16430         # re-start/mount MDTs
16431         for i in $(seq $MDSCOUNT); do
16432                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16433                         error "Fail to start mds$i"
16434         done
16435
16436         local first_rec
16437         for i in $(seq $MDSCOUNT); do
16438                 # check cl_user1 still registered
16439                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16440                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16441                 # check cl_user2 unregistered
16442                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16443                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16444
16445                 # check changelogs are present and starting at $user_rec1 + 1
16446                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16447                 [ -n "$user_rec1" ] ||
16448                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16449                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16450                             awk '{ print $1; exit; }')
16451
16452                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16453                 [ $((user_rec1 + 1)) == $first_rec ] ||
16454                         error "mds$i: first index should be $user_rec1 + 1, " \
16455                               "but is $first_rec"
16456         done
16457 }
16458 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16459               "during mount"
16460
16461 test_160i() {
16462
16463         local mdts=$(comma_list $(mdts_nodes))
16464
16465         changelog_register || error "first changelog_register failed"
16466
16467         # generate some changelog records to accumulate on each MDT
16468         # use all_char because created files should be evenly distributed
16469         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16470                 error "test_mkdir $tdir failed"
16471         for ((i = 0; i < MDSCOUNT; i++)); do
16472                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16473                         error "create $DIR/$tdir/d$i.1 failed"
16474         done
16475
16476         # check changelogs have been generated
16477         local nbcl=$(changelog_dump | wc -l)
16478         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16479
16480         # simulate race between register and unregister
16481         # XXX as fail_loc is set per-MDS, with DNE configs the race
16482         # simulation will only occur for one MDT per MDS and for the
16483         # others the normal race scenario will take place
16484         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16485         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16486         do_nodes $mdts $LCTL set_param fail_val=1
16487
16488         # unregister 1st user
16489         changelog_deregister &
16490         local pid1=$!
16491         # wait some time for deregister work to reach race rdv
16492         sleep 2
16493         # register 2nd user
16494         changelog_register || error "2nd user register failed"
16495
16496         wait $pid1 || error "1st user deregister failed"
16497
16498         local i
16499         local last_rec
16500         declare -A LAST_REC
16501         for i in $(seq $MDSCOUNT); do
16502                 if changelog_users mds$i | grep "^cl"; then
16503                         # make sure new records are added with one user present
16504                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16505                                           awk '/^current.index:/ { print $NF }')
16506                 else
16507                         error "mds$i has no user registered"
16508                 fi
16509         done
16510
16511         # generate more changelog records to accumulate on each MDT
16512         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16513                 error "create $DIR/$tdir/${tfile}bis failed"
16514
16515         for i in $(seq $MDSCOUNT); do
16516                 last_rec=$(changelog_users $SINGLEMDS |
16517                            awk '/^current.index:/ { print $NF }')
16518                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16519                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16520                         error "changelogs are off on mds$i"
16521         done
16522 }
16523 run_test 160i "changelog user register/unregister race"
16524
16525 test_160j() {
16526         remote_mds_nodsh && skip "remote MDS with nodsh"
16527         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16528                 skip "Need MDS version at least 2.12.56"
16529
16530         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16531         stack_trap "umount $MOUNT2" EXIT
16532
16533         changelog_register || error "first changelog_register failed"
16534         stack_trap "changelog_deregister" EXIT
16535
16536         # generate some changelog
16537         # use all_char because created files should be evenly distributed
16538         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16539                 error "mkdir $tdir failed"
16540         for ((i = 0; i < MDSCOUNT; i++)); do
16541                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16542                         error "create $DIR/$tdir/d$i.1 failed"
16543         done
16544
16545         # open the changelog device
16546         exec 3>/dev/changelog-$FSNAME-MDT0000
16547         stack_trap "exec 3>&-" EXIT
16548         exec 4</dev/changelog-$FSNAME-MDT0000
16549         stack_trap "exec 4<&-" EXIT
16550
16551         # umount the first lustre mount
16552         umount $MOUNT
16553         stack_trap "mount_client $MOUNT" EXIT
16554
16555         # read changelog, which may or may not fail, but should not crash
16556         cat <&4 >/dev/null
16557
16558         # clear changelog
16559         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16560         changelog_users $SINGLEMDS | grep -q $cl_user ||
16561                 error "User $cl_user not found in changelog_users"
16562
16563         printf 'clear:'$cl_user':0' >&3
16564 }
16565 run_test 160j "client can be umounted while its chanangelog is being used"
16566
16567 test_160k() {
16568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16569         remote_mds_nodsh && skip "remote MDS with nodsh"
16570
16571         mkdir -p $DIR/$tdir/1/1
16572
16573         changelog_register || error "changelog_register failed"
16574         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16575
16576         changelog_users $SINGLEMDS | grep -q $cl_user ||
16577                 error "User '$cl_user' not found in changelog_users"
16578 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16579         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16580         rmdir $DIR/$tdir/1/1 & sleep 1
16581         mkdir $DIR/$tdir/2
16582         touch $DIR/$tdir/2/2
16583         rm -rf $DIR/$tdir/2
16584
16585         wait
16586         sleep 4
16587
16588         changelog_dump | grep rmdir || error "rmdir not recorded"
16589 }
16590 run_test 160k "Verify that changelog records are not lost"
16591
16592 # Verifies that a file passed as a parameter has recently had an operation
16593 # performed on it that has generated an MTIME changelog which contains the
16594 # correct parent FID. As files might reside on a different MDT from the
16595 # parent directory in DNE configurations, the FIDs are translated to paths
16596 # before being compared, which should be identical
16597 compare_mtime_changelog() {
16598         local file="${1}"
16599         local mdtidx
16600         local mtime
16601         local cl_fid
16602         local pdir
16603         local dir
16604
16605         mdtidx=$($LFS getstripe --mdt-index $file)
16606         mdtidx=$(printf "%04x" $mdtidx)
16607
16608         # Obtain the parent FID from the MTIME changelog
16609         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16610         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16611
16612         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16613         [ -z "$cl_fid" ] && error "parent FID not present"
16614
16615         # Verify that the path for the parent FID is the same as the path for
16616         # the test directory
16617         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16618
16619         dir=$(dirname $1)
16620
16621         [[ "${pdir%/}" == "$dir" ]] ||
16622                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16623 }
16624
16625 test_160l() {
16626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16627
16628         remote_mds_nodsh && skip "remote MDS with nodsh"
16629         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16630                 skip "Need MDS version at least 2.13.55"
16631
16632         local cl_user
16633
16634         changelog_register || error "changelog_register failed"
16635         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16636
16637         changelog_users $SINGLEMDS | grep -q $cl_user ||
16638                 error "User '$cl_user' not found in changelog_users"
16639
16640         # Clear some types so that MTIME changelogs are generated
16641         changelog_chmask "-CREAT"
16642         changelog_chmask "-CLOSE"
16643
16644         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16645
16646         # Test CL_MTIME during setattr
16647         touch $DIR/$tdir/$tfile
16648         compare_mtime_changelog $DIR/$tdir/$tfile
16649
16650         # Test CL_MTIME during close
16651         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16652         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16653 }
16654 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16655
16656 test_160m() {
16657         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16658         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16659                 skip "Need MDS version at least 2.14.51"
16660         local cl_users
16661         local cl_user1
16662         local cl_user2
16663         local pid1
16664
16665         # Create a user
16666         changelog_register || error "first changelog_register failed"
16667         changelog_register || error "second changelog_register failed"
16668
16669         cl_users=(${CL_USERS[mds1]})
16670         cl_user1="${cl_users[0]}"
16671         cl_user2="${cl_users[1]}"
16672         # generate some changelog records to accumulate on MDT0
16673         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16674         createmany -m $DIR/$tdir/$tfile 50 ||
16675                 error "create $DIR/$tdir/$tfile failed"
16676         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16677         rm -f $DIR/$tdir
16678
16679         # check changelogs have been generated
16680         local nbcl=$(changelog_dump | wc -l)
16681         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16682
16683 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16684         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16685
16686         __changelog_clear mds1 $cl_user1 +10
16687         __changelog_clear mds1 $cl_user2 0 &
16688         pid1=$!
16689         sleep 2
16690         __changelog_clear mds1 $cl_user1 0 ||
16691                 error "fail to cancel record for $cl_user1"
16692         wait $pid1
16693         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16694 }
16695 run_test 160m "Changelog clear race"
16696
16697 test_160n() {
16698         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16699         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16700                 skip "Need MDS version at least 2.14.51"
16701         local cl_users
16702         local cl_user1
16703         local cl_user2
16704         local pid1
16705         local first_rec
16706         local last_rec=0
16707
16708         # Create a user
16709         changelog_register || error "first changelog_register failed"
16710
16711         cl_users=(${CL_USERS[mds1]})
16712         cl_user1="${cl_users[0]}"
16713
16714         # generate some changelog records to accumulate on MDT0
16715         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16716         first_rec=$(changelog_users $SINGLEMDS |
16717                         awk '/^current.index:/ { print $NF }')
16718         while (( last_rec < (( first_rec + 65000)) )); do
16719                 createmany -m $DIR/$tdir/$tfile 10000 ||
16720                         error "create $DIR/$tdir/$tfile failed"
16721
16722                 for i in $(seq 0 10000); do
16723                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16724                                 > /dev/null
16725                 done
16726
16727                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16728                         error "unlinkmany failed unlink"
16729                 last_rec=$(changelog_users $SINGLEMDS |
16730                         awk '/^current.index:/ { print $NF }')
16731                 echo last record $last_rec
16732                 (( last_rec == 0 )) && error "no changelog found"
16733         done
16734
16735 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16736         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16737
16738         __changelog_clear mds1 $cl_user1 0 &
16739         pid1=$!
16740         sleep 2
16741         __changelog_clear mds1 $cl_user1 0 ||
16742                 error "fail to cancel record for $cl_user1"
16743         wait $pid1
16744         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16745 }
16746 run_test 160n "Changelog destroy race"
16747
16748 test_160o() {
16749         local mdt="$(facet_svc $SINGLEMDS)"
16750
16751         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16752         remote_mds_nodsh && skip "remote MDS with nodsh"
16753         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16754                 skip "Need MDS version at least 2.14.52"
16755
16756         changelog_register --user test_160o -m unlnk+close+open ||
16757                 error "changelog_register failed"
16758
16759         do_facet $SINGLEMDS $LCTL --device $mdt \
16760                                 changelog_register -u "Tt3_-#" &&
16761                 error "bad symbols in name should fail"
16762
16763         do_facet $SINGLEMDS $LCTL --device $mdt \
16764                                 changelog_register -u test_160o &&
16765                 error "the same name registration should fail"
16766
16767         do_facet $SINGLEMDS $LCTL --device $mdt \
16768                         changelog_register -u test_160toolongname &&
16769                 error "too long name registration should fail"
16770
16771         changelog_chmask "MARK+HSM"
16772         lctl get_param mdd.*.changelog*mask
16773         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16774         changelog_users $SINGLEMDS | grep -q $cl_user ||
16775                 error "User $cl_user not found in changelog_users"
16776         #verify username
16777         echo $cl_user | grep -q test_160o ||
16778                 error "User $cl_user has no specific name 'test160o'"
16779
16780         # change something
16781         changelog_clear 0 || error "changelog_clear failed"
16782         # generate some changelog records to accumulate on MDT0
16783         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16784         touch $DIR/$tdir/$tfile                 # open 1
16785
16786         OPENS=$(changelog_dump | grep -c "OPEN")
16787         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16788
16789         # must be no MKDIR it wasn't set as user mask
16790         MKDIR=$(changelog_dump | grep -c "MKDIR")
16791         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16792
16793         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16794                                 mdd.$mdt.changelog_current_mask -n)
16795         # register maskless user
16796         changelog_register || error "changelog_register failed"
16797         # effective mask should be not changed because it is not minimal
16798         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16799                                 mdd.$mdt.changelog_current_mask -n)
16800         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16801         # set server mask to minimal value
16802         changelog_chmask "MARK"
16803         # check effective mask again, should be treated as DEFMASK now
16804         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16805                                 mdd.$mdt.changelog_current_mask -n)
16806         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16807
16808         do_facet $SINGLEMDS $LCTL --device $mdt \
16809                                 changelog_deregister -u test_160o ||
16810                 error "cannot deregister by name"
16811 }
16812 run_test 160o "changelog user name and mask"
16813
16814 test_160p() {
16815         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16816         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16817                 skip "Need MDS version at least 2.14.51"
16818         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16819         local cl_users
16820         local cl_user1
16821         local entry_count
16822
16823         # Create a user
16824         changelog_register || error "first changelog_register failed"
16825
16826         cl_users=(${CL_USERS[mds1]})
16827         cl_user1="${cl_users[0]}"
16828
16829         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16830         createmany -m $DIR/$tdir/$tfile 50 ||
16831                 error "create $DIR/$tdir/$tfile failed"
16832         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16833         rm -rf $DIR/$tdir
16834
16835         # check changelogs have been generated
16836         entry_count=$(changelog_dump | wc -l)
16837         ((entry_count != 0)) || error "no changelog entries found"
16838
16839         # remove changelog_users and check that orphan entries are removed
16840         stop mds1
16841         local dev=$(mdsdevname 1)
16842         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16843         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16844         entry_count=$(changelog_dump | wc -l)
16845         ((entry_count == 0)) ||
16846                 error "found $entry_count changelog entries, expected none"
16847 }
16848 run_test 160p "Changelog orphan cleanup with no users"
16849
16850 test_160q() {
16851         local mdt="$(facet_svc $SINGLEMDS)"
16852         local clu
16853
16854         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16855         remote_mds_nodsh && skip "remote MDS with nodsh"
16856         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16857                 skip "Need MDS version at least 2.14.54"
16858
16859         # set server mask to minimal value like server init does
16860         changelog_chmask "MARK"
16861         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16862                 error "changelog_register failed"
16863         # check effective mask again, should be treated as DEFMASK now
16864         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16865                                 mdd.$mdt.changelog_current_mask -n)
16866         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16867                 error "changelog_deregister failed"
16868         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16869 }
16870 run_test 160q "changelog effective mask is DEFMASK if not set"
16871
16872 test_160s() {
16873         remote_mds_nodsh && skip "remote MDS with nodsh"
16874         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16875                 skip "Need MDS version at least 2.14.55"
16876
16877         local mdts=$(comma_list $(mdts_nodes))
16878
16879         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16880         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16881                                        fail_val=$((24 * 3600 * 10))
16882
16883         # Create a user which is 10 days old
16884         changelog_register || error "first changelog_register failed"
16885         local cl_users
16886         declare -A cl_user1
16887         local i
16888
16889         # generate some changelog records to accumulate on each MDT
16890         # use all_char because created files should be evenly distributed
16891         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16892                 error "test_mkdir $tdir failed"
16893         for ((i = 0; i < MDSCOUNT; i++)); do
16894                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16895                         error "create $DIR/$tdir/d$i.1 failed"
16896         done
16897
16898         # check changelogs have been generated
16899         local nbcl=$(changelog_dump | wc -l)
16900         (( nbcl > 0 )) || error "no changelogs found"
16901
16902         # reduce the max_idle_indexes value to make sure we exceed it
16903         for param in "changelog_max_idle_indexes=2097446912" \
16904                      "changelog_max_idle_time=2592000" \
16905                      "changelog_gc=1" \
16906                      "changelog_min_gc_interval=2"; do
16907                 local MDT0=$(facet_svc $SINGLEMDS)
16908                 local var="${param%=*}"
16909                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16910
16911                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16912                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16913                         error "unable to set mdd.*.$param"
16914         done
16915
16916         local start=$SECONDS
16917         for i in $(seq $MDSCOUNT); do
16918                 cl_users=(${CL_USERS[mds$i]})
16919                 cl_user1[mds$i]="${cl_users[0]}"
16920
16921                 [[ -n "${cl_user1[mds$i]}" ]] ||
16922                         error "mds$i: no user registered"
16923         done
16924
16925         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16926         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16927
16928         # ensure we are past the previous changelog_min_gc_interval set above
16929         local sleep2=$((start + 2 - SECONDS))
16930         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16931
16932         # Generate one more changelog to trigger GC
16933         for ((i = 0; i < MDSCOUNT; i++)); do
16934                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16935                         error "create $DIR/$tdir/d$i.3 failed"
16936         done
16937
16938         # ensure gc thread is done
16939         for node in $(mdts_nodes); do
16940                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16941                         error "$node: GC-thread not done"
16942         done
16943
16944         do_nodes $mdts $LCTL set_param fail_loc=0
16945
16946         for (( i = 1; i <= MDSCOUNT; i++ )); do
16947                 # check cl_user1 is purged
16948                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16949                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16950         done
16951         return 0
16952 }
16953 run_test 160s "changelog garbage collect on idle records * time"
16954
16955 test_161a() {
16956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16957
16958         test_mkdir -c1 $DIR/$tdir
16959         cp /etc/hosts $DIR/$tdir/$tfile
16960         test_mkdir -c1 $DIR/$tdir/foo1
16961         test_mkdir -c1 $DIR/$tdir/foo2
16962         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16963         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16964         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16965         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16966         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16967         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16968                 $LFS fid2path $DIR $FID
16969                 error "bad link ea"
16970         fi
16971         # middle
16972         rm $DIR/$tdir/foo2/zachary
16973         # last
16974         rm $DIR/$tdir/foo2/thor
16975         # first
16976         rm $DIR/$tdir/$tfile
16977         # rename
16978         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16979         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16980                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16981         rm $DIR/$tdir/foo2/maggie
16982
16983         # overflow the EA
16984         local longname=$tfile.avg_len_is_thirty_two_
16985         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16986                 error_noexit 'failed to unlink many hardlinks'" EXIT
16987         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16988                 error "failed to hardlink many files"
16989         links=$($LFS fid2path $DIR $FID | wc -l)
16990         echo -n "${links}/1000 links in link EA"
16991         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16992 }
16993 run_test 161a "link ea sanity"
16994
16995 test_161b() {
16996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16997         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16998
16999         local MDTIDX=1
17000         local remote_dir=$DIR/$tdir/remote_dir
17001
17002         mkdir -p $DIR/$tdir
17003         $LFS mkdir -i $MDTIDX $remote_dir ||
17004                 error "create remote directory failed"
17005
17006         cp /etc/hosts $remote_dir/$tfile
17007         mkdir -p $remote_dir/foo1
17008         mkdir -p $remote_dir/foo2
17009         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17010         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17011         ln $remote_dir/$tfile $remote_dir/foo1/luna
17012         ln $remote_dir/$tfile $remote_dir/foo2/thor
17013
17014         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17015                      tr -d ']')
17016         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17017                 $LFS fid2path $DIR $FID
17018                 error "bad link ea"
17019         fi
17020         # middle
17021         rm $remote_dir/foo2/zachary
17022         # last
17023         rm $remote_dir/foo2/thor
17024         # first
17025         rm $remote_dir/$tfile
17026         # rename
17027         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17028         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17029         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17030                 $LFS fid2path $DIR $FID
17031                 error "bad link rename"
17032         fi
17033         rm $remote_dir/foo2/maggie
17034
17035         # overflow the EA
17036         local longname=filename_avg_len_is_thirty_two_
17037         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17038                 error "failed to hardlink many files"
17039         links=$($LFS fid2path $DIR $FID | wc -l)
17040         echo -n "${links}/1000 links in link EA"
17041         [[ ${links} -gt 60 ]] ||
17042                 error "expected at least 60 links in link EA"
17043         unlinkmany $remote_dir/foo2/$longname 1000 ||
17044         error "failed to unlink many hardlinks"
17045 }
17046 run_test 161b "link ea sanity under remote directory"
17047
17048 test_161c() {
17049         remote_mds_nodsh && skip "remote MDS with nodsh"
17050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17051         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17052                 skip "Need MDS version at least 2.1.5"
17053
17054         # define CLF_RENAME_LAST 0x0001
17055         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17056         changelog_register || error "changelog_register failed"
17057
17058         rm -rf $DIR/$tdir
17059         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17060         touch $DIR/$tdir/foo_161c
17061         touch $DIR/$tdir/bar_161c
17062         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17063         changelog_dump | grep RENME | tail -n 5
17064         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17065         changelog_clear 0 || error "changelog_clear failed"
17066         if [ x$flags != "x0x1" ]; then
17067                 error "flag $flags is not 0x1"
17068         fi
17069
17070         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17071         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17072         touch $DIR/$tdir/foo_161c
17073         touch $DIR/$tdir/bar_161c
17074         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17075         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17076         changelog_dump | grep RENME | tail -n 5
17077         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17078         changelog_clear 0 || error "changelog_clear failed"
17079         if [ x$flags != "x0x0" ]; then
17080                 error "flag $flags is not 0x0"
17081         fi
17082         echo "rename overwrite a target having nlink > 1," \
17083                 "changelog record has flags of $flags"
17084
17085         # rename doesn't overwrite a target (changelog flag 0x0)
17086         touch $DIR/$tdir/foo_161c
17087         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17088         changelog_dump | grep RENME | tail -n 5
17089         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17090         changelog_clear 0 || error "changelog_clear failed"
17091         if [ x$flags != "x0x0" ]; then
17092                 error "flag $flags is not 0x0"
17093         fi
17094         echo "rename doesn't overwrite a target," \
17095                 "changelog record has flags of $flags"
17096
17097         # define CLF_UNLINK_LAST 0x0001
17098         # unlink a file having nlink = 1 (changelog flag 0x1)
17099         rm -f $DIR/$tdir/foo2_161c
17100         changelog_dump | grep UNLNK | tail -n 5
17101         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17102         changelog_clear 0 || error "changelog_clear failed"
17103         if [ x$flags != "x0x1" ]; then
17104                 error "flag $flags is not 0x1"
17105         fi
17106         echo "unlink a file having nlink = 1," \
17107                 "changelog record has flags of $flags"
17108
17109         # unlink a file having nlink > 1 (changelog flag 0x0)
17110         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17111         rm -f $DIR/$tdir/foobar_161c
17112         changelog_dump | grep UNLNK | tail -n 5
17113         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17114         changelog_clear 0 || error "changelog_clear failed"
17115         if [ x$flags != "x0x0" ]; then
17116                 error "flag $flags is not 0x0"
17117         fi
17118         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17119 }
17120 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17121
17122 test_161d() {
17123         remote_mds_nodsh && skip "remote MDS with nodsh"
17124         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17125
17126         local pid
17127         local fid
17128
17129         changelog_register || error "changelog_register failed"
17130
17131         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17132         # interfer with $MOUNT/.lustre/fid/ access
17133         mkdir $DIR/$tdir
17134         [[ $? -eq 0 ]] || error "mkdir failed"
17135
17136         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17137         $LCTL set_param fail_loc=0x8000140c
17138         # 5s pause
17139         $LCTL set_param fail_val=5
17140
17141         # create file
17142         echo foofoo > $DIR/$tdir/$tfile &
17143         pid=$!
17144
17145         # wait for create to be delayed
17146         sleep 2
17147
17148         ps -p $pid
17149         [[ $? -eq 0 ]] || error "create should be blocked"
17150
17151         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17152         stack_trap "rm -f $tempfile"
17153         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17154         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17155         # some delay may occur during ChangeLog publishing and file read just
17156         # above, that could allow file write to happen finally
17157         [[ -s $tempfile ]] && echo "file should be empty"
17158
17159         $LCTL set_param fail_loc=0
17160
17161         wait $pid
17162         [[ $? -eq 0 ]] || error "create failed"
17163 }
17164 run_test 161d "create with concurrent .lustre/fid access"
17165
17166 check_path() {
17167         local expected="$1"
17168         shift
17169         local fid="$2"
17170
17171         local path
17172         path=$($LFS fid2path "$@")
17173         local rc=$?
17174
17175         if [ $rc -ne 0 ]; then
17176                 error "path looked up of '$expected' failed: rc=$rc"
17177         elif [ "$path" != "$expected" ]; then
17178                 error "path looked up '$path' instead of '$expected'"
17179         else
17180                 echo "FID '$fid' resolves to path '$path' as expected"
17181         fi
17182 }
17183
17184 test_162a() { # was test_162
17185         test_mkdir -p -c1 $DIR/$tdir/d2
17186         touch $DIR/$tdir/d2/$tfile
17187         touch $DIR/$tdir/d2/x1
17188         touch $DIR/$tdir/d2/x2
17189         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17190         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17191         # regular file
17192         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17193         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17194
17195         # softlink
17196         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17197         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17198         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17199
17200         # softlink to wrong file
17201         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17202         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17203         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17204
17205         # hardlink
17206         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17207         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17208         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17209         # fid2path dir/fsname should both work
17210         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17211         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17212
17213         # hardlink count: check that there are 2 links
17214         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17215         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17216
17217         # hardlink indexing: remove the first link
17218         rm $DIR/$tdir/d2/p/q/r/hlink
17219         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17220 }
17221 run_test 162a "path lookup sanity"
17222
17223 test_162b() {
17224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17225         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17226
17227         mkdir $DIR/$tdir
17228         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17229                                 error "create striped dir failed"
17230
17231         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17232                                         tail -n 1 | awk '{print $2}')
17233         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17234
17235         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17236         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17237
17238         # regular file
17239         for ((i=0;i<5;i++)); do
17240                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17241                         error "get fid for f$i failed"
17242                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17243
17244                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17245                         error "get fid for d$i failed"
17246                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17247         done
17248
17249         return 0
17250 }
17251 run_test 162b "striped directory path lookup sanity"
17252
17253 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17254 test_162c() {
17255         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17256                 skip "Need MDS version at least 2.7.51"
17257
17258         local lpath=$tdir.local
17259         local rpath=$tdir.remote
17260
17261         test_mkdir $DIR/$lpath
17262         test_mkdir $DIR/$rpath
17263
17264         for ((i = 0; i <= 101; i++)); do
17265                 lpath="$lpath/$i"
17266                 mkdir $DIR/$lpath
17267                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17268                         error "get fid for local directory $DIR/$lpath failed"
17269                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17270
17271                 rpath="$rpath/$i"
17272                 test_mkdir $DIR/$rpath
17273                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17274                         error "get fid for remote directory $DIR/$rpath failed"
17275                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17276         done
17277
17278         return 0
17279 }
17280 run_test 162c "fid2path works with paths 100 or more directories deep"
17281
17282 oalr_event_count() {
17283         local event="${1}"
17284         local trace="${2}"
17285
17286         awk -v name="${FSNAME}-OST0000" \
17287             -v event="${event}" \
17288             '$1 == "TRACE" && $2 == event && $3 == name' \
17289             "${trace}" |
17290         wc -l
17291 }
17292
17293 oalr_expect_event_count() {
17294         local event="${1}"
17295         local trace="${2}"
17296         local expect="${3}"
17297         local count
17298
17299         count=$(oalr_event_count "${event}" "${trace}")
17300         if ((count == expect)); then
17301                 return 0
17302         fi
17303
17304         error_noexit "${event} event count was '${count}', expected ${expect}"
17305         cat "${trace}" >&2
17306         exit 1
17307 }
17308
17309 cleanup_165() {
17310         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17311         stop ost1
17312         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17313 }
17314
17315 setup_165() {
17316         sync # Flush previous IOs so we can count log entries.
17317         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17318         stack_trap cleanup_165 EXIT
17319 }
17320
17321 test_165a() {
17322         local trace="/tmp/${tfile}.trace"
17323         local rc
17324         local count
17325
17326         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17327                 skip "OFD access log unsupported"
17328
17329         setup_165
17330         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17331         sleep 5
17332
17333         do_facet ost1 ofd_access_log_reader --list
17334         stop ost1
17335
17336         do_facet ost1 killall -TERM ofd_access_log_reader
17337         wait
17338         rc=$?
17339
17340         if ((rc != 0)); then
17341                 error "ofd_access_log_reader exited with rc = '${rc}'"
17342         fi
17343
17344         # Parse trace file for discovery events:
17345         oalr_expect_event_count alr_log_add "${trace}" 1
17346         oalr_expect_event_count alr_log_eof "${trace}" 1
17347         oalr_expect_event_count alr_log_free "${trace}" 1
17348 }
17349 run_test 165a "ofd access log discovery"
17350
17351 test_165b() {
17352         local trace="/tmp/${tfile}.trace"
17353         local file="${DIR}/${tfile}"
17354         local pfid1
17355         local pfid2
17356         local -a entry
17357         local rc
17358         local count
17359         local size
17360         local flags
17361
17362         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17363                 skip "OFD access log unsupported"
17364
17365         setup_165
17366         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17367         sleep 5
17368
17369         do_facet ost1 ofd_access_log_reader --list
17370
17371         lfs setstripe -c 1 -i 0 "${file}"
17372         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17373                 error "cannot create '${file}'"
17374
17375         sleep 5
17376         do_facet ost1 killall -TERM ofd_access_log_reader
17377         wait
17378         rc=$?
17379
17380         if ((rc != 0)); then
17381                 error "ofd_access_log_reader exited with rc = '${rc}'"
17382         fi
17383
17384         oalr_expect_event_count alr_log_entry "${trace}" 1
17385
17386         pfid1=$($LFS path2fid "${file}")
17387
17388         # 1     2             3   4    5     6   7    8    9     10
17389         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17390         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17391
17392         echo "entry = '${entry[*]}'" >&2
17393
17394         pfid2=${entry[4]}
17395         if [[ "${pfid1}" != "${pfid2}" ]]; then
17396                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17397         fi
17398
17399         size=${entry[8]}
17400         if ((size != 1048576)); then
17401                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17402         fi
17403
17404         flags=${entry[10]}
17405         if [[ "${flags}" != "w" ]]; then
17406                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17407         fi
17408
17409         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17410         sleep 5
17411
17412         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17413                 error "cannot read '${file}'"
17414         sleep 5
17415
17416         do_facet ost1 killall -TERM ofd_access_log_reader
17417         wait
17418         rc=$?
17419
17420         if ((rc != 0)); then
17421                 error "ofd_access_log_reader exited with rc = '${rc}'"
17422         fi
17423
17424         oalr_expect_event_count alr_log_entry "${trace}" 1
17425
17426         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17427         echo "entry = '${entry[*]}'" >&2
17428
17429         pfid2=${entry[4]}
17430         if [[ "${pfid1}" != "${pfid2}" ]]; then
17431                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17432         fi
17433
17434         size=${entry[8]}
17435         if ((size != 524288)); then
17436                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17437         fi
17438
17439         flags=${entry[10]}
17440         if [[ "${flags}" != "r" ]]; then
17441                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17442         fi
17443 }
17444 run_test 165b "ofd access log entries are produced and consumed"
17445
17446 test_165c() {
17447         local trace="/tmp/${tfile}.trace"
17448         local file="${DIR}/${tdir}/${tfile}"
17449
17450         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17451                 skip "OFD access log unsupported"
17452
17453         test_mkdir "${DIR}/${tdir}"
17454
17455         setup_165
17456         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17457         sleep 5
17458
17459         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17460
17461         # 4096 / 64 = 64. Create twice as many entries.
17462         for ((i = 0; i < 128; i++)); do
17463                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17464                         error "cannot create file"
17465         done
17466
17467         sync
17468
17469         do_facet ost1 killall -TERM ofd_access_log_reader
17470         wait
17471         rc=$?
17472         if ((rc != 0)); then
17473                 error "ofd_access_log_reader exited with rc = '${rc}'"
17474         fi
17475
17476         unlinkmany  "${file}-%d" 128
17477 }
17478 run_test 165c "full ofd access logs do not block IOs"
17479
17480 oal_get_read_count() {
17481         local stats="$1"
17482
17483         # STATS lustre-OST0001 alr_read_count 1
17484
17485         do_facet ost1 cat "${stats}" |
17486         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17487              END { print count; }'
17488 }
17489
17490 oal_expect_read_count() {
17491         local stats="$1"
17492         local count
17493         local expect="$2"
17494
17495         # Ask ofd_access_log_reader to write stats.
17496         do_facet ost1 killall -USR1 ofd_access_log_reader
17497
17498         # Allow some time for things to happen.
17499         sleep 1
17500
17501         count=$(oal_get_read_count "${stats}")
17502         if ((count == expect)); then
17503                 return 0
17504         fi
17505
17506         error_noexit "bad read count, got ${count}, expected ${expect}"
17507         do_facet ost1 cat "${stats}" >&2
17508         exit 1
17509 }
17510
17511 test_165d() {
17512         local stats="/tmp/${tfile}.stats"
17513         local file="${DIR}/${tdir}/${tfile}"
17514         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17515
17516         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17517                 skip "OFD access log unsupported"
17518
17519         test_mkdir "${DIR}/${tdir}"
17520
17521         setup_165
17522         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17523         sleep 5
17524
17525         lfs setstripe -c 1 -i 0 "${file}"
17526
17527         do_facet ost1 lctl set_param "${param}=rw"
17528         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17529                 error "cannot create '${file}'"
17530         oal_expect_read_count "${stats}" 1
17531
17532         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17533                 error "cannot read '${file}'"
17534         oal_expect_read_count "${stats}" 2
17535
17536         do_facet ost1 lctl set_param "${param}=r"
17537         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17538                 error "cannot create '${file}'"
17539         oal_expect_read_count "${stats}" 2
17540
17541         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17542                 error "cannot read '${file}'"
17543         oal_expect_read_count "${stats}" 3
17544
17545         do_facet ost1 lctl set_param "${param}=w"
17546         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17547                 error "cannot create '${file}'"
17548         oal_expect_read_count "${stats}" 4
17549
17550         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17551                 error "cannot read '${file}'"
17552         oal_expect_read_count "${stats}" 4
17553
17554         do_facet ost1 lctl set_param "${param}=0"
17555         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17556                 error "cannot create '${file}'"
17557         oal_expect_read_count "${stats}" 4
17558
17559         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17560                 error "cannot read '${file}'"
17561         oal_expect_read_count "${stats}" 4
17562
17563         do_facet ost1 killall -TERM ofd_access_log_reader
17564         wait
17565         rc=$?
17566         if ((rc != 0)); then
17567                 error "ofd_access_log_reader exited with rc = '${rc}'"
17568         fi
17569 }
17570 run_test 165d "ofd_access_log mask works"
17571
17572 test_165e() {
17573         local stats="/tmp/${tfile}.stats"
17574         local file0="${DIR}/${tdir}-0/${tfile}"
17575         local file1="${DIR}/${tdir}-1/${tfile}"
17576
17577         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17578                 skip "OFD access log unsupported"
17579
17580         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17581
17582         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17583         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17584
17585         lfs setstripe -c 1 -i 0 "${file0}"
17586         lfs setstripe -c 1 -i 0 "${file1}"
17587
17588         setup_165
17589         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17590         sleep 5
17591
17592         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17593                 error "cannot create '${file0}'"
17594         sync
17595         oal_expect_read_count "${stats}" 0
17596
17597         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17598                 error "cannot create '${file1}'"
17599         sync
17600         oal_expect_read_count "${stats}" 1
17601
17602         do_facet ost1 killall -TERM ofd_access_log_reader
17603         wait
17604         rc=$?
17605         if ((rc != 0)); then
17606                 error "ofd_access_log_reader exited with rc = '${rc}'"
17607         fi
17608 }
17609 run_test 165e "ofd_access_log MDT index filter works"
17610
17611 test_165f() {
17612         local trace="/tmp/${tfile}.trace"
17613         local rc
17614         local count
17615
17616         setup_165
17617         do_facet ost1 timeout 60 ofd_access_log_reader \
17618                 --exit-on-close --debug=- --trace=- > "${trace}" &
17619         sleep 5
17620         stop ost1
17621
17622         wait
17623         rc=$?
17624
17625         if ((rc != 0)); then
17626                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17627                 cat "${trace}"
17628                 exit 1
17629         fi
17630 }
17631 run_test 165f "ofd_access_log_reader --exit-on-close works"
17632
17633 test_169() {
17634         # do directio so as not to populate the page cache
17635         log "creating a 10 Mb file"
17636         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17637                 error "multiop failed while creating a file"
17638         log "starting reads"
17639         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17640         log "truncating the file"
17641         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17642                 error "multiop failed while truncating the file"
17643         log "killing dd"
17644         kill %+ || true # reads might have finished
17645         echo "wait until dd is finished"
17646         wait
17647         log "removing the temporary file"
17648         rm -rf $DIR/$tfile || error "tmp file removal failed"
17649 }
17650 run_test 169 "parallel read and truncate should not deadlock"
17651
17652 test_170() {
17653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17654
17655         $LCTL clear     # bug 18514
17656         $LCTL debug_daemon start $TMP/${tfile}_log_good
17657         touch $DIR/$tfile
17658         $LCTL debug_daemon stop
17659         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17660                 error "sed failed to read log_good"
17661
17662         $LCTL debug_daemon start $TMP/${tfile}_log_good
17663         rm -rf $DIR/$tfile
17664         $LCTL debug_daemon stop
17665
17666         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17667                error "lctl df log_bad failed"
17668
17669         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17670         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17671
17672         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17673         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17674
17675         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17676                 error "bad_line good_line1 good_line2 are empty"
17677
17678         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17679         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17680         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17681
17682         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17683         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17684         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17685
17686         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17687                 error "bad_line_new good_line_new are empty"
17688
17689         local expected_good=$((good_line1 + good_line2*2))
17690
17691         rm -f $TMP/${tfile}*
17692         # LU-231, short malformed line may not be counted into bad lines
17693         if [ $bad_line -ne $bad_line_new ] &&
17694                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17695                 error "expected $bad_line bad lines, but got $bad_line_new"
17696                 return 1
17697         fi
17698
17699         if [ $expected_good -ne $good_line_new ]; then
17700                 error "expected $expected_good good lines, but got $good_line_new"
17701                 return 2
17702         fi
17703         true
17704 }
17705 run_test 170 "test lctl df to handle corrupted log ====================="
17706
17707 test_171() { # bug20592
17708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17709
17710         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17711         $LCTL set_param fail_loc=0x50e
17712         $LCTL set_param fail_val=3000
17713         multiop_bg_pause $DIR/$tfile O_s || true
17714         local MULTIPID=$!
17715         kill -USR1 $MULTIPID
17716         # cause log dump
17717         sleep 3
17718         wait $MULTIPID
17719         if dmesg | grep "recursive fault"; then
17720                 error "caught a recursive fault"
17721         fi
17722         $LCTL set_param fail_loc=0
17723         true
17724 }
17725 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17726
17727 # it would be good to share it with obdfilter-survey/iokit-libecho code
17728 setup_obdecho_osc () {
17729         local rc=0
17730         local ost_nid=$1
17731         local obdfilter_name=$2
17732         echo "Creating new osc for $obdfilter_name on $ost_nid"
17733         # make sure we can find loopback nid
17734         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17735
17736         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17737                            ${obdfilter_name}_osc_UUID || rc=2; }
17738         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17739                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17740         return $rc
17741 }
17742
17743 cleanup_obdecho_osc () {
17744         local obdfilter_name=$1
17745         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17746         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17747         return 0
17748 }
17749
17750 obdecho_test() {
17751         local OBD=$1
17752         local node=$2
17753         local pages=${3:-64}
17754         local rc=0
17755         local id
17756
17757         local count=10
17758         local obd_size=$(get_obd_size $node $OBD)
17759         local page_size=$(get_page_size $node)
17760         if [[ -n "$obd_size" ]]; then
17761                 local new_count=$((obd_size / (pages * page_size / 1024)))
17762                 [[ $new_count -ge $count ]] || count=$new_count
17763         fi
17764
17765         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17766         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17767                            rc=2; }
17768         if [ $rc -eq 0 ]; then
17769             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17770             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17771         fi
17772         echo "New object id is $id"
17773         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17774                            rc=4; }
17775         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17776                            "test_brw $count w v $pages $id" || rc=4; }
17777         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17778                            rc=4; }
17779         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17780                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17781         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17782                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17783         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17784         return $rc
17785 }
17786
17787 test_180a() {
17788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17789
17790         if ! [ -d /sys/fs/lustre/echo_client ] &&
17791            ! module_loaded obdecho; then
17792                 load_module obdecho/obdecho &&
17793                         stack_trap "rmmod obdecho" EXIT ||
17794                         error "unable to load obdecho on client"
17795         fi
17796
17797         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17798         local host=$($LCTL get_param -n osc.$osc.import |
17799                      awk '/current_connection:/ { print $2 }' )
17800         local target=$($LCTL get_param -n osc.$osc.import |
17801                        awk '/target:/ { print $2 }' )
17802         target=${target%_UUID}
17803
17804         if [ -n "$target" ]; then
17805                 setup_obdecho_osc $host $target &&
17806                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17807                         { error "obdecho setup failed with $?"; return; }
17808
17809                 obdecho_test ${target}_osc client ||
17810                         error "obdecho_test failed on ${target}_osc"
17811         else
17812                 $LCTL get_param osc.$osc.import
17813                 error "there is no osc.$osc.import target"
17814         fi
17815 }
17816 run_test 180a "test obdecho on osc"
17817
17818 test_180b() {
17819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17820         remote_ost_nodsh && skip "remote OST with nodsh"
17821
17822         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17823                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17824                 error "failed to load module obdecho"
17825
17826         local target=$(do_facet ost1 $LCTL dl |
17827                        awk '/obdfilter/ { print $4; exit; }')
17828
17829         if [ -n "$target" ]; then
17830                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17831         else
17832                 do_facet ost1 $LCTL dl
17833                 error "there is no obdfilter target on ost1"
17834         fi
17835 }
17836 run_test 180b "test obdecho directly on obdfilter"
17837
17838 test_180c() { # LU-2598
17839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17840         remote_ost_nodsh && skip "remote OST with nodsh"
17841         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17842                 skip "Need MDS version at least 2.4.0"
17843
17844         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17845                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17846                 error "failed to load module obdecho"
17847
17848         local target=$(do_facet ost1 $LCTL dl |
17849                        awk '/obdfilter/ { print $4; exit; }')
17850
17851         if [ -n "$target" ]; then
17852                 local pages=16384 # 64MB bulk I/O RPC size
17853
17854                 obdecho_test "$target" ost1 "$pages" ||
17855                         error "obdecho_test with pages=$pages failed with $?"
17856         else
17857                 do_facet ost1 $LCTL dl
17858                 error "there is no obdfilter target on ost1"
17859         fi
17860 }
17861 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17862
17863 test_181() { # bug 22177
17864         test_mkdir $DIR/$tdir
17865         # create enough files to index the directory
17866         createmany -o $DIR/$tdir/foobar 4000
17867         # print attributes for debug purpose
17868         lsattr -d .
17869         # open dir
17870         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17871         MULTIPID=$!
17872         # remove the files & current working dir
17873         unlinkmany $DIR/$tdir/foobar 4000
17874         rmdir $DIR/$tdir
17875         kill -USR1 $MULTIPID
17876         wait $MULTIPID
17877         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17878         return 0
17879 }
17880 run_test 181 "Test open-unlinked dir ========================"
17881
17882 test_182() {
17883         local fcount=1000
17884         local tcount=10
17885
17886         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17887
17888         $LCTL set_param mdc.*.rpc_stats=clear
17889
17890         for (( i = 0; i < $tcount; i++ )) ; do
17891                 mkdir $DIR/$tdir/$i
17892         done
17893
17894         for (( i = 0; i < $tcount; i++ )) ; do
17895                 createmany -o $DIR/$tdir/$i/f- $fcount &
17896         done
17897         wait
17898
17899         for (( i = 0; i < $tcount; i++ )) ; do
17900                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17901         done
17902         wait
17903
17904         $LCTL get_param mdc.*.rpc_stats
17905
17906         rm -rf $DIR/$tdir
17907 }
17908 run_test 182 "Test parallel modify metadata operations ================"
17909
17910 test_183() { # LU-2275
17911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17912         remote_mds_nodsh && skip "remote MDS with nodsh"
17913         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17914                 skip "Need MDS version at least 2.3.56"
17915
17916         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17917         echo aaa > $DIR/$tdir/$tfile
17918
17919 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17920         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17921
17922         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17923         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17924
17925         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17926
17927         # Flush negative dentry cache
17928         touch $DIR/$tdir/$tfile
17929
17930         # We are not checking for any leaked references here, they'll
17931         # become evident next time we do cleanup with module unload.
17932         rm -rf $DIR/$tdir
17933 }
17934 run_test 183 "No crash or request leak in case of strange dispositions ========"
17935
17936 # test suite 184 is for LU-2016, LU-2017
17937 test_184a() {
17938         check_swap_layouts_support
17939
17940         dir0=$DIR/$tdir/$testnum
17941         test_mkdir -p -c1 $dir0
17942         ref1=/etc/passwd
17943         ref2=/etc/group
17944         file1=$dir0/f1
17945         file2=$dir0/f2
17946         $LFS setstripe -c1 $file1
17947         cp $ref1 $file1
17948         $LFS setstripe -c2 $file2
17949         cp $ref2 $file2
17950         gen1=$($LFS getstripe -g $file1)
17951         gen2=$($LFS getstripe -g $file2)
17952
17953         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17954         gen=$($LFS getstripe -g $file1)
17955         [[ $gen1 != $gen ]] ||
17956                 error "Layout generation on $file1 does not change"
17957         gen=$($LFS getstripe -g $file2)
17958         [[ $gen2 != $gen ]] ||
17959                 error "Layout generation on $file2 does not change"
17960
17961         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17962         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17963
17964         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17965 }
17966 run_test 184a "Basic layout swap"
17967
17968 test_184b() {
17969         check_swap_layouts_support
17970
17971         dir0=$DIR/$tdir/$testnum
17972         mkdir -p $dir0 || error "creating dir $dir0"
17973         file1=$dir0/f1
17974         file2=$dir0/f2
17975         file3=$dir0/f3
17976         dir1=$dir0/d1
17977         dir2=$dir0/d2
17978         mkdir $dir1 $dir2
17979         $LFS setstripe -c1 $file1
17980         $LFS setstripe -c2 $file2
17981         $LFS setstripe -c1 $file3
17982         chown $RUNAS_ID $file3
17983         gen1=$($LFS getstripe -g $file1)
17984         gen2=$($LFS getstripe -g $file2)
17985
17986         $LFS swap_layouts $dir1 $dir2 &&
17987                 error "swap of directories layouts should fail"
17988         $LFS swap_layouts $dir1 $file1 &&
17989                 error "swap of directory and file layouts should fail"
17990         $RUNAS $LFS swap_layouts $file1 $file2 &&
17991                 error "swap of file we cannot write should fail"
17992         $LFS swap_layouts $file1 $file3 &&
17993                 error "swap of file with different owner should fail"
17994         /bin/true # to clear error code
17995 }
17996 run_test 184b "Forbidden layout swap (will generate errors)"
17997
17998 test_184c() {
17999         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18000         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18001         check_swap_layouts_support
18002         check_swap_layout_no_dom $DIR
18003
18004         local dir0=$DIR/$tdir/$testnum
18005         mkdir -p $dir0 || error "creating dir $dir0"
18006
18007         local ref1=$dir0/ref1
18008         local ref2=$dir0/ref2
18009         local file1=$dir0/file1
18010         local file2=$dir0/file2
18011         # create a file large enough for the concurrent test
18012         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18013         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18014         echo "ref file size: ref1($(stat -c %s $ref1))," \
18015              "ref2($(stat -c %s $ref2))"
18016
18017         cp $ref2 $file2
18018         dd if=$ref1 of=$file1 bs=16k &
18019         local DD_PID=$!
18020
18021         # Make sure dd starts to copy file, but wait at most 5 seconds
18022         local loops=0
18023         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18024
18025         $LFS swap_layouts $file1 $file2
18026         local rc=$?
18027         wait $DD_PID
18028         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18029         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18030
18031         # how many bytes copied before swapping layout
18032         local copied=$(stat -c %s $file2)
18033         local remaining=$(stat -c %s $ref1)
18034         remaining=$((remaining - copied))
18035         echo "Copied $copied bytes before swapping layout..."
18036
18037         cmp -n $copied $file1 $ref2 | grep differ &&
18038                 error "Content mismatch [0, $copied) of ref2 and file1"
18039         cmp -n $copied $file2 $ref1 ||
18040                 error "Content mismatch [0, $copied) of ref1 and file2"
18041         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18042                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18043
18044         # clean up
18045         rm -f $ref1 $ref2 $file1 $file2
18046 }
18047 run_test 184c "Concurrent write and layout swap"
18048
18049 test_184d() {
18050         check_swap_layouts_support
18051         check_swap_layout_no_dom $DIR
18052         [ -z "$(which getfattr 2>/dev/null)" ] &&
18053                 skip_env "no getfattr command"
18054
18055         local file1=$DIR/$tdir/$tfile-1
18056         local file2=$DIR/$tdir/$tfile-2
18057         local file3=$DIR/$tdir/$tfile-3
18058         local lovea1
18059         local lovea2
18060
18061         mkdir -p $DIR/$tdir
18062         touch $file1 || error "create $file1 failed"
18063         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18064                 error "create $file2 failed"
18065         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18066                 error "create $file3 failed"
18067         lovea1=$(get_layout_param $file1)
18068
18069         $LFS swap_layouts $file2 $file3 ||
18070                 error "swap $file2 $file3 layouts failed"
18071         $LFS swap_layouts $file1 $file2 ||
18072                 error "swap $file1 $file2 layouts failed"
18073
18074         lovea2=$(get_layout_param $file2)
18075         echo "$lovea1"
18076         echo "$lovea2"
18077         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18078
18079         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18080         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18081 }
18082 run_test 184d "allow stripeless layouts swap"
18083
18084 test_184e() {
18085         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18086                 skip "Need MDS version at least 2.6.94"
18087         check_swap_layouts_support
18088         check_swap_layout_no_dom $DIR
18089         [ -z "$(which getfattr 2>/dev/null)" ] &&
18090                 skip_env "no getfattr command"
18091
18092         local file1=$DIR/$tdir/$tfile-1
18093         local file2=$DIR/$tdir/$tfile-2
18094         local file3=$DIR/$tdir/$tfile-3
18095         local lovea
18096
18097         mkdir -p $DIR/$tdir
18098         touch $file1 || error "create $file1 failed"
18099         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18100                 error "create $file2 failed"
18101         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18102                 error "create $file3 failed"
18103
18104         $LFS swap_layouts $file1 $file2 ||
18105                 error "swap $file1 $file2 layouts failed"
18106
18107         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18108         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18109
18110         echo 123 > $file1 || error "Should be able to write into $file1"
18111
18112         $LFS swap_layouts $file1 $file3 ||
18113                 error "swap $file1 $file3 layouts failed"
18114
18115         echo 123 > $file1 || error "Should be able to write into $file1"
18116
18117         rm -rf $file1 $file2 $file3
18118 }
18119 run_test 184e "Recreate layout after stripeless layout swaps"
18120
18121 test_184f() {
18122         # Create a file with name longer than sizeof(struct stat) ==
18123         # 144 to see if we can get chars from the file name to appear
18124         # in the returned striping. Note that 'f' == 0x66.
18125         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18126
18127         mkdir -p $DIR/$tdir
18128         mcreate $DIR/$tdir/$file
18129         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18130                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18131         fi
18132 }
18133 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18134
18135 test_185() { # LU-2441
18136         # LU-3553 - no volatile file support in old servers
18137         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18138                 skip "Need MDS version at least 2.3.60"
18139
18140         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18141         touch $DIR/$tdir/spoo
18142         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18143         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18144                 error "cannot create/write a volatile file"
18145         [ "$FILESET" == "" ] &&
18146         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18147                 error "FID is still valid after close"
18148
18149         multiop_bg_pause $DIR/$tdir vVw4096_c
18150         local multi_pid=$!
18151
18152         local OLD_IFS=$IFS
18153         IFS=":"
18154         local fidv=($fid)
18155         IFS=$OLD_IFS
18156         # assume that the next FID for this client is sequential, since stdout
18157         # is unfortunately eaten by multiop_bg_pause
18158         local n=$((${fidv[1]} + 1))
18159         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18160         if [ "$FILESET" == "" ]; then
18161                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18162                         error "FID is missing before close"
18163         fi
18164         kill -USR1 $multi_pid
18165         # 1 second delay, so if mtime change we will see it
18166         sleep 1
18167         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18168         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18169 }
18170 run_test 185 "Volatile file support"
18171
18172 function create_check_volatile() {
18173         local idx=$1
18174         local tgt
18175
18176         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18177         local PID=$!
18178         sleep 1
18179         local FID=$(cat /tmp/${tfile}.fid)
18180         [ "$FID" == "" ] && error "can't get FID for volatile"
18181         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18182         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18183         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18184         kill -USR1 $PID
18185         wait
18186         sleep 1
18187         cancel_lru_locks mdc # flush opencache
18188         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18189         return 0
18190 }
18191
18192 test_185a(){
18193         # LU-12516 - volatile creation via .lustre
18194         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18195                 skip "Need MDS version at least 2.3.55"
18196
18197         create_check_volatile 0
18198         [ $MDSCOUNT -lt 2 ] && return 0
18199
18200         # DNE case
18201         create_check_volatile 1
18202
18203         return 0
18204 }
18205 run_test 185a "Volatile file creation in .lustre/fid/"
18206
18207 test_187a() {
18208         remote_mds_nodsh && skip "remote MDS with nodsh"
18209         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18210                 skip "Need MDS version at least 2.3.0"
18211
18212         local dir0=$DIR/$tdir/$testnum
18213         mkdir -p $dir0 || error "creating dir $dir0"
18214
18215         local file=$dir0/file1
18216         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18217         local dv1=$($LFS data_version $file)
18218         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18219         local dv2=$($LFS data_version $file)
18220         [[ $dv1 != $dv2 ]] ||
18221                 error "data version did not change on write $dv1 == $dv2"
18222
18223         # clean up
18224         rm -f $file1
18225 }
18226 run_test 187a "Test data version change"
18227
18228 test_187b() {
18229         remote_mds_nodsh && skip "remote MDS with nodsh"
18230         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18231                 skip "Need MDS version at least 2.3.0"
18232
18233         local dir0=$DIR/$tdir/$testnum
18234         mkdir -p $dir0 || error "creating dir $dir0"
18235
18236         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18237         [[ ${DV[0]} != ${DV[1]} ]] ||
18238                 error "data version did not change on write"\
18239                       " ${DV[0]} == ${DV[1]}"
18240
18241         # clean up
18242         rm -f $file1
18243 }
18244 run_test 187b "Test data version change on volatile file"
18245
18246 test_200() {
18247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18248         remote_mgs_nodsh && skip "remote MGS with nodsh"
18249         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18250
18251         local POOL=${POOL:-cea1}
18252         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18253         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18254         # Pool OST targets
18255         local first_ost=0
18256         local last_ost=$(($OSTCOUNT - 1))
18257         local ost_step=2
18258         local ost_list=$(seq $first_ost $ost_step $last_ost)
18259         local ost_range="$first_ost $last_ost $ost_step"
18260         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18261         local file_dir=$POOL_ROOT/file_tst
18262         local subdir=$test_path/subdir
18263         local rc=0
18264
18265         while : ; do
18266                 # former test_200a test_200b
18267                 pool_add $POOL                          || { rc=$? ; break; }
18268                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18269                 # former test_200c test_200d
18270                 mkdir -p $test_path
18271                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18272                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18273                 mkdir -p $subdir
18274                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18275                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18276                                                         || { rc=$? ; break; }
18277                 # former test_200e test_200f
18278                 local files=$((OSTCOUNT*3))
18279                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18280                                                         || { rc=$? ; break; }
18281                 pool_create_files $POOL $file_dir $files "$ost_list" \
18282                                                         || { rc=$? ; break; }
18283                 # former test_200g test_200h
18284                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18285                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18286
18287                 # former test_201a test_201b test_201c
18288                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18289
18290                 local f=$test_path/$tfile
18291                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18292                 pool_remove $POOL $f                    || { rc=$? ; break; }
18293                 break
18294         done
18295
18296         destroy_test_pools
18297
18298         return $rc
18299 }
18300 run_test 200 "OST pools"
18301
18302 # usage: default_attr <count | size | offset>
18303 default_attr() {
18304         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18305 }
18306
18307 # usage: check_default_stripe_attr
18308 check_default_stripe_attr() {
18309         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18310         case $1 in
18311         --stripe-count|-c)
18312                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18313         --stripe-size|-S)
18314                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18315         --stripe-index|-i)
18316                 EXPECTED=-1;;
18317         *)
18318                 error "unknown getstripe attr '$1'"
18319         esac
18320
18321         [ $ACTUAL == $EXPECTED ] ||
18322                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18323 }
18324
18325 test_204a() {
18326         test_mkdir $DIR/$tdir
18327         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18328
18329         check_default_stripe_attr --stripe-count
18330         check_default_stripe_attr --stripe-size
18331         check_default_stripe_attr --stripe-index
18332 }
18333 run_test 204a "Print default stripe attributes"
18334
18335 test_204b() {
18336         test_mkdir $DIR/$tdir
18337         $LFS setstripe --stripe-count 1 $DIR/$tdir
18338
18339         check_default_stripe_attr --stripe-size
18340         check_default_stripe_attr --stripe-index
18341 }
18342 run_test 204b "Print default stripe size and offset"
18343
18344 test_204c() {
18345         test_mkdir $DIR/$tdir
18346         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18347
18348         check_default_stripe_attr --stripe-count
18349         check_default_stripe_attr --stripe-index
18350 }
18351 run_test 204c "Print default stripe count and offset"
18352
18353 test_204d() {
18354         test_mkdir $DIR/$tdir
18355         $LFS setstripe --stripe-index 0 $DIR/$tdir
18356
18357         check_default_stripe_attr --stripe-count
18358         check_default_stripe_attr --stripe-size
18359 }
18360 run_test 204d "Print default stripe count and size"
18361
18362 test_204e() {
18363         test_mkdir $DIR/$tdir
18364         $LFS setstripe -d $DIR/$tdir
18365
18366         check_default_stripe_attr --stripe-count --raw
18367         check_default_stripe_attr --stripe-size --raw
18368         check_default_stripe_attr --stripe-index --raw
18369 }
18370 run_test 204e "Print raw stripe attributes"
18371
18372 test_204f() {
18373         test_mkdir $DIR/$tdir
18374         $LFS setstripe --stripe-count 1 $DIR/$tdir
18375
18376         check_default_stripe_attr --stripe-size --raw
18377         check_default_stripe_attr --stripe-index --raw
18378 }
18379 run_test 204f "Print raw stripe size and offset"
18380
18381 test_204g() {
18382         test_mkdir $DIR/$tdir
18383         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18384
18385         check_default_stripe_attr --stripe-count --raw
18386         check_default_stripe_attr --stripe-index --raw
18387 }
18388 run_test 204g "Print raw stripe count and offset"
18389
18390 test_204h() {
18391         test_mkdir $DIR/$tdir
18392         $LFS setstripe --stripe-index 0 $DIR/$tdir
18393
18394         check_default_stripe_attr --stripe-count --raw
18395         check_default_stripe_attr --stripe-size --raw
18396 }
18397 run_test 204h "Print raw stripe count and size"
18398
18399 # Figure out which job scheduler is being used, if any,
18400 # or use a fake one
18401 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18402         JOBENV=SLURM_JOB_ID
18403 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18404         JOBENV=LSB_JOBID
18405 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18406         JOBENV=PBS_JOBID
18407 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18408         JOBENV=LOADL_STEP_ID
18409 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18410         JOBENV=JOB_ID
18411 else
18412         $LCTL list_param jobid_name > /dev/null 2>&1
18413         if [ $? -eq 0 ]; then
18414                 JOBENV=nodelocal
18415         else
18416                 JOBENV=FAKE_JOBID
18417         fi
18418 fi
18419 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18420
18421 verify_jobstats() {
18422         local cmd=($1)
18423         shift
18424         local facets="$@"
18425
18426 # we don't really need to clear the stats for this test to work, since each
18427 # command has a unique jobid, but it makes debugging easier if needed.
18428 #       for facet in $facets; do
18429 #               local dev=$(convert_facet2label $facet)
18430 #               # clear old jobstats
18431 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18432 #       done
18433
18434         # use a new JobID for each test, or we might see an old one
18435         [ "$JOBENV" = "FAKE_JOBID" ] &&
18436                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18437
18438         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18439
18440         [ "$JOBENV" = "nodelocal" ] && {
18441                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18442                 $LCTL set_param jobid_name=$FAKE_JOBID
18443                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18444         }
18445
18446         log "Test: ${cmd[*]}"
18447         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18448
18449         if [ $JOBENV = "FAKE_JOBID" ]; then
18450                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18451         else
18452                 ${cmd[*]}
18453         fi
18454
18455         # all files are created on OST0000
18456         for facet in $facets; do
18457                 local stats="*.$(convert_facet2label $facet).job_stats"
18458
18459                 # strip out libtool wrappers for in-tree executables
18460                 if (( $(do_facet $facet lctl get_param $stats |
18461                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18462                         do_facet $facet lctl get_param $stats
18463                         error "No jobstats for $JOBVAL found on $facet::$stats"
18464                 fi
18465         done
18466 }
18467
18468 jobstats_set() {
18469         local new_jobenv=$1
18470
18471         set_persistent_param_and_check client "jobid_var" \
18472                 "$FSNAME.sys.jobid_var" $new_jobenv
18473 }
18474
18475 test_205a() { # Job stats
18476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18477         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18478                 skip "Need MDS version with at least 2.7.1"
18479         remote_mgs_nodsh && skip "remote MGS with nodsh"
18480         remote_mds_nodsh && skip "remote MDS with nodsh"
18481         remote_ost_nodsh && skip "remote OST with nodsh"
18482         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18483                 skip "Server doesn't support jobstats"
18484         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18485
18486         local old_jobenv=$($LCTL get_param -n jobid_var)
18487         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18488
18489         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18490                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18491         else
18492                 stack_trap "do_facet mgs $PERM_CMD \
18493                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18494         fi
18495         changelog_register
18496
18497         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18498                                 mdt.*.job_cleanup_interval | head -n 1)
18499         local new_interval=5
18500         do_facet $SINGLEMDS \
18501                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18502         stack_trap "do_facet $SINGLEMDS \
18503                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18504         local start=$SECONDS
18505
18506         local cmd
18507         # mkdir
18508         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18509         verify_jobstats "$cmd" "$SINGLEMDS"
18510         # rmdir
18511         cmd="rmdir $DIR/$tdir"
18512         verify_jobstats "$cmd" "$SINGLEMDS"
18513         # mkdir on secondary MDT
18514         if [ $MDSCOUNT -gt 1 ]; then
18515                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18516                 verify_jobstats "$cmd" "mds2"
18517         fi
18518         # mknod
18519         cmd="mknod $DIR/$tfile c 1 3"
18520         verify_jobstats "$cmd" "$SINGLEMDS"
18521         # unlink
18522         cmd="rm -f $DIR/$tfile"
18523         verify_jobstats "$cmd" "$SINGLEMDS"
18524         # create all files on OST0000 so verify_jobstats can find OST stats
18525         # open & close
18526         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18527         verify_jobstats "$cmd" "$SINGLEMDS"
18528         # setattr
18529         cmd="touch $DIR/$tfile"
18530         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18531         # write
18532         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18533         verify_jobstats "$cmd" "ost1"
18534         # read
18535         cancel_lru_locks osc
18536         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18537         verify_jobstats "$cmd" "ost1"
18538         # truncate
18539         cmd="$TRUNCATE $DIR/$tfile 0"
18540         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18541         # rename
18542         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18543         verify_jobstats "$cmd" "$SINGLEMDS"
18544         # jobstats expiry - sleep until old stats should be expired
18545         local left=$((new_interval + 5 - (SECONDS - start)))
18546         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18547                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18548                         "0" $left
18549         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18550         verify_jobstats "$cmd" "$SINGLEMDS"
18551         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18552             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18553
18554         # Ensure that jobid are present in changelog (if supported by MDS)
18555         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18556                 changelog_dump | tail -10
18557                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18558                 [ $jobids -eq 9 ] ||
18559                         error "Wrong changelog jobid count $jobids != 9"
18560
18561                 # LU-5862
18562                 JOBENV="disable"
18563                 jobstats_set $JOBENV
18564                 touch $DIR/$tfile
18565                 changelog_dump | grep $tfile
18566                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18567                 [ $jobids -eq 0 ] ||
18568                         error "Unexpected jobids when jobid_var=$JOBENV"
18569         fi
18570
18571         # test '%j' access to environment variable - if supported
18572         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18573                 JOBENV="JOBCOMPLEX"
18574                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18575
18576                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18577         fi
18578
18579         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18580                 JOBENV="JOBCOMPLEX"
18581                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18582
18583                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18584         fi
18585
18586         # test '%j' access to per-session jobid - if supported
18587         if lctl list_param jobid_this_session > /dev/null 2>&1
18588         then
18589                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18590                 lctl set_param jobid_this_session=$USER
18591
18592                 JOBENV="JOBCOMPLEX"
18593                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18594
18595                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18596         fi
18597 }
18598 run_test 205a "Verify job stats"
18599
18600 # LU-13117, LU-13597
18601 test_205b() {
18602         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18603                 skip "Need MDS version at least 2.13.54.91"
18604
18605         job_stats="mdt.*.job_stats"
18606         $LCTL set_param $job_stats=clear
18607         # Setting jobid_var to USER might not be supported
18608         $LCTL set_param jobid_var=USER || true
18609         $LCTL set_param jobid_name="%e.%u"
18610         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18611         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18612                 grep "job_id:.*foolish" &&
18613                         error "Unexpected jobid found"
18614         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18615                 grep "open:.*min.*max.*sum" ||
18616                         error "wrong job_stats format found"
18617 }
18618 run_test 205b "Verify job stats jobid and output format"
18619
18620 # LU-13733
18621 test_205c() {
18622         $LCTL set_param llite.*.stats=0
18623         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18624         $LCTL get_param llite.*.stats
18625         $LCTL get_param llite.*.stats | grep \
18626                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18627                         error "wrong client stats format found"
18628 }
18629 run_test 205c "Verify client stats format"
18630
18631 # LU-1480, LU-1773 and LU-1657
18632 test_206() {
18633         mkdir -p $DIR/$tdir
18634         $LFS setstripe -c -1 $DIR/$tdir
18635 #define OBD_FAIL_LOV_INIT 0x1403
18636         $LCTL set_param fail_loc=0xa0001403
18637         $LCTL set_param fail_val=1
18638         touch $DIR/$tdir/$tfile || true
18639 }
18640 run_test 206 "fail lov_init_raid0() doesn't lbug"
18641
18642 test_207a() {
18643         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18644         local fsz=`stat -c %s $DIR/$tfile`
18645         cancel_lru_locks mdc
18646
18647         # do not return layout in getattr intent
18648 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18649         $LCTL set_param fail_loc=0x170
18650         local sz=`stat -c %s $DIR/$tfile`
18651
18652         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18653
18654         rm -rf $DIR/$tfile
18655 }
18656 run_test 207a "can refresh layout at glimpse"
18657
18658 test_207b() {
18659         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18660         local cksum=`md5sum $DIR/$tfile`
18661         local fsz=`stat -c %s $DIR/$tfile`
18662         cancel_lru_locks mdc
18663         cancel_lru_locks osc
18664
18665         # do not return layout in getattr intent
18666 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18667         $LCTL set_param fail_loc=0x171
18668
18669         # it will refresh layout after the file is opened but before read issues
18670         echo checksum is "$cksum"
18671         echo "$cksum" |md5sum -c --quiet || error "file differs"
18672
18673         rm -rf $DIR/$tfile
18674 }
18675 run_test 207b "can refresh layout at open"
18676
18677 test_208() {
18678         # FIXME: in this test suite, only RD lease is used. This is okay
18679         # for now as only exclusive open is supported. After generic lease
18680         # is done, this test suite should be revised. - Jinshan
18681
18682         remote_mds_nodsh && skip "remote MDS with nodsh"
18683         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18684                 skip "Need MDS version at least 2.4.52"
18685
18686         echo "==== test 1: verify get lease work"
18687         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18688
18689         echo "==== test 2: verify lease can be broken by upcoming open"
18690         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18691         local PID=$!
18692         sleep 2
18693
18694         $MULTIOP $DIR/$tfile oO_RDWR:c
18695         kill -USR1 $PID && wait $PID || error "break lease error"
18696
18697         echo "==== test 3: verify lease can't be granted if an open already exists"
18698         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18699         local PID=$!
18700         sleep 2
18701
18702         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18703         kill -USR1 $PID && wait $PID || error "open file error"
18704
18705         echo "==== test 4: lease can sustain over recovery"
18706         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18707         PID=$!
18708         sleep 2
18709
18710         fail mds1
18711
18712         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18713
18714         echo "==== test 5: lease broken can't be regained by replay"
18715         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18716         PID=$!
18717         sleep 2
18718
18719         # open file to break lease and then recovery
18720         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18721         fail mds1
18722
18723         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18724
18725         rm -f $DIR/$tfile
18726 }
18727 run_test 208 "Exclusive open"
18728
18729 test_209() {
18730         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18731                 skip_env "must have disp_stripe"
18732
18733         touch $DIR/$tfile
18734         sync; sleep 5; sync;
18735
18736         echo 3 > /proc/sys/vm/drop_caches
18737         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18738                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18739         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18740
18741         # open/close 500 times
18742         for i in $(seq 500); do
18743                 cat $DIR/$tfile
18744         done
18745
18746         echo 3 > /proc/sys/vm/drop_caches
18747         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18748                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18749         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18750
18751         echo "before: $req_before, after: $req_after"
18752         [ $((req_after - req_before)) -ge 300 ] &&
18753                 error "open/close requests are not freed"
18754         return 0
18755 }
18756 run_test 209 "read-only open/close requests should be freed promptly"
18757
18758 test_210() {
18759         local pid
18760
18761         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18762         pid=$!
18763         sleep 1
18764
18765         $LFS getstripe $DIR/$tfile
18766         kill -USR1 $pid
18767         wait $pid || error "multiop failed"
18768
18769         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18770         pid=$!
18771         sleep 1
18772
18773         $LFS getstripe $DIR/$tfile
18774         kill -USR1 $pid
18775         wait $pid || error "multiop failed"
18776 }
18777 run_test 210 "lfs getstripe does not break leases"
18778
18779 test_212() {
18780         size=`date +%s`
18781         size=$((size % 8192 + 1))
18782         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18783         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18784         rm -f $DIR/f212 $DIR/f212.xyz
18785 }
18786 run_test 212 "Sendfile test ============================================"
18787
18788 test_213() {
18789         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18790         cancel_lru_locks osc
18791         lctl set_param fail_loc=0x8000040f
18792         # generate a read lock
18793         cat $DIR/$tfile > /dev/null
18794         # write to the file, it will try to cancel the above read lock.
18795         cat /etc/hosts >> $DIR/$tfile
18796 }
18797 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18798
18799 test_214() { # for bug 20133
18800         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18801         for (( i=0; i < 340; i++ )) ; do
18802                 touch $DIR/$tdir/d214c/a$i
18803         done
18804
18805         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18806         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18807         ls $DIR/d214c || error "ls $DIR/d214c failed"
18808         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18809         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18810 }
18811 run_test 214 "hash-indexed directory test - bug 20133"
18812
18813 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18814 create_lnet_proc_files() {
18815         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18816 }
18817
18818 # counterpart of create_lnet_proc_files
18819 remove_lnet_proc_files() {
18820         rm -f $TMP/lnet_$1.sys
18821 }
18822
18823 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18824 # 3rd arg as regexp for body
18825 check_lnet_proc_stats() {
18826         local l=$(cat "$TMP/lnet_$1" |wc -l)
18827         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18828
18829         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18830 }
18831
18832 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18833 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18834 # optional and can be regexp for 2nd line (lnet.routes case)
18835 check_lnet_proc_entry() {
18836         local blp=2          # blp stands for 'position of 1st line of body'
18837         [ -z "$5" ] || blp=3 # lnet.routes case
18838
18839         local l=$(cat "$TMP/lnet_$1" |wc -l)
18840         # subtracting one from $blp because the body can be empty
18841         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18842
18843         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18844                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18845
18846         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18847                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18848
18849         # bail out if any unexpected line happened
18850         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18851         [ "$?" != 0 ] || error "$2 misformatted"
18852 }
18853
18854 test_215() { # for bugs 18102, 21079, 21517
18855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18856
18857         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18858         local P='[1-9][0-9]*'           # positive numeric
18859         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18860         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18861         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18862         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18863
18864         local L1 # regexp for 1st line
18865         local L2 # regexp for 2nd line (optional)
18866         local BR # regexp for the rest (body)
18867
18868         # lnet.stats should look as 11 space-separated non-negative numerics
18869         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18870         create_lnet_proc_files "stats"
18871         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18872         remove_lnet_proc_files "stats"
18873
18874         # lnet.routes should look like this:
18875         # Routing disabled/enabled
18876         # net hops priority state router
18877         # where net is a string like tcp0, hops > 0, priority >= 0,
18878         # state is up/down,
18879         # router is a string like 192.168.1.1@tcp2
18880         L1="^Routing (disabled|enabled)$"
18881         L2="^net +hops +priority +state +router$"
18882         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18883         create_lnet_proc_files "routes"
18884         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18885         remove_lnet_proc_files "routes"
18886
18887         # lnet.routers should look like this:
18888         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18889         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18890         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18891         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18892         L1="^ref +rtr_ref +alive +router$"
18893         BR="^$P +$P +(up|down) +$NID$"
18894         create_lnet_proc_files "routers"
18895         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18896         remove_lnet_proc_files "routers"
18897
18898         # lnet.peers should look like this:
18899         # nid refs state last max rtr min tx min queue
18900         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18901         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18902         # numeric (0 or >0 or <0), queue >= 0.
18903         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18904         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18905         create_lnet_proc_files "peers"
18906         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18907         remove_lnet_proc_files "peers"
18908
18909         # lnet.buffers  should look like this:
18910         # pages count credits min
18911         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18912         L1="^pages +count +credits +min$"
18913         BR="^ +$N +$N +$I +$I$"
18914         create_lnet_proc_files "buffers"
18915         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18916         remove_lnet_proc_files "buffers"
18917
18918         # lnet.nis should look like this:
18919         # nid status alive refs peer rtr max tx min
18920         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18921         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18922         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18923         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18924         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18925         create_lnet_proc_files "nis"
18926         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18927         remove_lnet_proc_files "nis"
18928
18929         # can we successfully write to lnet.stats?
18930         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18931 }
18932 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18933
18934 test_216() { # bug 20317
18935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18936         remote_ost_nodsh && skip "remote OST with nodsh"
18937
18938         local node
18939         local facets=$(get_facets OST)
18940         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18941
18942         save_lustre_params client "osc.*.contention_seconds" > $p
18943         save_lustre_params $facets \
18944                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18945         save_lustre_params $facets \
18946                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18947         save_lustre_params $facets \
18948                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18949         clear_stats osc.*.osc_stats
18950
18951         # agressive lockless i/o settings
18952         do_nodes $(comma_list $(osts_nodes)) \
18953                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18954                         ldlm.namespaces.filter-*.contended_locks=0 \
18955                         ldlm.namespaces.filter-*.contention_seconds=60"
18956         lctl set_param -n osc.*.contention_seconds=60
18957
18958         $DIRECTIO write $DIR/$tfile 0 10 4096
18959         $CHECKSTAT -s 40960 $DIR/$tfile
18960
18961         # disable lockless i/o
18962         do_nodes $(comma_list $(osts_nodes)) \
18963                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18964                         ldlm.namespaces.filter-*.contended_locks=32 \
18965                         ldlm.namespaces.filter-*.contention_seconds=0"
18966         lctl set_param -n osc.*.contention_seconds=0
18967         clear_stats osc.*.osc_stats
18968
18969         dd if=/dev/zero of=$DIR/$tfile count=0
18970         $CHECKSTAT -s 0 $DIR/$tfile
18971
18972         restore_lustre_params <$p
18973         rm -f $p
18974         rm $DIR/$tfile
18975 }
18976 run_test 216 "check lockless direct write updates file size and kms correctly"
18977
18978 test_217() { # bug 22430
18979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18980
18981         local node
18982         local nid
18983
18984         for node in $(nodes_list); do
18985                 nid=$(host_nids_address $node $NETTYPE)
18986                 if [[ $nid = *-* ]] ; then
18987                         echo "lctl ping $(h2nettype $nid)"
18988                         lctl ping $(h2nettype $nid)
18989                 else
18990                         echo "skipping $node (no hyphen detected)"
18991                 fi
18992         done
18993 }
18994 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18995
18996 test_218() {
18997        # do directio so as not to populate the page cache
18998        log "creating a 10 Mb file"
18999        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19000        log "starting reads"
19001        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19002        log "truncating the file"
19003        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19004        log "killing dd"
19005        kill %+ || true # reads might have finished
19006        echo "wait until dd is finished"
19007        wait
19008        log "removing the temporary file"
19009        rm -rf $DIR/$tfile || error "tmp file removal failed"
19010 }
19011 run_test 218 "parallel read and truncate should not deadlock"
19012
19013 test_219() {
19014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19015
19016         # write one partial page
19017         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19018         # set no grant so vvp_io_commit_write will do sync write
19019         $LCTL set_param fail_loc=0x411
19020         # write a full page at the end of file
19021         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19022
19023         $LCTL set_param fail_loc=0
19024         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19025         $LCTL set_param fail_loc=0x411
19026         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19027
19028         # LU-4201
19029         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19030         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19031 }
19032 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19033
19034 test_220() { #LU-325
19035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19036         remote_ost_nodsh && skip "remote OST with nodsh"
19037         remote_mds_nodsh && skip "remote MDS with nodsh"
19038         remote_mgs_nodsh && skip "remote MGS with nodsh"
19039
19040         local OSTIDX=0
19041
19042         # create on MDT0000 so the last_id and next_id are correct
19043         mkdir_on_mdt0 $DIR/$tdir
19044         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19045         OST=${OST%_UUID}
19046
19047         # on the mdt's osc
19048         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19049         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19050                         osp.$mdtosc_proc1.prealloc_last_id)
19051         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19052                         osp.$mdtosc_proc1.prealloc_next_id)
19053
19054         $LFS df -i
19055
19056         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19057         #define OBD_FAIL_OST_ENOINO              0x229
19058         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19059         create_pool $FSNAME.$TESTNAME || return 1
19060         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19061
19062         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19063
19064         MDSOBJS=$((last_id - next_id))
19065         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19066
19067         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19068         echo "OST still has $count kbytes free"
19069
19070         echo "create $MDSOBJS files @next_id..."
19071         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19072
19073         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19074                         osp.$mdtosc_proc1.prealloc_last_id)
19075         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19076                         osp.$mdtosc_proc1.prealloc_next_id)
19077
19078         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19079         $LFS df -i
19080
19081         echo "cleanup..."
19082
19083         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19084         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19085
19086         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19087                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19088         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19089                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19090         echo "unlink $MDSOBJS files @$next_id..."
19091         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19092 }
19093 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19094
19095 test_221() {
19096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19097
19098         dd if=`which date` of=$MOUNT/date oflag=sync
19099         chmod +x $MOUNT/date
19100
19101         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19102         $LCTL set_param fail_loc=0x80001401
19103
19104         $MOUNT/date > /dev/null
19105         rm -f $MOUNT/date
19106 }
19107 run_test 221 "make sure fault and truncate race to not cause OOM"
19108
19109 test_222a () {
19110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19111
19112         rm -rf $DIR/$tdir
19113         test_mkdir $DIR/$tdir
19114         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19115         createmany -o $DIR/$tdir/$tfile 10
19116         cancel_lru_locks mdc
19117         cancel_lru_locks osc
19118         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19119         $LCTL set_param fail_loc=0x31a
19120         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19121         $LCTL set_param fail_loc=0
19122         rm -r $DIR/$tdir
19123 }
19124 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19125
19126 test_222b () {
19127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19128
19129         rm -rf $DIR/$tdir
19130         test_mkdir $DIR/$tdir
19131         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19132         createmany -o $DIR/$tdir/$tfile 10
19133         cancel_lru_locks mdc
19134         cancel_lru_locks osc
19135         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19136         $LCTL set_param fail_loc=0x31a
19137         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19138         $LCTL set_param fail_loc=0
19139 }
19140 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19141
19142 test_223 () {
19143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19144
19145         rm -rf $DIR/$tdir
19146         test_mkdir $DIR/$tdir
19147         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19148         createmany -o $DIR/$tdir/$tfile 10
19149         cancel_lru_locks mdc
19150         cancel_lru_locks osc
19151         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19152         $LCTL set_param fail_loc=0x31b
19153         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19154         $LCTL set_param fail_loc=0
19155         rm -r $DIR/$tdir
19156 }
19157 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19158
19159 test_224a() { # LU-1039, MRP-303
19160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19161         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19162         $LCTL set_param fail_loc=0x508
19163         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19164         $LCTL set_param fail_loc=0
19165         df $DIR
19166 }
19167 run_test 224a "Don't panic on bulk IO failure"
19168
19169 test_224bd_sub() { # LU-1039, MRP-303
19170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19171         local timeout=$1
19172
19173         shift
19174         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19175
19176         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19177
19178         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19179         cancel_lru_locks osc
19180         set_checksums 0
19181         stack_trap "set_checksums $ORIG_CSUM" EXIT
19182         local at_max_saved=0
19183
19184         # adaptive timeouts may prevent seeing the issue
19185         if at_is_enabled; then
19186                 at_max_saved=$(at_max_get mds)
19187                 at_max_set 0 mds client
19188                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19189         fi
19190
19191         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19192         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19193         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19194
19195         do_facet ost1 $LCTL set_param fail_loc=0
19196         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19197         df $DIR
19198 }
19199
19200 test_224b() {
19201         test_224bd_sub 3 error "dd failed"
19202 }
19203 run_test 224b "Don't panic on bulk IO failure"
19204
19205 test_224c() { # LU-6441
19206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19207         remote_mds_nodsh && skip "remote MDS with nodsh"
19208
19209         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19210         save_writethrough $p
19211         set_cache writethrough on
19212
19213         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19214         local at_max=$($LCTL get_param -n at_max)
19215         local timeout=$($LCTL get_param -n timeout)
19216         local test_at="at_max"
19217         local param_at="$FSNAME.sys.at_max"
19218         local test_timeout="timeout"
19219         local param_timeout="$FSNAME.sys.timeout"
19220
19221         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19222
19223         set_persistent_param_and_check client "$test_at" "$param_at" 0
19224         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19225
19226         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19227         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19228         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19229         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19230         sync
19231         do_facet ost1 "$LCTL set_param fail_loc=0"
19232
19233         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19234         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19235                 $timeout
19236
19237         $LCTL set_param -n $pages_per_rpc
19238         restore_lustre_params < $p
19239         rm -f $p
19240 }
19241 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19242
19243 test_224d() { # LU-11169
19244         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19245 }
19246 run_test 224d "Don't corrupt data on bulk IO timeout"
19247
19248 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19249 test_225a () {
19250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19251         if [ -z ${MDSSURVEY} ]; then
19252                 skip_env "mds-survey not found"
19253         fi
19254         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19255                 skip "Need MDS version at least 2.2.51"
19256
19257         local mds=$(facet_host $SINGLEMDS)
19258         local target=$(do_nodes $mds 'lctl dl' |
19259                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19260
19261         local cmd1="file_count=1000 thrhi=4"
19262         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19263         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19264         local cmd="$cmd1 $cmd2 $cmd3"
19265
19266         rm -f ${TMP}/mds_survey*
19267         echo + $cmd
19268         eval $cmd || error "mds-survey with zero-stripe failed"
19269         cat ${TMP}/mds_survey*
19270         rm -f ${TMP}/mds_survey*
19271 }
19272 run_test 225a "Metadata survey sanity with zero-stripe"
19273
19274 test_225b () {
19275         if [ -z ${MDSSURVEY} ]; then
19276                 skip_env "mds-survey not found"
19277         fi
19278         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19279                 skip "Need MDS version at least 2.2.51"
19280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19281         remote_mds_nodsh && skip "remote MDS with nodsh"
19282         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19283                 skip_env "Need to mount OST to test"
19284         fi
19285
19286         local mds=$(facet_host $SINGLEMDS)
19287         local target=$(do_nodes $mds 'lctl dl' |
19288                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19289
19290         local cmd1="file_count=1000 thrhi=4"
19291         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19292         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19293         local cmd="$cmd1 $cmd2 $cmd3"
19294
19295         rm -f ${TMP}/mds_survey*
19296         echo + $cmd
19297         eval $cmd || error "mds-survey with stripe_count failed"
19298         cat ${TMP}/mds_survey*
19299         rm -f ${TMP}/mds_survey*
19300 }
19301 run_test 225b "Metadata survey sanity with stripe_count = 1"
19302
19303 mcreate_path2fid () {
19304         local mode=$1
19305         local major=$2
19306         local minor=$3
19307         local name=$4
19308         local desc=$5
19309         local path=$DIR/$tdir/$name
19310         local fid
19311         local rc
19312         local fid_path
19313
19314         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19315                 error "cannot create $desc"
19316
19317         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19318         rc=$?
19319         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19320
19321         fid_path=$($LFS fid2path $MOUNT $fid)
19322         rc=$?
19323         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19324
19325         [ "$path" == "$fid_path" ] ||
19326                 error "fid2path returned $fid_path, expected $path"
19327
19328         echo "pass with $path and $fid"
19329 }
19330
19331 test_226a () {
19332         rm -rf $DIR/$tdir
19333         mkdir -p $DIR/$tdir
19334
19335         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19336         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19337         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19338         mcreate_path2fid 0040666 0 0 dir "directory"
19339         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19340         mcreate_path2fid 0100666 0 0 file "regular file"
19341         mcreate_path2fid 0120666 0 0 link "symbolic link"
19342         mcreate_path2fid 0140666 0 0 sock "socket"
19343 }
19344 run_test 226a "call path2fid and fid2path on files of all type"
19345
19346 test_226b () {
19347         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19348
19349         local MDTIDX=1
19350
19351         rm -rf $DIR/$tdir
19352         mkdir -p $DIR/$tdir
19353         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19354                 error "create remote directory failed"
19355         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19356         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19357                                 "character special file (null)"
19358         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19359                                 "character special file (no device)"
19360         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19361         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19362                                 "block special file (loop)"
19363         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19364         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19365         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19366 }
19367 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19368
19369 test_226c () {
19370         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19371         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19372                 skip "Need MDS version at least 2.13.55"
19373
19374         local submnt=/mnt/submnt
19375         local srcfile=/etc/passwd
19376         local dstfile=$submnt/passwd
19377         local path
19378         local fid
19379
19380         rm -rf $DIR/$tdir
19381         rm -rf $submnt
19382         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19383                 error "create remote directory failed"
19384         mkdir -p $submnt || error "create $submnt failed"
19385         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19386                 error "mount $submnt failed"
19387         stack_trap "umount $submnt" EXIT
19388
19389         cp $srcfile $dstfile
19390         fid=$($LFS path2fid $dstfile)
19391         path=$($LFS fid2path $submnt "$fid")
19392         [ "$path" = "$dstfile" ] ||
19393                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19394 }
19395 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19396
19397 # LU-1299 Executing or running ldd on a truncated executable does not
19398 # cause an out-of-memory condition.
19399 test_227() {
19400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19401         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19402
19403         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19404         chmod +x $MOUNT/date
19405
19406         $MOUNT/date > /dev/null
19407         ldd $MOUNT/date > /dev/null
19408         rm -f $MOUNT/date
19409 }
19410 run_test 227 "running truncated executable does not cause OOM"
19411
19412 # LU-1512 try to reuse idle OI blocks
19413 test_228a() {
19414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19415         remote_mds_nodsh && skip "remote MDS with nodsh"
19416         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19417
19418         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19419         local myDIR=$DIR/$tdir
19420
19421         mkdir -p $myDIR
19422         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19423         $LCTL set_param fail_loc=0x80001002
19424         createmany -o $myDIR/t- 10000
19425         $LCTL set_param fail_loc=0
19426         # The guard is current the largest FID holder
19427         touch $myDIR/guard
19428         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19429                     tr -d '[')
19430         local IDX=$(($SEQ % 64))
19431
19432         do_facet $SINGLEMDS sync
19433         # Make sure journal flushed.
19434         sleep 6
19435         local blk1=$(do_facet $SINGLEMDS \
19436                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19437                      grep Blockcount | awk '{print $4}')
19438
19439         # Remove old files, some OI blocks will become idle.
19440         unlinkmany $myDIR/t- 10000
19441         # Create new files, idle OI blocks should be reused.
19442         createmany -o $myDIR/t- 2000
19443         do_facet $SINGLEMDS sync
19444         # Make sure journal flushed.
19445         sleep 6
19446         local blk2=$(do_facet $SINGLEMDS \
19447                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19448                      grep Blockcount | awk '{print $4}')
19449
19450         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19451 }
19452 run_test 228a "try to reuse idle OI blocks"
19453
19454 test_228b() {
19455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19456         remote_mds_nodsh && skip "remote MDS with nodsh"
19457         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19458
19459         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19460         local myDIR=$DIR/$tdir
19461
19462         mkdir -p $myDIR
19463         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19464         $LCTL set_param fail_loc=0x80001002
19465         createmany -o $myDIR/t- 10000
19466         $LCTL set_param fail_loc=0
19467         # The guard is current the largest FID holder
19468         touch $myDIR/guard
19469         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19470                     tr -d '[')
19471         local IDX=$(($SEQ % 64))
19472
19473         do_facet $SINGLEMDS sync
19474         # Make sure journal flushed.
19475         sleep 6
19476         local blk1=$(do_facet $SINGLEMDS \
19477                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19478                      grep Blockcount | awk '{print $4}')
19479
19480         # Remove old files, some OI blocks will become idle.
19481         unlinkmany $myDIR/t- 10000
19482
19483         # stop the MDT
19484         stop $SINGLEMDS || error "Fail to stop MDT."
19485         # remount the MDT
19486         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19487                 error "Fail to start MDT."
19488
19489         df $MOUNT || error "Fail to df."
19490         # Create new files, idle OI blocks should be reused.
19491         createmany -o $myDIR/t- 2000
19492         do_facet $SINGLEMDS sync
19493         # Make sure journal flushed.
19494         sleep 6
19495         local blk2=$(do_facet $SINGLEMDS \
19496                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19497                      grep Blockcount | awk '{print $4}')
19498
19499         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19500 }
19501 run_test 228b "idle OI blocks can be reused after MDT restart"
19502
19503 #LU-1881
19504 test_228c() {
19505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19506         remote_mds_nodsh && skip "remote MDS with nodsh"
19507         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19508
19509         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19510         local myDIR=$DIR/$tdir
19511
19512         mkdir -p $myDIR
19513         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19514         $LCTL set_param fail_loc=0x80001002
19515         # 20000 files can guarantee there are index nodes in the OI file
19516         createmany -o $myDIR/t- 20000
19517         $LCTL set_param fail_loc=0
19518         # The guard is current the largest FID holder
19519         touch $myDIR/guard
19520         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19521                     tr -d '[')
19522         local IDX=$(($SEQ % 64))
19523
19524         do_facet $SINGLEMDS sync
19525         # Make sure journal flushed.
19526         sleep 6
19527         local blk1=$(do_facet $SINGLEMDS \
19528                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19529                      grep Blockcount | awk '{print $4}')
19530
19531         # Remove old files, some OI blocks will become idle.
19532         unlinkmany $myDIR/t- 20000
19533         rm -f $myDIR/guard
19534         # The OI file should become empty now
19535
19536         # Create new files, idle OI blocks should be reused.
19537         createmany -o $myDIR/t- 2000
19538         do_facet $SINGLEMDS sync
19539         # Make sure journal flushed.
19540         sleep 6
19541         local blk2=$(do_facet $SINGLEMDS \
19542                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19543                      grep Blockcount | awk '{print $4}')
19544
19545         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19546 }
19547 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19548
19549 test_229() { # LU-2482, LU-3448
19550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19551         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19552         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19553                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19554
19555         rm -f $DIR/$tfile
19556
19557         # Create a file with a released layout and stripe count 2.
19558         $MULTIOP $DIR/$tfile H2c ||
19559                 error "failed to create file with released layout"
19560
19561         $LFS getstripe -v $DIR/$tfile
19562
19563         local pattern=$($LFS getstripe -L $DIR/$tfile)
19564         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19565
19566         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19567                 error "getstripe"
19568         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19569         stat $DIR/$tfile || error "failed to stat released file"
19570
19571         chown $RUNAS_ID $DIR/$tfile ||
19572                 error "chown $RUNAS_ID $DIR/$tfile failed"
19573
19574         chgrp $RUNAS_ID $DIR/$tfile ||
19575                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19576
19577         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19578         rm $DIR/$tfile || error "failed to remove released file"
19579 }
19580 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19581
19582 test_230a() {
19583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19584         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19585         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19586                 skip "Need MDS version at least 2.11.52"
19587
19588         local MDTIDX=1
19589
19590         test_mkdir $DIR/$tdir
19591         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19592         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19593         [ $mdt_idx -ne 0 ] &&
19594                 error "create local directory on wrong MDT $mdt_idx"
19595
19596         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19597                         error "create remote directory failed"
19598         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19599         [ $mdt_idx -ne $MDTIDX ] &&
19600                 error "create remote directory on wrong MDT $mdt_idx"
19601
19602         createmany -o $DIR/$tdir/test_230/t- 10 ||
19603                 error "create files on remote directory failed"
19604         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19605         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19606         rm -r $DIR/$tdir || error "unlink remote directory failed"
19607 }
19608 run_test 230a "Create remote directory and files under the remote directory"
19609
19610 test_230b() {
19611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19612         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19613         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19614                 skip "Need MDS version at least 2.11.52"
19615
19616         local MDTIDX=1
19617         local mdt_index
19618         local i
19619         local file
19620         local pid
19621         local stripe_count
19622         local migrate_dir=$DIR/$tdir/migrate_dir
19623         local other_dir=$DIR/$tdir/other_dir
19624
19625         test_mkdir $DIR/$tdir
19626         test_mkdir -i0 -c1 $migrate_dir
19627         test_mkdir -i0 -c1 $other_dir
19628         for ((i=0; i<10; i++)); do
19629                 mkdir -p $migrate_dir/dir_${i}
19630                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19631                         error "create files under remote dir failed $i"
19632         done
19633
19634         cp /etc/passwd $migrate_dir/$tfile
19635         cp /etc/passwd $other_dir/$tfile
19636         chattr +SAD $migrate_dir
19637         chattr +SAD $migrate_dir/$tfile
19638
19639         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19640         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19641         local old_dir_mode=$(stat -c%f $migrate_dir)
19642         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19643
19644         mkdir -p $migrate_dir/dir_default_stripe2
19645         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19646         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19647
19648         mkdir -p $other_dir
19649         ln $migrate_dir/$tfile $other_dir/luna
19650         ln $migrate_dir/$tfile $migrate_dir/sofia
19651         ln $other_dir/$tfile $migrate_dir/david
19652         ln -s $migrate_dir/$tfile $other_dir/zachary
19653         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19654         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19655
19656         local len
19657         local lnktgt
19658
19659         # inline symlink
19660         for len in 58 59 60; do
19661                 lnktgt=$(str_repeat 'l' $len)
19662                 touch $migrate_dir/$lnktgt
19663                 ln -s $lnktgt $migrate_dir/${len}char_ln
19664         done
19665
19666         # PATH_MAX
19667         for len in 4094 4095; do
19668                 lnktgt=$(str_repeat 'l' $len)
19669                 ln -s $lnktgt $migrate_dir/${len}char_ln
19670         done
19671
19672         # NAME_MAX
19673         for len in 254 255; do
19674                 touch $migrate_dir/$(str_repeat 'l' $len)
19675         done
19676
19677         $LFS migrate -m $MDTIDX $migrate_dir ||
19678                 error "fails on migrating remote dir to MDT1"
19679
19680         echo "migratate to MDT1, then checking.."
19681         for ((i = 0; i < 10; i++)); do
19682                 for file in $(find $migrate_dir/dir_${i}); do
19683                         mdt_index=$($LFS getstripe -m $file)
19684                         # broken symlink getstripe will fail
19685                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19686                                 error "$file is not on MDT${MDTIDX}"
19687                 done
19688         done
19689
19690         # the multiple link file should still in MDT0
19691         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19692         [ $mdt_index == 0 ] ||
19693                 error "$file is not on MDT${MDTIDX}"
19694
19695         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19696         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19697                 error " expect $old_dir_flag get $new_dir_flag"
19698
19699         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19700         [ "$old_file_flag" = "$new_file_flag" ] ||
19701                 error " expect $old_file_flag get $new_file_flag"
19702
19703         local new_dir_mode=$(stat -c%f $migrate_dir)
19704         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19705                 error "expect mode $old_dir_mode get $new_dir_mode"
19706
19707         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19708         [ "$old_file_mode" = "$new_file_mode" ] ||
19709                 error "expect mode $old_file_mode get $new_file_mode"
19710
19711         diff /etc/passwd $migrate_dir/$tfile ||
19712                 error "$tfile different after migration"
19713
19714         diff /etc/passwd $other_dir/luna ||
19715                 error "luna different after migration"
19716
19717         diff /etc/passwd $migrate_dir/sofia ||
19718                 error "sofia different after migration"
19719
19720         diff /etc/passwd $migrate_dir/david ||
19721                 error "david different after migration"
19722
19723         diff /etc/passwd $other_dir/zachary ||
19724                 error "zachary different after migration"
19725
19726         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19727                 error "${tfile}_ln different after migration"
19728
19729         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19730                 error "${tfile}_ln_other different after migration"
19731
19732         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19733         [ $stripe_count = 2 ] ||
19734                 error "dir strpe_count $d != 2 after migration."
19735
19736         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19737         [ $stripe_count = 2 ] ||
19738                 error "file strpe_count $d != 2 after migration."
19739
19740         #migrate back to MDT0
19741         MDTIDX=0
19742
19743         $LFS migrate -m $MDTIDX $migrate_dir ||
19744                 error "fails on migrating remote dir to MDT0"
19745
19746         echo "migrate back to MDT0, checking.."
19747         for file in $(find $migrate_dir); do
19748                 mdt_index=$($LFS getstripe -m $file)
19749                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19750                         error "$file is not on MDT${MDTIDX}"
19751         done
19752
19753         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19754         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19755                 error " expect $old_dir_flag get $new_dir_flag"
19756
19757         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19758         [ "$old_file_flag" = "$new_file_flag" ] ||
19759                 error " expect $old_file_flag get $new_file_flag"
19760
19761         local new_dir_mode=$(stat -c%f $migrate_dir)
19762         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19763                 error "expect mode $old_dir_mode get $new_dir_mode"
19764
19765         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19766         [ "$old_file_mode" = "$new_file_mode" ] ||
19767                 error "expect mode $old_file_mode get $new_file_mode"
19768
19769         diff /etc/passwd ${migrate_dir}/$tfile ||
19770                 error "$tfile different after migration"
19771
19772         diff /etc/passwd ${other_dir}/luna ||
19773                 error "luna different after migration"
19774
19775         diff /etc/passwd ${migrate_dir}/sofia ||
19776                 error "sofia different after migration"
19777
19778         diff /etc/passwd ${other_dir}/zachary ||
19779                 error "zachary different after migration"
19780
19781         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19782                 error "${tfile}_ln different after migration"
19783
19784         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19785                 error "${tfile}_ln_other different after migration"
19786
19787         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19788         [ $stripe_count = 2 ] ||
19789                 error "dir strpe_count $d != 2 after migration."
19790
19791         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19792         [ $stripe_count = 2 ] ||
19793                 error "file strpe_count $d != 2 after migration."
19794
19795         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19796 }
19797 run_test 230b "migrate directory"
19798
19799 test_230c() {
19800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19801         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19802         remote_mds_nodsh && skip "remote MDS with nodsh"
19803         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19804                 skip "Need MDS version at least 2.11.52"
19805
19806         local MDTIDX=1
19807         local total=3
19808         local mdt_index
19809         local file
19810         local migrate_dir=$DIR/$tdir/migrate_dir
19811
19812         #If migrating directory fails in the middle, all entries of
19813         #the directory is still accessiable.
19814         test_mkdir $DIR/$tdir
19815         test_mkdir -i0 -c1 $migrate_dir
19816         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19817         stat $migrate_dir
19818         createmany -o $migrate_dir/f $total ||
19819                 error "create files under ${migrate_dir} failed"
19820
19821         # fail after migrating top dir, and this will fail only once, so the
19822         # first sub file migration will fail (currently f3), others succeed.
19823         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19824         do_facet mds1 lctl set_param fail_loc=0x1801
19825         local t=$(ls $migrate_dir | wc -l)
19826         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19827                 error "migrate should fail"
19828         local u=$(ls $migrate_dir | wc -l)
19829         [ "$u" == "$t" ] || error "$u != $t during migration"
19830
19831         # add new dir/file should succeed
19832         mkdir $migrate_dir/dir ||
19833                 error "mkdir failed under migrating directory"
19834         touch $migrate_dir/file ||
19835                 error "create file failed under migrating directory"
19836
19837         # add file with existing name should fail
19838         for file in $migrate_dir/f*; do
19839                 stat $file > /dev/null || error "stat $file failed"
19840                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19841                         error "open(O_CREAT|O_EXCL) $file should fail"
19842                 $MULTIOP $file m && error "create $file should fail"
19843                 touch $DIR/$tdir/remote_dir/$tfile ||
19844                         error "touch $tfile failed"
19845                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19846                         error "link $file should fail"
19847                 mdt_index=$($LFS getstripe -m $file)
19848                 if [ $mdt_index == 0 ]; then
19849                         # file failed to migrate is not allowed to rename to
19850                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19851                                 error "rename to $file should fail"
19852                 else
19853                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19854                                 error "rename to $file failed"
19855                 fi
19856                 echo hello >> $file || error "write $file failed"
19857         done
19858
19859         # resume migration with different options should fail
19860         $LFS migrate -m 0 $migrate_dir &&
19861                 error "migrate -m 0 $migrate_dir should fail"
19862
19863         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19864                 error "migrate -c 2 $migrate_dir should fail"
19865
19866         # resume migration should succeed
19867         $LFS migrate -m $MDTIDX $migrate_dir ||
19868                 error "migrate $migrate_dir failed"
19869
19870         echo "Finish migration, then checking.."
19871         for file in $(find $migrate_dir); do
19872                 mdt_index=$($LFS getstripe -m $file)
19873                 [ $mdt_index == $MDTIDX ] ||
19874                         error "$file is not on MDT${MDTIDX}"
19875         done
19876
19877         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19878 }
19879 run_test 230c "check directory accessiblity if migration failed"
19880
19881 test_230d() {
19882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19883         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19884         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19885                 skip "Need MDS version at least 2.11.52"
19886         # LU-11235
19887         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19888
19889         local migrate_dir=$DIR/$tdir/migrate_dir
19890         local old_index
19891         local new_index
19892         local old_count
19893         local new_count
19894         local new_hash
19895         local mdt_index
19896         local i
19897         local j
19898
19899         old_index=$((RANDOM % MDSCOUNT))
19900         old_count=$((MDSCOUNT - old_index))
19901         new_index=$((RANDOM % MDSCOUNT))
19902         new_count=$((MDSCOUNT - new_index))
19903         new_hash=1 # for all_char
19904
19905         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19906         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19907
19908         test_mkdir $DIR/$tdir
19909         test_mkdir -i $old_index -c $old_count $migrate_dir
19910
19911         for ((i=0; i<100; i++)); do
19912                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19913                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19914                         error "create files under remote dir failed $i"
19915         done
19916
19917         echo -n "Migrate from MDT$old_index "
19918         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19919         echo -n "to MDT$new_index"
19920         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19921         echo
19922
19923         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19924         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19925                 error "migrate remote dir error"
19926
19927         echo "Finish migration, then checking.."
19928         for file in $(find $migrate_dir -maxdepth 1); do
19929                 mdt_index=$($LFS getstripe -m $file)
19930                 if [ $mdt_index -lt $new_index ] ||
19931                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19932                         error "$file is on MDT$mdt_index"
19933                 fi
19934         done
19935
19936         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19937 }
19938 run_test 230d "check migrate big directory"
19939
19940 test_230e() {
19941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19942         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19943         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19944                 skip "Need MDS version at least 2.11.52"
19945
19946         local i
19947         local j
19948         local a_fid
19949         local b_fid
19950
19951         mkdir_on_mdt0 $DIR/$tdir
19952         mkdir $DIR/$tdir/migrate_dir
19953         mkdir $DIR/$tdir/other_dir
19954         touch $DIR/$tdir/migrate_dir/a
19955         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19956         ls $DIR/$tdir/other_dir
19957
19958         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19959                 error "migrate dir fails"
19960
19961         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19962         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19963
19964         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19965         [ $mdt_index == 0 ] || error "a is not on MDT0"
19966
19967         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19968                 error "migrate dir fails"
19969
19970         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19971         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19972
19973         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19974         [ $mdt_index == 1 ] || error "a is not on MDT1"
19975
19976         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19977         [ $mdt_index == 1 ] || error "b is not on MDT1"
19978
19979         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19980         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19981
19982         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19983
19984         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19985 }
19986 run_test 230e "migrate mulitple local link files"
19987
19988 test_230f() {
19989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19990         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19991         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19992                 skip "Need MDS version at least 2.11.52"
19993
19994         local a_fid
19995         local ln_fid
19996
19997         mkdir -p $DIR/$tdir
19998         mkdir $DIR/$tdir/migrate_dir
19999         $LFS mkdir -i1 $DIR/$tdir/other_dir
20000         touch $DIR/$tdir/migrate_dir/a
20001         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20002         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20003         ls $DIR/$tdir/other_dir
20004
20005         # a should be migrated to MDT1, since no other links on MDT0
20006         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20007                 error "#1 migrate dir fails"
20008         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20009         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20010         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20011         [ $mdt_index == 1 ] || error "a is not on MDT1"
20012
20013         # a should stay on MDT1, because it is a mulitple link file
20014         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20015                 error "#2 migrate dir fails"
20016         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20017         [ $mdt_index == 1 ] || error "a is not on MDT1"
20018
20019         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20020                 error "#3 migrate dir fails"
20021
20022         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20023         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20024         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20025
20026         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20027         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20028
20029         # a should be migrated to MDT0, since no other links on MDT1
20030         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20031                 error "#4 migrate dir fails"
20032         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20033         [ $mdt_index == 0 ] || error "a is not on MDT0"
20034
20035         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20036 }
20037 run_test 230f "migrate mulitple remote link files"
20038
20039 test_230g() {
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         mkdir -p $DIR/$tdir/migrate_dir
20046
20047         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20048                 error "migrating dir to non-exist MDT succeeds"
20049         true
20050 }
20051 run_test 230g "migrate dir to non-exist MDT"
20052
20053 test_230h() {
20054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20055         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20056         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20057                 skip "Need MDS version at least 2.11.52"
20058
20059         local mdt_index
20060
20061         mkdir -p $DIR/$tdir/migrate_dir
20062
20063         $LFS migrate -m1 $DIR &&
20064                 error "migrating mountpoint1 should fail"
20065
20066         $LFS migrate -m1 $DIR/$tdir/.. &&
20067                 error "migrating mountpoint2 should fail"
20068
20069         # same as mv
20070         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20071                 error "migrating $tdir/migrate_dir/.. should fail"
20072
20073         true
20074 }
20075 run_test 230h "migrate .. and root"
20076
20077 test_230i() {
20078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20079         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20080         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20081                 skip "Need MDS version at least 2.11.52"
20082
20083         mkdir -p $DIR/$tdir/migrate_dir
20084
20085         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20086                 error "migration fails with a tailing slash"
20087
20088         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20089                 error "migration fails with two tailing slashes"
20090 }
20091 run_test 230i "lfs migrate -m tolerates trailing slashes"
20092
20093 test_230j() {
20094         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20095         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20096                 skip "Need MDS version at least 2.11.52"
20097
20098         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20099         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20100                 error "create $tfile failed"
20101         cat /etc/passwd > $DIR/$tdir/$tfile
20102
20103         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20104
20105         cmp /etc/passwd $DIR/$tdir/$tfile ||
20106                 error "DoM file mismatch after migration"
20107 }
20108 run_test 230j "DoM file data not changed after dir migration"
20109
20110 test_230k() {
20111         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20112         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20113                 skip "Need MDS version at least 2.11.56"
20114
20115         local total=20
20116         local files_on_starting_mdt=0
20117
20118         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20119         $LFS getdirstripe $DIR/$tdir
20120         for i in $(seq $total); do
20121                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20122                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20123                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20124         done
20125
20126         echo "$files_on_starting_mdt files on MDT0"
20127
20128         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 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 migration"
20135                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20136                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20137         done
20138
20139         echo "$files_on_starting_mdt files on MDT1 after migration"
20140         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20141
20142         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20143         $LFS getdirstripe $DIR/$tdir
20144
20145         files_on_starting_mdt=0
20146         for i in $(seq $total); do
20147                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20148                         error "file $tfile.$i mismatch after 2nd migration"
20149                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20150                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20151         done
20152
20153         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20154         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20155
20156         true
20157 }
20158 run_test 230k "file data not changed after dir migration"
20159
20160 test_230l() {
20161         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20162         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20163                 skip "Need MDS version at least 2.11.56"
20164
20165         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20166         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20167                 error "create files under remote dir failed $i"
20168         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20169 }
20170 run_test 230l "readdir between MDTs won't crash"
20171
20172 test_230m() {
20173         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20174         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20175                 skip "Need MDS version at least 2.11.56"
20176
20177         local MDTIDX=1
20178         local mig_dir=$DIR/$tdir/migrate_dir
20179         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20180         local shortstr="b"
20181         local val
20182
20183         echo "Creating files and dirs with xattrs"
20184         test_mkdir $DIR/$tdir
20185         test_mkdir -i0 -c1 $mig_dir
20186         mkdir $mig_dir/dir
20187         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20188                 error "cannot set xattr attr1 on dir"
20189         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20190                 error "cannot set xattr attr2 on dir"
20191         touch $mig_dir/dir/f0
20192         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20193                 error "cannot set xattr attr1 on file"
20194         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20195                 error "cannot set xattr attr2 on file"
20196         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20197         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20198         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20199         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20200         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20201         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20202         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20203         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20204         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20205
20206         echo "Migrating to MDT1"
20207         $LFS migrate -m $MDTIDX $mig_dir ||
20208                 error "fails on migrating dir to MDT1"
20209
20210         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20211         echo "Checking xattrs"
20212         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20213         [ "$val" = $longstr ] ||
20214                 error "expecting xattr1 $longstr on dir, found $val"
20215         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20216         [ "$val" = $shortstr ] ||
20217                 error "expecting xattr2 $shortstr on dir, found $val"
20218         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20219         [ "$val" = $longstr ] ||
20220                 error "expecting xattr1 $longstr on file, found $val"
20221         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20222         [ "$val" = $shortstr ] ||
20223                 error "expecting xattr2 $shortstr on file, found $val"
20224 }
20225 run_test 230m "xattrs not changed after dir migration"
20226
20227 test_230n() {
20228         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20229         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20230                 skip "Need MDS version at least 2.13.53"
20231
20232         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20233         cat /etc/hosts > $DIR/$tdir/$tfile
20234         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20235         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20236
20237         cmp /etc/hosts $DIR/$tdir/$tfile ||
20238                 error "File data mismatch after migration"
20239 }
20240 run_test 230n "Dir migration with mirrored file"
20241
20242 test_230o() {
20243         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20244         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20245                 skip "Need MDS version at least 2.13.52"
20246
20247         local mdts=$(comma_list $(mdts_nodes))
20248         local timeout=100
20249         local restripe_status
20250         local delta
20251         local i
20252
20253         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20254
20255         # in case "crush" hash type is not set
20256         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20257
20258         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20259                            mdt.*MDT0000.enable_dir_restripe)
20260         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20261         stack_trap "do_nodes $mdts $LCTL set_param \
20262                     mdt.*.enable_dir_restripe=$restripe_status"
20263
20264         mkdir $DIR/$tdir
20265         createmany -m $DIR/$tdir/f 100 ||
20266                 error "create files under remote dir failed $i"
20267         createmany -d $DIR/$tdir/d 100 ||
20268                 error "create dirs under remote dir failed $i"
20269
20270         for i in $(seq 2 $MDSCOUNT); do
20271                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20272                 $LFS setdirstripe -c $i $DIR/$tdir ||
20273                         error "split -c $i $tdir failed"
20274                 wait_update $HOSTNAME \
20275                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20276                         error "dir split not finished"
20277                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20278                         awk '/migrate/ {sum += $2} END { print sum }')
20279                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20280                 # delta is around total_files/stripe_count
20281                 (( $delta < 200 / (i - 1) + 4 )) ||
20282                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20283         done
20284 }
20285 run_test 230o "dir split"
20286
20287 test_230p() {
20288         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20289         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20290                 skip "Need MDS version at least 2.13.52"
20291
20292         local mdts=$(comma_list $(mdts_nodes))
20293         local timeout=100
20294         local restripe_status
20295         local delta
20296         local c
20297
20298         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20299
20300         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20301
20302         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20303                            mdt.*MDT0000.enable_dir_restripe)
20304         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20305         stack_trap "do_nodes $mdts $LCTL set_param \
20306                     mdt.*.enable_dir_restripe=$restripe_status"
20307
20308         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20309         createmany -m $DIR/$tdir/f 100 ||
20310                 error "create files under remote dir failed"
20311         createmany -d $DIR/$tdir/d 100 ||
20312                 error "create dirs under remote dir failed"
20313
20314         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20315                 local mdt_hash="crush"
20316
20317                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20318                 $LFS setdirstripe -c $c $DIR/$tdir ||
20319                         error "split -c $c $tdir failed"
20320                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20321                         mdt_hash="$mdt_hash,fixed"
20322                 elif [ $c -eq 1 ]; then
20323                         mdt_hash="none"
20324                 fi
20325                 wait_update $HOSTNAME \
20326                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20327                         error "dir merge not finished"
20328                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20329                         awk '/migrate/ {sum += $2} END { print sum }')
20330                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20331                 # delta is around total_files/stripe_count
20332                 (( delta < 200 / c + 4 )) ||
20333                         error "$delta files migrated >= $((200 / c + 4))"
20334         done
20335 }
20336 run_test 230p "dir merge"
20337
20338 test_230q() {
20339         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20340         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20341                 skip "Need MDS version at least 2.13.52"
20342
20343         local mdts=$(comma_list $(mdts_nodes))
20344         local saved_threshold=$(do_facet mds1 \
20345                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20346         local saved_delta=$(do_facet mds1 \
20347                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20348         local threshold=100
20349         local delta=2
20350         local total=0
20351         local stripe_count=0
20352         local stripe_index
20353         local nr_files
20354         local create
20355
20356         # test with fewer files on ZFS
20357         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20358
20359         stack_trap "do_nodes $mdts $LCTL set_param \
20360                     mdt.*.dir_split_count=$saved_threshold"
20361         stack_trap "do_nodes $mdts $LCTL set_param \
20362                     mdt.*.dir_split_delta=$saved_delta"
20363         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20364         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20365         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20366         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20367         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20368         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20369
20370         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20371         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20372
20373         create=$((threshold * 3 / 2))
20374         while [ $stripe_count -lt $MDSCOUNT ]; do
20375                 createmany -m $DIR/$tdir/f $total $create ||
20376                         error "create sub files failed"
20377                 stat $DIR/$tdir > /dev/null
20378                 total=$((total + create))
20379                 stripe_count=$((stripe_count + delta))
20380                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20381
20382                 wait_update $HOSTNAME \
20383                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20384                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20385
20386                 wait_update $HOSTNAME \
20387                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20388                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20389
20390                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20391                 echo "$nr_files/$total files on MDT$stripe_index after split"
20392                 # allow 10% margin of imbalance with crush hash
20393                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20394                         error "$nr_files files on MDT$stripe_index after split"
20395
20396                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20397                 [ $nr_files -eq $total ] ||
20398                         error "total sub files $nr_files != $total"
20399         done
20400
20401         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20402
20403         echo "fixed layout directory won't auto split"
20404         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20405         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20406                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20407         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20408                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20409 }
20410 run_test 230q "dir auto split"
20411
20412 test_230r() {
20413         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20414         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20415         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20416                 skip "Need MDS version at least 2.13.54"
20417
20418         # maximum amount of local locks:
20419         # parent striped dir - 2 locks
20420         # new stripe in parent to migrate to - 1 lock
20421         # source and target - 2 locks
20422         # Total 5 locks for regular file
20423         mkdir -p $DIR/$tdir
20424         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20425         touch $DIR/$tdir/dir1/eee
20426
20427         # create 4 hardlink for 4 more locks
20428         # Total: 9 locks > RS_MAX_LOCKS (8)
20429         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20430         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20431         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20432         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20433         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20434         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20435         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20436         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20437
20438         cancel_lru_locks mdc
20439
20440         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20441                 error "migrate dir fails"
20442
20443         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20444 }
20445 run_test 230r "migrate with too many local locks"
20446
20447 test_230s() {
20448         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
20449                 skip "Need MDS version at least 2.13.57"
20450
20451         local mdts=$(comma_list $(mdts_nodes))
20452         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20453                                 mdt.*MDT0000.enable_dir_restripe)
20454
20455         stack_trap "do_nodes $mdts $LCTL set_param \
20456                     mdt.*.enable_dir_restripe=$restripe_status"
20457
20458         local st
20459         for st in 0 1; do
20460                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20461                 test_mkdir $DIR/$tdir
20462                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20463                         error "$LFS mkdir doesn't return -EEXIST if target exists"
20464                 rmdir $DIR/$tdir
20465         done
20466 }
20467 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20468
20469 test_230t()
20470 {
20471         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20472         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20473                 skip "Need MDS version at least 2.14.50"
20474
20475         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20476         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20477         $LFS project -p 1 -s $DIR/$tdir ||
20478                 error "set $tdir project id failed"
20479         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20480                 error "set subdir project id failed"
20481         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20482 }
20483 run_test 230t "migrate directory with project ID set"
20484
20485 test_230u()
20486 {
20487         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20488         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20489                 skip "Need MDS version at least 2.14.53"
20490
20491         local count
20492
20493         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20494         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20495         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20496         for i in $(seq 0 $((MDSCOUNT - 1))); do
20497                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20498                 echo "$count dirs migrated to MDT$i"
20499         done
20500         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20501         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20502 }
20503 run_test 230u "migrate directory by QOS"
20504
20505 test_230v()
20506 {
20507         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20508         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20509                 skip "Need MDS version at least 2.14.53"
20510
20511         local count
20512
20513         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20514         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20515         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20516         for i in $(seq 0 $((MDSCOUNT - 1))); do
20517                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20518                 echo "$count subdirs migrated to MDT$i"
20519                 (( i == 3 )) && (( count > 0 )) &&
20520                         error "subdir shouldn't be migrated to MDT3"
20521         done
20522         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20523         (( count == 3 )) || error "dirs migrated to $count MDTs"
20524 }
20525 run_test 230v "subdir migrated to the MDT where its parent is located"
20526
20527 test_230w() {
20528         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20529         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20530                 skip "Need MDS version at least 2.14.53"
20531
20532         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20533
20534         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20535                 error "migrate failed"
20536
20537         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20538                 error "$tdir stripe count mismatch"
20539
20540         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20541                 error "$tdir/sub is striped"
20542 }
20543 run_test 230w "non-recursive mode dir migration"
20544
20545 test_231a()
20546 {
20547         # For simplicity this test assumes that max_pages_per_rpc
20548         # is the same across all OSCs
20549         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20550         local bulk_size=$((max_pages * PAGE_SIZE))
20551         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20552                                        head -n 1)
20553
20554         mkdir -p $DIR/$tdir
20555         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20556                 error "failed to set stripe with -S ${brw_size}M option"
20557
20558         # clear the OSC stats
20559         $LCTL set_param osc.*.stats=0 &>/dev/null
20560         stop_writeback
20561
20562         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20563         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20564                 oflag=direct &>/dev/null || error "dd failed"
20565
20566         sync; sleep 1; sync # just to be safe
20567         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20568         if [ x$nrpcs != "x1" ]; then
20569                 $LCTL get_param osc.*.stats
20570                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20571         fi
20572
20573         start_writeback
20574         # Drop the OSC cache, otherwise we will read from it
20575         cancel_lru_locks osc
20576
20577         # clear the OSC stats
20578         $LCTL set_param osc.*.stats=0 &>/dev/null
20579
20580         # Client reads $bulk_size.
20581         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20582                 iflag=direct &>/dev/null || error "dd failed"
20583
20584         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20585         if [ x$nrpcs != "x1" ]; then
20586                 $LCTL get_param osc.*.stats
20587                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20588         fi
20589 }
20590 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20591
20592 test_231b() {
20593         mkdir -p $DIR/$tdir
20594         local i
20595         for i in {0..1023}; do
20596                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20597                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20598                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20599         done
20600         sync
20601 }
20602 run_test 231b "must not assert on fully utilized OST request buffer"
20603
20604 test_232a() {
20605         mkdir -p $DIR/$tdir
20606         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20607
20608         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20609         do_facet ost1 $LCTL set_param fail_loc=0x31c
20610
20611         # ignore dd failure
20612         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20613
20614         do_facet ost1 $LCTL set_param fail_loc=0
20615         umount_client $MOUNT || error "umount failed"
20616         mount_client $MOUNT || error "mount failed"
20617         stop ost1 || error "cannot stop ost1"
20618         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20619 }
20620 run_test 232a "failed lock should not block umount"
20621
20622 test_232b() {
20623         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20624                 skip "Need MDS version at least 2.10.58"
20625
20626         mkdir -p $DIR/$tdir
20627         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20628         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20629         sync
20630         cancel_lru_locks osc
20631
20632         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20633         do_facet ost1 $LCTL set_param fail_loc=0x31c
20634
20635         # ignore failure
20636         $LFS data_version $DIR/$tdir/$tfile || true
20637
20638         do_facet ost1 $LCTL set_param fail_loc=0
20639         umount_client $MOUNT || error "umount failed"
20640         mount_client $MOUNT || error "mount failed"
20641         stop ost1 || error "cannot stop ost1"
20642         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20643 }
20644 run_test 232b "failed data version lock should not block umount"
20645
20646 test_233a() {
20647         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20648                 skip "Need MDS version at least 2.3.64"
20649         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20650
20651         local fid=$($LFS path2fid $MOUNT)
20652
20653         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20654                 error "cannot access $MOUNT using its FID '$fid'"
20655 }
20656 run_test 233a "checking that OBF of the FS root succeeds"
20657
20658 test_233b() {
20659         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20660                 skip "Need MDS version at least 2.5.90"
20661         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20662
20663         local fid=$($LFS path2fid $MOUNT/.lustre)
20664
20665         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20666                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20667
20668         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20669         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20670                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20671 }
20672 run_test 233b "checking that OBF of the FS .lustre succeeds"
20673
20674 test_234() {
20675         local p="$TMP/sanityN-$TESTNAME.parameters"
20676         save_lustre_params client "llite.*.xattr_cache" > $p
20677         lctl set_param llite.*.xattr_cache 1 ||
20678                 skip_env "xattr cache is not supported"
20679
20680         mkdir -p $DIR/$tdir || error "mkdir failed"
20681         touch $DIR/$tdir/$tfile || error "touch failed"
20682         # OBD_FAIL_LLITE_XATTR_ENOMEM
20683         $LCTL set_param fail_loc=0x1405
20684         getfattr -n user.attr $DIR/$tdir/$tfile &&
20685                 error "getfattr should have failed with ENOMEM"
20686         $LCTL set_param fail_loc=0x0
20687         rm -rf $DIR/$tdir
20688
20689         restore_lustre_params < $p
20690         rm -f $p
20691 }
20692 run_test 234 "xattr cache should not crash on ENOMEM"
20693
20694 test_235() {
20695         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20696                 skip "Need MDS version at least 2.4.52"
20697
20698         flock_deadlock $DIR/$tfile
20699         local RC=$?
20700         case $RC in
20701                 0)
20702                 ;;
20703                 124) error "process hangs on a deadlock"
20704                 ;;
20705                 *) error "error executing flock_deadlock $DIR/$tfile"
20706                 ;;
20707         esac
20708 }
20709 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20710
20711 #LU-2935
20712 test_236() {
20713         check_swap_layouts_support
20714
20715         local ref1=/etc/passwd
20716         local ref2=/etc/group
20717         local file1=$DIR/$tdir/f1
20718         local file2=$DIR/$tdir/f2
20719
20720         test_mkdir -c1 $DIR/$tdir
20721         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20722         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20723         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20724         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20725         local fd=$(free_fd)
20726         local cmd="exec $fd<>$file2"
20727         eval $cmd
20728         rm $file2
20729         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20730                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20731         cmd="exec $fd>&-"
20732         eval $cmd
20733         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20734
20735         #cleanup
20736         rm -rf $DIR/$tdir
20737 }
20738 run_test 236 "Layout swap on open unlinked file"
20739
20740 # LU-4659 linkea consistency
20741 test_238() {
20742         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20743                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20744                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20745                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20746
20747         touch $DIR/$tfile
20748         ln $DIR/$tfile $DIR/$tfile.lnk
20749         touch $DIR/$tfile.new
20750         mv $DIR/$tfile.new $DIR/$tfile
20751         local fid1=$($LFS path2fid $DIR/$tfile)
20752         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20753         local path1=$($LFS fid2path $FSNAME "$fid1")
20754         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20755         local path2=$($LFS fid2path $FSNAME "$fid2")
20756         [ $tfile.lnk == $path2 ] ||
20757                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20758         rm -f $DIR/$tfile*
20759 }
20760 run_test 238 "Verify linkea consistency"
20761
20762 test_239A() { # was test_239
20763         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20764                 skip "Need MDS version at least 2.5.60"
20765
20766         local list=$(comma_list $(mdts_nodes))
20767
20768         mkdir -p $DIR/$tdir
20769         createmany -o $DIR/$tdir/f- 5000
20770         unlinkmany $DIR/$tdir/f- 5000
20771         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20772                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20773         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20774                         osp.*MDT*.sync_in_flight" | calc_sum)
20775         [ "$changes" -eq 0 ] || error "$changes not synced"
20776 }
20777 run_test 239A "osp_sync test"
20778
20779 test_239a() { #LU-5297
20780         remote_mds_nodsh && skip "remote MDS with nodsh"
20781
20782         touch $DIR/$tfile
20783         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20784         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20785         chgrp $RUNAS_GID $DIR/$tfile
20786         wait_delete_completed
20787 }
20788 run_test 239a "process invalid osp sync record correctly"
20789
20790 test_239b() { #LU-5297
20791         remote_mds_nodsh && skip "remote MDS with nodsh"
20792
20793         touch $DIR/$tfile1
20794         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20795         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20796         chgrp $RUNAS_GID $DIR/$tfile1
20797         wait_delete_completed
20798         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20799         touch $DIR/$tfile2
20800         chgrp $RUNAS_GID $DIR/$tfile2
20801         wait_delete_completed
20802 }
20803 run_test 239b "process osp sync record with ENOMEM error correctly"
20804
20805 test_240() {
20806         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20807         remote_mds_nodsh && skip "remote MDS with nodsh"
20808
20809         mkdir -p $DIR/$tdir
20810
20811         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20812                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20813         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20814                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20815
20816         umount_client $MOUNT || error "umount failed"
20817         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20818         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20819         mount_client $MOUNT || error "failed to mount client"
20820
20821         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20822         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20823 }
20824 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20825
20826 test_241_bio() {
20827         local count=$1
20828         local bsize=$2
20829
20830         for LOOP in $(seq $count); do
20831                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20832                 cancel_lru_locks $OSC || true
20833         done
20834 }
20835
20836 test_241_dio() {
20837         local count=$1
20838         local bsize=$2
20839
20840         for LOOP in $(seq $1); do
20841                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20842                         2>/dev/null
20843         done
20844 }
20845
20846 test_241a() { # was test_241
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         cancel_lru_locks $OSC
20853         test_241_bio 1000 $bsize &
20854         PID=$!
20855         test_241_dio 1000 $bsize
20856         wait $PID
20857 }
20858 run_test 241a "bio vs dio"
20859
20860 test_241b() {
20861         local bsize=$PAGE_SIZE
20862
20863         (( bsize < 40960 )) && bsize=40960
20864         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20865         ls -la $DIR/$tfile
20866         test_241_dio 1000 $bsize &
20867         PID=$!
20868         test_241_dio 1000 $bsize
20869         wait $PID
20870 }
20871 run_test 241b "dio vs dio"
20872
20873 test_242() {
20874         remote_mds_nodsh && skip "remote MDS with nodsh"
20875
20876         mkdir_on_mdt0 $DIR/$tdir
20877         touch $DIR/$tdir/$tfile
20878
20879         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20880         do_facet mds1 lctl set_param fail_loc=0x105
20881         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20882
20883         do_facet mds1 lctl set_param fail_loc=0
20884         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20885 }
20886 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20887
20888 test_243()
20889 {
20890         test_mkdir $DIR/$tdir
20891         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20892 }
20893 run_test 243 "various group lock tests"
20894
20895 test_244a()
20896 {
20897         test_mkdir $DIR/$tdir
20898         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20899         sendfile_grouplock $DIR/$tdir/$tfile || \
20900                 error "sendfile+grouplock failed"
20901         rm -rf $DIR/$tdir
20902 }
20903 run_test 244a "sendfile with group lock tests"
20904
20905 test_244b()
20906 {
20907         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20908
20909         local threads=50
20910         local size=$((1024*1024))
20911
20912         test_mkdir $DIR/$tdir
20913         for i in $(seq 1 $threads); do
20914                 local file=$DIR/$tdir/file_$((i / 10))
20915                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20916                 local pids[$i]=$!
20917         done
20918         for i in $(seq 1 $threads); do
20919                 wait ${pids[$i]}
20920         done
20921 }
20922 run_test 244b "multi-threaded write with group lock"
20923
20924 test_245() {
20925         local flagname="multi_mod_rpcs"
20926         local connect_data_name="max_mod_rpcs"
20927         local out
20928
20929         # check if multiple modify RPCs flag is set
20930         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20931                 grep "connect_flags:")
20932         echo "$out"
20933
20934         echo "$out" | grep -qw $flagname
20935         if [ $? -ne 0 ]; then
20936                 echo "connect flag $flagname is not set"
20937                 return
20938         fi
20939
20940         # check if multiple modify RPCs data is set
20941         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20942         echo "$out"
20943
20944         echo "$out" | grep -qw $connect_data_name ||
20945                 error "import should have connect data $connect_data_name"
20946 }
20947 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20948
20949 cleanup_247() {
20950         local submount=$1
20951
20952         trap 0
20953         umount_client $submount
20954         rmdir $submount
20955 }
20956
20957 test_247a() {
20958         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20959                 grep -q subtree ||
20960                 skip_env "Fileset feature is not supported"
20961
20962         local submount=${MOUNT}_$tdir
20963
20964         mkdir $MOUNT/$tdir
20965         mkdir -p $submount || error "mkdir $submount failed"
20966         FILESET="$FILESET/$tdir" mount_client $submount ||
20967                 error "mount $submount failed"
20968         trap "cleanup_247 $submount" EXIT
20969         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20970         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20971                 error "read $MOUNT/$tdir/$tfile failed"
20972         cleanup_247 $submount
20973 }
20974 run_test 247a "mount subdir as fileset"
20975
20976 test_247b() {
20977         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20978                 skip_env "Fileset feature is not supported"
20979
20980         local submount=${MOUNT}_$tdir
20981
20982         rm -rf $MOUNT/$tdir
20983         mkdir -p $submount || error "mkdir $submount failed"
20984         SKIP_FILESET=1
20985         FILESET="$FILESET/$tdir" mount_client $submount &&
20986                 error "mount $submount should fail"
20987         rmdir $submount
20988 }
20989 run_test 247b "mount subdir that dose not exist"
20990
20991 test_247c() {
20992         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20993                 skip_env "Fileset feature is not supported"
20994
20995         local submount=${MOUNT}_$tdir
20996
20997         mkdir -p $MOUNT/$tdir/dir1
20998         mkdir -p $submount || error "mkdir $submount failed"
20999         trap "cleanup_247 $submount" EXIT
21000         FILESET="$FILESET/$tdir" mount_client $submount ||
21001                 error "mount $submount failed"
21002         local fid=$($LFS path2fid $MOUNT/)
21003         $LFS fid2path $submount $fid && error "fid2path should fail"
21004         cleanup_247 $submount
21005 }
21006 run_test 247c "running fid2path outside subdirectory root"
21007
21008 test_247d() {
21009         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21010                 skip "Fileset feature is not supported"
21011
21012         local submount=${MOUNT}_$tdir
21013
21014         mkdir -p $MOUNT/$tdir/dir1
21015         mkdir -p $submount || error "mkdir $submount failed"
21016         FILESET="$FILESET/$tdir" mount_client $submount ||
21017                 error "mount $submount failed"
21018         trap "cleanup_247 $submount" EXIT
21019
21020         local td=$submount/dir1
21021         local fid=$($LFS path2fid $td)
21022         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21023
21024         # check that we get the same pathname back
21025         local rootpath
21026         local found
21027         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21028                 echo "$rootpath $fid"
21029                 found=$($LFS fid2path $rootpath "$fid")
21030                 [ -n "found" ] || error "fid2path should succeed"
21031                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21032         done
21033         # check wrong root path format
21034         rootpath=$submount"_wrong"
21035         found=$($LFS fid2path $rootpath "$fid")
21036         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21037
21038         cleanup_247 $submount
21039 }
21040 run_test 247d "running fid2path inside subdirectory root"
21041
21042 # LU-8037
21043 test_247e() {
21044         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21045                 grep -q subtree ||
21046                 skip "Fileset feature is not supported"
21047
21048         local submount=${MOUNT}_$tdir
21049
21050         mkdir $MOUNT/$tdir
21051         mkdir -p $submount || error "mkdir $submount failed"
21052         FILESET="$FILESET/.." mount_client $submount &&
21053                 error "mount $submount should fail"
21054         rmdir $submount
21055 }
21056 run_test 247e "mount .. as fileset"
21057
21058 test_247f() {
21059         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21060         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21061                 skip "Need at least version 2.13.52"
21062         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21063                 skip "Need at least version 2.14.50"
21064         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21065                 grep -q subtree ||
21066                 skip "Fileset feature is not supported"
21067
21068         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21069         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21070                 error "mkdir remote failed"
21071         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21072                 error "mkdir remote/subdir failed"
21073         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21074                 error "mkdir striped failed"
21075         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21076
21077         local submount=${MOUNT}_$tdir
21078
21079         mkdir -p $submount || error "mkdir $submount failed"
21080         stack_trap "rmdir $submount"
21081
21082         local dir
21083         local stat
21084         local fileset=$FILESET
21085         local mdts=$(comma_list $(mdts_nodes))
21086
21087         stat=$(do_facet mds1 $LCTL get_param -n \
21088                 mdt.*MDT0000.enable_remote_subdir_mount)
21089         stack_trap "do_nodes $mdts $LCTL set_param \
21090                 mdt.*.enable_remote_subdir_mount=$stat"
21091
21092         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21093         stack_trap "umount_client $submount"
21094         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21095                 error "mount remote dir $dir should fail"
21096
21097         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21098                 $tdir/striped/. ; do
21099                 FILESET="$fileset/$dir" mount_client $submount ||
21100                         error "mount $dir failed"
21101                 umount_client $submount
21102         done
21103
21104         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21105         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21106                 error "mount $tdir/remote failed"
21107 }
21108 run_test 247f "mount striped or remote directory as fileset"
21109
21110 test_247g() {
21111         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21112         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21113                 skip "Need at least version 2.14.50"
21114
21115         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21116                 error "mkdir $tdir failed"
21117         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21118
21119         local submount=${MOUNT}_$tdir
21120
21121         mkdir -p $submount || error "mkdir $submount failed"
21122         stack_trap "rmdir $submount"
21123
21124         FILESET="$fileset/$tdir" mount_client $submount ||
21125                 error "mount $dir failed"
21126         stack_trap "umount $submount"
21127
21128         local mdts=$(comma_list $(mdts_nodes))
21129
21130         local nrpcs
21131
21132         stat $submount > /dev/null
21133         cancel_lru_locks $MDC
21134         stat $submount > /dev/null
21135         stat $submount/$tfile > /dev/null
21136         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21137         stat $submount/$tfile > /dev/null
21138         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21139                 awk '/getattr/ {sum += $2} END {print sum}')
21140
21141         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21142 }
21143 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21144
21145 test_248a() {
21146         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21147         [ -z "$fast_read_sav" ] && skip "no fast read support"
21148
21149         # create a large file for fast read verification
21150         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21151
21152         # make sure the file is created correctly
21153         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21154                 { rm -f $DIR/$tfile; skip "file creation error"; }
21155
21156         echo "Test 1: verify that fast read is 4 times faster on cache read"
21157
21158         # small read with fast read enabled
21159         $LCTL set_param -n llite.*.fast_read=1
21160         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21161                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21162                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21163         # small read with fast read disabled
21164         $LCTL set_param -n llite.*.fast_read=0
21165         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21166                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21167                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21168
21169         # verify that fast read is 4 times faster for cache read
21170         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21171                 error_not_in_vm "fast read was not 4 times faster: " \
21172                            "$t_fast vs $t_slow"
21173
21174         echo "Test 2: verify the performance between big and small read"
21175         $LCTL set_param -n llite.*.fast_read=1
21176
21177         # 1k non-cache read
21178         cancel_lru_locks osc
21179         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21180                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21181                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21182
21183         # 1M non-cache read
21184         cancel_lru_locks osc
21185         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21186                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21187                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21188
21189         # verify that big IO is not 4 times faster than small IO
21190         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21191                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21192
21193         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21194         rm -f $DIR/$tfile
21195 }
21196 run_test 248a "fast read verification"
21197
21198 test_248b() {
21199         # Default short_io_bytes=16384, try both smaller and larger sizes.
21200         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21201         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21202         echo "bs=53248 count=113 normal buffered write"
21203         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21204                 error "dd of initial data file failed"
21205         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21206
21207         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21208         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21209                 error "dd with sync normal writes failed"
21210         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21211
21212         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21213         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21214                 error "dd with sync small writes failed"
21215         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21216
21217         cancel_lru_locks osc
21218
21219         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21220         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21221         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21222         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21223                 iflag=direct || error "dd with O_DIRECT small read failed"
21224         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21225         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21226                 error "compare $TMP/$tfile.1 failed"
21227
21228         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21229         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21230
21231         # just to see what the maximum tunable value is, and test parsing
21232         echo "test invalid parameter 2MB"
21233         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21234                 error "too-large short_io_bytes allowed"
21235         echo "test maximum parameter 512KB"
21236         # if we can set a larger short_io_bytes, run test regardless of version
21237         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21238                 # older clients may not allow setting it this large, that's OK
21239                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21240                         skip "Need at least client version 2.13.50"
21241                 error "medium short_io_bytes failed"
21242         fi
21243         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21244         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21245
21246         echo "test large parameter 64KB"
21247         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21248         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21249
21250         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21251         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21252                 error "dd with sync large writes failed"
21253         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21254
21255         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21256         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21257         num=$((113 * 4096 / PAGE_SIZE))
21258         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21259         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21260                 error "dd with O_DIRECT large writes failed"
21261         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21262                 error "compare $DIR/$tfile.3 failed"
21263
21264         cancel_lru_locks osc
21265
21266         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21267         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21268                 error "dd with O_DIRECT large read failed"
21269         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21270                 error "compare $TMP/$tfile.2 failed"
21271
21272         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21273         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21274                 error "dd with O_DIRECT large read failed"
21275         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21276                 error "compare $TMP/$tfile.3 failed"
21277 }
21278 run_test 248b "test short_io read and write for both small and large sizes"
21279
21280 test_249() { # LU-7890
21281         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21282                 skip "Need at least version 2.8.54"
21283
21284         rm -f $DIR/$tfile
21285         $LFS setstripe -c 1 $DIR/$tfile
21286         # Offset 2T == 4k * 512M
21287         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21288                 error "dd to 2T offset failed"
21289 }
21290 run_test 249 "Write above 2T file size"
21291
21292 test_250() {
21293         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21294          && skip "no 16TB file size limit on ZFS"
21295
21296         $LFS setstripe -c 1 $DIR/$tfile
21297         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21298         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21299         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21300         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21301                 conv=notrunc,fsync && error "append succeeded"
21302         return 0
21303 }
21304 run_test 250 "Write above 16T limit"
21305
21306 test_251() {
21307         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21308
21309         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21310         #Skip once - writing the first stripe will succeed
21311         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21312         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21313                 error "short write happened"
21314
21315         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21316         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21317                 error "short read happened"
21318
21319         rm -f $DIR/$tfile
21320 }
21321 run_test 251 "Handling short read and write correctly"
21322
21323 test_252() {
21324         remote_mds_nodsh && skip "remote MDS with nodsh"
21325         remote_ost_nodsh && skip "remote OST with nodsh"
21326         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21327                 skip_env "ldiskfs only test"
21328         fi
21329
21330         local tgt
21331         local dev
21332         local out
21333         local uuid
21334         local num
21335         local gen
21336
21337         # check lr_reader on OST0000
21338         tgt=ost1
21339         dev=$(facet_device $tgt)
21340         out=$(do_facet $tgt $LR_READER $dev)
21341         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21342         echo "$out"
21343         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21344         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21345                 error "Invalid uuid returned by $LR_READER on target $tgt"
21346         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21347
21348         # check lr_reader -c on MDT0000
21349         tgt=mds1
21350         dev=$(facet_device $tgt)
21351         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21352                 skip "$LR_READER does not support additional options"
21353         fi
21354         out=$(do_facet $tgt $LR_READER -c $dev)
21355         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21356         echo "$out"
21357         num=$(echo "$out" | grep -c "mdtlov")
21358         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21359                 error "Invalid number of mdtlov clients returned by $LR_READER"
21360         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21361
21362         # check lr_reader -cr on MDT0000
21363         out=$(do_facet $tgt $LR_READER -cr $dev)
21364         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21365         echo "$out"
21366         echo "$out" | grep -q "^reply_data:$" ||
21367                 error "$LR_READER should have returned 'reply_data' section"
21368         num=$(echo "$out" | grep -c "client_generation")
21369         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21370 }
21371 run_test 252 "check lr_reader tool"
21372
21373 test_253() {
21374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21375         remote_mds_nodsh && skip "remote MDS with nodsh"
21376         remote_mgs_nodsh && skip "remote MGS with nodsh"
21377
21378         local ostidx=0
21379         local rc=0
21380         local ost_name=$(ostname_from_index $ostidx)
21381
21382         # on the mdt's osc
21383         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21384         do_facet $SINGLEMDS $LCTL get_param -n \
21385                 osp.$mdtosc_proc1.reserved_mb_high ||
21386                 skip  "remote MDS does not support reserved_mb_high"
21387
21388         rm -rf $DIR/$tdir
21389         wait_mds_ost_sync
21390         wait_delete_completed
21391         mkdir $DIR/$tdir
21392
21393         pool_add $TESTNAME || error "Pool creation failed"
21394         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21395
21396         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21397                 error "Setstripe failed"
21398
21399         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21400
21401         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21402                     grep "watermarks")
21403         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21404
21405         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21406                         osp.$mdtosc_proc1.prealloc_status)
21407         echo "prealloc_status $oa_status"
21408
21409         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21410                 error "File creation should fail"
21411
21412         #object allocation was stopped, but we still able to append files
21413         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21414                 oflag=append || error "Append failed"
21415
21416         rm -f $DIR/$tdir/$tfile.0
21417
21418         # For this test, we want to delete the files we created to go out of
21419         # space but leave the watermark, so we remain nearly out of space
21420         ost_watermarks_enospc_delete_files $tfile $ostidx
21421
21422         wait_delete_completed
21423
21424         sleep_maxage
21425
21426         for i in $(seq 10 12); do
21427                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21428                         2>/dev/null || error "File creation failed after rm"
21429         done
21430
21431         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21432                         osp.$mdtosc_proc1.prealloc_status)
21433         echo "prealloc_status $oa_status"
21434
21435         if (( oa_status != 0 )); then
21436                 error "Object allocation still disable after rm"
21437         fi
21438 }
21439 run_test 253 "Check object allocation limit"
21440
21441 test_254() {
21442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21443         remote_mds_nodsh && skip "remote MDS with nodsh"
21444
21445         local mdt=$(facet_svc $SINGLEMDS)
21446
21447         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21448                 skip "MDS does not support changelog_size"
21449
21450         local cl_user
21451
21452         changelog_register || error "changelog_register failed"
21453
21454         changelog_clear 0 || error "changelog_clear failed"
21455
21456         local size1=$(do_facet $SINGLEMDS \
21457                       $LCTL get_param -n mdd.$mdt.changelog_size)
21458         echo "Changelog size $size1"
21459
21460         rm -rf $DIR/$tdir
21461         $LFS mkdir -i 0 $DIR/$tdir
21462         # change something
21463         mkdir -p $DIR/$tdir/pics/2008/zachy
21464         touch $DIR/$tdir/pics/2008/zachy/timestamp
21465         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21466         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21467         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21468         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21469         rm $DIR/$tdir/pics/desktop.jpg
21470
21471         local size2=$(do_facet $SINGLEMDS \
21472                       $LCTL get_param -n mdd.$mdt.changelog_size)
21473         echo "Changelog size after work $size2"
21474
21475         (( $size2 > $size1 )) ||
21476                 error "new Changelog size=$size2 less than old size=$size1"
21477 }
21478 run_test 254 "Check changelog size"
21479
21480 ladvise_no_type()
21481 {
21482         local type=$1
21483         local file=$2
21484
21485         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21486                 awk -F: '{print $2}' | grep $type > /dev/null
21487         if [ $? -ne 0 ]; then
21488                 return 0
21489         fi
21490         return 1
21491 }
21492
21493 ladvise_no_ioctl()
21494 {
21495         local file=$1
21496
21497         lfs ladvise -a willread $file > /dev/null 2>&1
21498         if [ $? -eq 0 ]; then
21499                 return 1
21500         fi
21501
21502         lfs ladvise -a willread $file 2>&1 |
21503                 grep "Inappropriate ioctl for device" > /dev/null
21504         if [ $? -eq 0 ]; then
21505                 return 0
21506         fi
21507         return 1
21508 }
21509
21510 percent() {
21511         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21512 }
21513
21514 # run a random read IO workload
21515 # usage: random_read_iops <filename> <filesize> <iosize>
21516 random_read_iops() {
21517         local file=$1
21518         local fsize=$2
21519         local iosize=${3:-4096}
21520
21521         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21522                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21523 }
21524
21525 drop_file_oss_cache() {
21526         local file="$1"
21527         local nodes="$2"
21528
21529         $LFS ladvise -a dontneed $file 2>/dev/null ||
21530                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21531 }
21532
21533 ladvise_willread_performance()
21534 {
21535         local repeat=10
21536         local average_origin=0
21537         local average_cache=0
21538         local average_ladvise=0
21539
21540         for ((i = 1; i <= $repeat; i++)); do
21541                 echo "Iter $i/$repeat: reading without willread hint"
21542                 cancel_lru_locks osc
21543                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21544                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21545                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21546                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21547
21548                 cancel_lru_locks osc
21549                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21550                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21551                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21552
21553                 cancel_lru_locks osc
21554                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21555                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21556                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21557                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21558                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21559         done
21560         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21561         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21562         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21563
21564         speedup_cache=$(percent $average_cache $average_origin)
21565         speedup_ladvise=$(percent $average_ladvise $average_origin)
21566
21567         echo "Average uncached read: $average_origin"
21568         echo "Average speedup with OSS cached read: " \
21569                 "$average_cache = +$speedup_cache%"
21570         echo "Average speedup with ladvise willread: " \
21571                 "$average_ladvise = +$speedup_ladvise%"
21572
21573         local lowest_speedup=20
21574         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
21575                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
21576                         "got $average_cache%. Skipping ladvise willread check."
21577                 return 0
21578         fi
21579
21580         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21581         # it is still good to run until then to exercise 'ladvise willread'
21582         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21583                 [ "$ost1_FSTYPE" = "zfs" ] &&
21584                 echo "osd-zfs does not support dontneed or drop_caches" &&
21585                 return 0
21586
21587         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21588         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
21589                 error_not_in_vm "Speedup with willread is less than " \
21590                         "$lowest_speedup%, got $average_ladvise%"
21591 }
21592
21593 test_255a() {
21594         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21595                 skip "lustre < 2.8.54 does not support ladvise "
21596         remote_ost_nodsh && skip "remote OST with nodsh"
21597
21598         stack_trap "rm -f $DIR/$tfile"
21599         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21600
21601         ladvise_no_type willread $DIR/$tfile &&
21602                 skip "willread ladvise is not supported"
21603
21604         ladvise_no_ioctl $DIR/$tfile &&
21605                 skip "ladvise ioctl is not supported"
21606
21607         local size_mb=100
21608         local size=$((size_mb * 1048576))
21609         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21610                 error "dd to $DIR/$tfile failed"
21611
21612         lfs ladvise -a willread $DIR/$tfile ||
21613                 error "Ladvise failed with no range argument"
21614
21615         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21616                 error "Ladvise failed with no -l or -e argument"
21617
21618         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21619                 error "Ladvise failed with only -e argument"
21620
21621         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21622                 error "Ladvise failed with only -l argument"
21623
21624         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21625                 error "End offset should not be smaller than start offset"
21626
21627         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21628                 error "End offset should not be equal to start offset"
21629
21630         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21631                 error "Ladvise failed with overflowing -s argument"
21632
21633         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21634                 error "Ladvise failed with overflowing -e argument"
21635
21636         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21637                 error "Ladvise failed with overflowing -l argument"
21638
21639         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21640                 error "Ladvise succeeded with conflicting -l and -e arguments"
21641
21642         echo "Synchronous ladvise should wait"
21643         local delay=4
21644 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21645         do_nodes $(comma_list $(osts_nodes)) \
21646                 $LCTL set_param fail_val=$delay fail_loc=0x237
21647
21648         local start_ts=$SECONDS
21649         lfs ladvise -a willread $DIR/$tfile ||
21650                 error "Ladvise failed with no range argument"
21651         local end_ts=$SECONDS
21652         local inteval_ts=$((end_ts - start_ts))
21653
21654         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21655                 error "Synchronous advice didn't wait reply"
21656         fi
21657
21658         echo "Asynchronous ladvise shouldn't wait"
21659         local start_ts=$SECONDS
21660         lfs ladvise -a willread -b $DIR/$tfile ||
21661                 error "Ladvise failed with no range argument"
21662         local end_ts=$SECONDS
21663         local inteval_ts=$((end_ts - start_ts))
21664
21665         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21666                 error "Asynchronous advice blocked"
21667         fi
21668
21669         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21670         ladvise_willread_performance
21671 }
21672 run_test 255a "check 'lfs ladvise -a willread'"
21673
21674 facet_meminfo() {
21675         local facet=$1
21676         local info=$2
21677
21678         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21679 }
21680
21681 test_255b() {
21682         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21683                 skip "lustre < 2.8.54 does not support ladvise "
21684         remote_ost_nodsh && skip "remote OST with nodsh"
21685
21686         stack_trap "rm -f $DIR/$tfile"
21687         lfs setstripe -c 1 -i 0 $DIR/$tfile
21688
21689         ladvise_no_type dontneed $DIR/$tfile &&
21690                 skip "dontneed ladvise is not supported"
21691
21692         ladvise_no_ioctl $DIR/$tfile &&
21693                 skip "ladvise ioctl is not supported"
21694
21695         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21696                 [ "$ost1_FSTYPE" = "zfs" ] &&
21697                 skip "zfs-osd does not support 'ladvise dontneed'"
21698
21699         local size_mb=100
21700         local size=$((size_mb * 1048576))
21701         # In order to prevent disturbance of other processes, only check 3/4
21702         # of the memory usage
21703         local kibibytes=$((size_mb * 1024 * 3 / 4))
21704
21705         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21706                 error "dd to $DIR/$tfile failed"
21707
21708         #force write to complete before dropping OST cache & checking memory
21709         sync
21710
21711         local total=$(facet_meminfo ost1 MemTotal)
21712         echo "Total memory: $total KiB"
21713
21714         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21715         local before_read=$(facet_meminfo ost1 Cached)
21716         echo "Cache used before read: $before_read KiB"
21717
21718         lfs ladvise -a willread $DIR/$tfile ||
21719                 error "Ladvise willread failed"
21720         local after_read=$(facet_meminfo ost1 Cached)
21721         echo "Cache used after read: $after_read KiB"
21722
21723         lfs ladvise -a dontneed $DIR/$tfile ||
21724                 error "Ladvise dontneed again failed"
21725         local no_read=$(facet_meminfo ost1 Cached)
21726         echo "Cache used after dontneed ladvise: $no_read KiB"
21727
21728         if [ $total -lt $((before_read + kibibytes)) ]; then
21729                 echo "Memory is too small, abort checking"
21730                 return 0
21731         fi
21732
21733         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21734                 error "Ladvise willread should use more memory" \
21735                         "than $kibibytes KiB"
21736         fi
21737
21738         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21739                 error "Ladvise dontneed should release more memory" \
21740                         "than $kibibytes KiB"
21741         fi
21742 }
21743 run_test 255b "check 'lfs ladvise -a dontneed'"
21744
21745 test_255c() {
21746         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21747                 skip "lustre < 2.10.50 does not support lockahead"
21748
21749         local ost1_imp=$(get_osc_import_name client ost1)
21750         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21751                          cut -d'.' -f2)
21752         local count
21753         local new_count
21754         local difference
21755         local i
21756         local rc
21757
21758         test_mkdir -p $DIR/$tdir
21759         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21760
21761         #test 10 returns only success/failure
21762         i=10
21763         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21764         rc=$?
21765         if [ $rc -eq 255 ]; then
21766                 error "Ladvise test${i} failed, ${rc}"
21767         fi
21768
21769         #test 11 counts lock enqueue requests, all others count new locks
21770         i=11
21771         count=$(do_facet ost1 \
21772                 $LCTL get_param -n ost.OSS.ost.stats)
21773         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21774
21775         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21776         rc=$?
21777         if [ $rc -eq 255 ]; then
21778                 error "Ladvise test${i} failed, ${rc}"
21779         fi
21780
21781         new_count=$(do_facet ost1 \
21782                 $LCTL get_param -n ost.OSS.ost.stats)
21783         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21784                    awk '{ print $2 }')
21785
21786         difference="$((new_count - count))"
21787         if [ $difference -ne $rc ]; then
21788                 error "Ladvise test${i}, bad enqueue count, returned " \
21789                       "${rc}, actual ${difference}"
21790         fi
21791
21792         for i in $(seq 12 21); do
21793                 # If we do not do this, we run the risk of having too many
21794                 # locks and starting lock cancellation while we are checking
21795                 # lock counts.
21796                 cancel_lru_locks osc
21797
21798                 count=$($LCTL get_param -n \
21799                        ldlm.namespaces.$imp_name.lock_unused_count)
21800
21801                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21802                 rc=$?
21803                 if [ $rc -eq 255 ]; then
21804                         error "Ladvise test ${i} failed, ${rc}"
21805                 fi
21806
21807                 new_count=$($LCTL get_param -n \
21808                        ldlm.namespaces.$imp_name.lock_unused_count)
21809                 difference="$((new_count - count))"
21810
21811                 # Test 15 output is divided by 100 to map down to valid return
21812                 if [ $i -eq 15 ]; then
21813                         rc="$((rc * 100))"
21814                 fi
21815
21816                 if [ $difference -ne $rc ]; then
21817                         error "Ladvise test ${i}, bad lock count, returned " \
21818                               "${rc}, actual ${difference}"
21819                 fi
21820         done
21821
21822         #test 22 returns only success/failure
21823         i=22
21824         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21825         rc=$?
21826         if [ $rc -eq 255 ]; then
21827                 error "Ladvise test${i} failed, ${rc}"
21828         fi
21829 }
21830 run_test 255c "suite of ladvise lockahead tests"
21831
21832 test_256() {
21833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21834         remote_mds_nodsh && skip "remote MDS with nodsh"
21835         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21836         changelog_users $SINGLEMDS | grep "^cl" &&
21837                 skip "active changelog user"
21838
21839         local cl_user
21840         local cat_sl
21841         local mdt_dev
21842
21843         mdt_dev=$(facet_device $SINGLEMDS)
21844         echo $mdt_dev
21845
21846         changelog_register || error "changelog_register failed"
21847
21848         rm -rf $DIR/$tdir
21849         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
21850
21851         changelog_clear 0 || error "changelog_clear failed"
21852
21853         # change something
21854         touch $DIR/$tdir/{1..10}
21855
21856         # stop the MDT
21857         stop $SINGLEMDS || error "Fail to stop MDT"
21858
21859         # remount the MDT
21860         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21861                 error "Fail to start MDT"
21862
21863         #after mount new plainllog is used
21864         touch $DIR/$tdir/{11..19}
21865         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21866         stack_trap "rm -f $tmpfile"
21867         cat_sl=$(do_facet $SINGLEMDS "sync; \
21868                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21869                  llog_reader $tmpfile | grep -c type=1064553b")
21870         do_facet $SINGLEMDS llog_reader $tmpfile
21871
21872         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21873
21874         changelog_clear 0 || error "changelog_clear failed"
21875
21876         cat_sl=$(do_facet $SINGLEMDS "sync; \
21877                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21878                  llog_reader $tmpfile | grep -c type=1064553b")
21879
21880         if (( cat_sl == 2 )); then
21881                 error "Empty plain llog was not deleted from changelog catalog"
21882         elif (( cat_sl != 1 )); then
21883                 error "Active plain llog shouldn't be deleted from catalog"
21884         fi
21885 }
21886 run_test 256 "Check llog delete for empty and not full state"
21887
21888 test_257() {
21889         remote_mds_nodsh && skip "remote MDS with nodsh"
21890         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21891                 skip "Need MDS version at least 2.8.55"
21892
21893         test_mkdir $DIR/$tdir
21894
21895         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21896                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21897         stat $DIR/$tdir
21898
21899 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21900         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21901         local facet=mds$((mdtidx + 1))
21902         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21903         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21904
21905         stop $facet || error "stop MDS failed"
21906         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21907                 error "start MDS fail"
21908         wait_recovery_complete $facet
21909 }
21910 run_test 257 "xattr locks are not lost"
21911
21912 # Verify we take the i_mutex when security requires it
21913 test_258a() {
21914 #define OBD_FAIL_IMUTEX_SEC 0x141c
21915         $LCTL set_param fail_loc=0x141c
21916         touch $DIR/$tfile
21917         chmod u+s $DIR/$tfile
21918         chmod a+rwx $DIR/$tfile
21919         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21920         RC=$?
21921         if [ $RC -ne 0 ]; then
21922                 error "error, failed to take i_mutex, rc=$?"
21923         fi
21924         rm -f $DIR/$tfile
21925 }
21926 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21927
21928 # Verify we do NOT take the i_mutex in the normal case
21929 test_258b() {
21930 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21931         $LCTL set_param fail_loc=0x141d
21932         touch $DIR/$tfile
21933         chmod a+rwx $DIR
21934         chmod a+rw $DIR/$tfile
21935         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21936         RC=$?
21937         if [ $RC -ne 0 ]; then
21938                 error "error, took i_mutex unnecessarily, rc=$?"
21939         fi
21940         rm -f $DIR/$tfile
21941
21942 }
21943 run_test 258b "verify i_mutex security behavior"
21944
21945 test_259() {
21946         local file=$DIR/$tfile
21947         local before
21948         local after
21949
21950         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21951
21952         stack_trap "rm -f $file" EXIT
21953
21954         wait_delete_completed
21955         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21956         echo "before: $before"
21957
21958         $LFS setstripe -i 0 -c 1 $file
21959         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21960         sync_all_data
21961         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21962         echo "after write: $after"
21963
21964 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21965         do_facet ost1 $LCTL set_param fail_loc=0x2301
21966         $TRUNCATE $file 0
21967         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21968         echo "after truncate: $after"
21969
21970         stop ost1
21971         do_facet ost1 $LCTL set_param fail_loc=0
21972         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21973         sleep 2
21974         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21975         echo "after restart: $after"
21976         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21977                 error "missing truncate?"
21978
21979         return 0
21980 }
21981 run_test 259 "crash at delayed truncate"
21982
21983 test_260() {
21984 #define OBD_FAIL_MDC_CLOSE               0x806
21985         $LCTL set_param fail_loc=0x80000806
21986         touch $DIR/$tfile
21987
21988 }
21989 run_test 260 "Check mdc_close fail"
21990
21991 ### Data-on-MDT sanity tests ###
21992 test_270a() {
21993         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21994                 skip "Need MDS version at least 2.10.55 for DoM"
21995
21996         # create DoM file
21997         local dom=$DIR/$tdir/dom_file
21998         local tmp=$DIR/$tdir/tmp_file
21999
22000         mkdir_on_mdt0 $DIR/$tdir
22001
22002         # basic checks for DoM component creation
22003         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22004                 error "Can set MDT layout to non-first entry"
22005
22006         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22007                 error "Can define multiple entries as MDT layout"
22008
22009         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22010
22011         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22012         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22013         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22014
22015         local mdtidx=$($LFS getstripe -m $dom)
22016         local mdtname=MDT$(printf %04x $mdtidx)
22017         local facet=mds$((mdtidx + 1))
22018         local space_check=1
22019
22020         # Skip free space checks with ZFS
22021         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22022
22023         # write
22024         sync
22025         local size_tmp=$((65536 * 3))
22026         local mdtfree1=$(do_facet $facet \
22027                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22028
22029         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22030         # check also direct IO along write
22031         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22032         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22033         sync
22034         cmp $tmp $dom || error "file data is different"
22035         [ $(stat -c%s $dom) == $size_tmp ] ||
22036                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22037         if [ $space_check == 1 ]; then
22038                 local mdtfree2=$(do_facet $facet \
22039                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22040
22041                 # increase in usage from by $size_tmp
22042                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22043                         error "MDT free space wrong after write: " \
22044                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22045         fi
22046
22047         # truncate
22048         local size_dom=10000
22049
22050         $TRUNCATE $dom $size_dom
22051         [ $(stat -c%s $dom) == $size_dom ] ||
22052                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22053         if [ $space_check == 1 ]; then
22054                 mdtfree1=$(do_facet $facet \
22055                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22056                 # decrease in usage from $size_tmp to new $size_dom
22057                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22058                   $(((size_tmp - size_dom) / 1024)) ] ||
22059                         error "MDT free space is wrong after truncate: " \
22060                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22061         fi
22062
22063         # append
22064         cat $tmp >> $dom
22065         sync
22066         size_dom=$((size_dom + size_tmp))
22067         [ $(stat -c%s $dom) == $size_dom ] ||
22068                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22069         if [ $space_check == 1 ]; then
22070                 mdtfree2=$(do_facet $facet \
22071                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22072                 # increase in usage by $size_tmp from previous
22073                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22074                         error "MDT free space is wrong after append: " \
22075                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22076         fi
22077
22078         # delete
22079         rm $dom
22080         if [ $space_check == 1 ]; then
22081                 mdtfree1=$(do_facet $facet \
22082                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22083                 # decrease in usage by $size_dom from previous
22084                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22085                         error "MDT free space is wrong after removal: " \
22086                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22087         fi
22088
22089         # combined striping
22090         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22091                 error "Can't create DoM + OST striping"
22092
22093         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22094         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22095         # check also direct IO along write
22096         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22097         sync
22098         cmp $tmp $dom || error "file data is different"
22099         [ $(stat -c%s $dom) == $size_tmp ] ||
22100                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22101         rm $dom $tmp
22102
22103         return 0
22104 }
22105 run_test 270a "DoM: basic functionality tests"
22106
22107 test_270b() {
22108         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22109                 skip "Need MDS version at least 2.10.55"
22110
22111         local dom=$DIR/$tdir/dom_file
22112         local max_size=1048576
22113
22114         mkdir -p $DIR/$tdir
22115         $LFS setstripe -E $max_size -L mdt $dom
22116
22117         # truncate over the limit
22118         $TRUNCATE $dom $(($max_size + 1)) &&
22119                 error "successful truncate over the maximum size"
22120         # write over the limit
22121         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22122                 error "successful write over the maximum size"
22123         # append over the limit
22124         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22125         echo "12345" >> $dom && error "successful append over the maximum size"
22126         rm $dom
22127
22128         return 0
22129 }
22130 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22131
22132 test_270c() {
22133         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22134                 skip "Need MDS version at least 2.10.55"
22135
22136         mkdir -p $DIR/$tdir
22137         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22138
22139         # check files inherit DoM EA
22140         touch $DIR/$tdir/first
22141         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22142                 error "bad pattern"
22143         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22144                 error "bad stripe count"
22145         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22146                 error "bad stripe size"
22147
22148         # check directory inherits DoM EA and uses it as default
22149         mkdir $DIR/$tdir/subdir
22150         touch $DIR/$tdir/subdir/second
22151         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22152                 error "bad pattern in sub-directory"
22153         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22154                 error "bad stripe count in sub-directory"
22155         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22156                 error "bad stripe size in sub-directory"
22157         return 0
22158 }
22159 run_test 270c "DoM: DoM EA inheritance tests"
22160
22161 test_270d() {
22162         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22163                 skip "Need MDS version at least 2.10.55"
22164
22165         mkdir -p $DIR/$tdir
22166         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22167
22168         # inherit default DoM striping
22169         mkdir $DIR/$tdir/subdir
22170         touch $DIR/$tdir/subdir/f1
22171
22172         # change default directory striping
22173         $LFS setstripe -c 1 $DIR/$tdir/subdir
22174         touch $DIR/$tdir/subdir/f2
22175         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22176                 error "wrong default striping in file 2"
22177         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22178                 error "bad pattern in file 2"
22179         return 0
22180 }
22181 run_test 270d "DoM: change striping from DoM to RAID0"
22182
22183 test_270e() {
22184         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22185                 skip "Need MDS version at least 2.10.55"
22186
22187         mkdir -p $DIR/$tdir/dom
22188         mkdir -p $DIR/$tdir/norm
22189         DOMFILES=20
22190         NORMFILES=10
22191         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22192         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22193
22194         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22195         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22196
22197         # find DoM files by layout
22198         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22199         [ $NUM -eq  $DOMFILES ] ||
22200                 error "lfs find -L: found $NUM, expected $DOMFILES"
22201         echo "Test 1: lfs find 20 DOM files by layout: OK"
22202
22203         # there should be 1 dir with default DOM striping
22204         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22205         [ $NUM -eq  1 ] ||
22206                 error "lfs find -L: found $NUM, expected 1 dir"
22207         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22208
22209         # find DoM files by stripe size
22210         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22211         [ $NUM -eq  $DOMFILES ] ||
22212                 error "lfs find -S: found $NUM, expected $DOMFILES"
22213         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22214
22215         # find files by stripe offset except DoM files
22216         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22217         [ $NUM -eq  $NORMFILES ] ||
22218                 error "lfs find -i: found $NUM, expected $NORMFILES"
22219         echo "Test 5: lfs find no DOM files by stripe index: OK"
22220         return 0
22221 }
22222 run_test 270e "DoM: lfs find with DoM files test"
22223
22224 test_270f() {
22225         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22226                 skip "Need MDS version at least 2.10.55"
22227
22228         local mdtname=${FSNAME}-MDT0000-mdtlov
22229         local dom=$DIR/$tdir/dom_file
22230         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22231                                                 lod.$mdtname.dom_stripesize)
22232         local dom_limit=131072
22233
22234         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22235         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22236                                                 lod.$mdtname.dom_stripesize)
22237         [ ${dom_limit} -eq ${dom_current} ] ||
22238                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22239
22240         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22241         $LFS setstripe -d $DIR/$tdir
22242         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22243                 error "Can't set directory default striping"
22244
22245         # exceed maximum stripe size
22246         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22247                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22248         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22249                 error "Able to create DoM component size more than LOD limit"
22250
22251         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22252         dom_current=$(do_facet mds1 $LCTL get_param -n \
22253                                                 lod.$mdtname.dom_stripesize)
22254         [ 0 -eq ${dom_current} ] ||
22255                 error "Can't set zero DoM stripe limit"
22256         rm $dom
22257
22258         # attempt to create DoM file on server with disabled DoM should
22259         # remove DoM entry from layout and be succeed
22260         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22261                 error "Can't create DoM file (DoM is disabled)"
22262         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22263                 error "File has DoM component while DoM is disabled"
22264         rm $dom
22265
22266         # attempt to create DoM file with only DoM stripe should return error
22267         $LFS setstripe -E $dom_limit -L mdt $dom &&
22268                 error "Able to create DoM-only file while DoM is disabled"
22269
22270         # too low values to be aligned with smallest stripe size 64K
22271         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22272         dom_current=$(do_facet mds1 $LCTL get_param -n \
22273                                                 lod.$mdtname.dom_stripesize)
22274         [ 30000 -eq ${dom_current} ] &&
22275                 error "Can set too small DoM stripe limit"
22276
22277         # 64K is a minimal stripe size in Lustre, expect limit of that size
22278         [ 65536 -eq ${dom_current} ] ||
22279                 error "Limit is not set to 64K but ${dom_current}"
22280
22281         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22282         dom_current=$(do_facet mds1 $LCTL get_param -n \
22283                                                 lod.$mdtname.dom_stripesize)
22284         echo $dom_current
22285         [ 2147483648 -eq ${dom_current} ] &&
22286                 error "Can set too large DoM stripe limit"
22287
22288         do_facet mds1 $LCTL set_param -n \
22289                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22290         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22291                 error "Can't create DoM component size after limit change"
22292         do_facet mds1 $LCTL set_param -n \
22293                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22294         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22295                 error "Can't create DoM file after limit decrease"
22296         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22297                 error "Can create big DoM component after limit decrease"
22298         touch ${dom}_def ||
22299                 error "Can't create file with old default layout"
22300
22301         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22302         return 0
22303 }
22304 run_test 270f "DoM: maximum DoM stripe size checks"
22305
22306 test_270g() {
22307         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22308                 skip "Need MDS version at least 2.13.52"
22309         local dom=$DIR/$tdir/$tfile
22310
22311         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22312         local lodname=${FSNAME}-MDT0000-mdtlov
22313
22314         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22315         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22316         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22317         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22318
22319         local dom_limit=1024
22320         local dom_threshold="50%"
22321
22322         $LFS setstripe -d $DIR/$tdir
22323         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22324                 error "Can't set directory default striping"
22325
22326         do_facet mds1 $LCTL set_param -n \
22327                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22328         # set 0 threshold and create DOM file to change tunable stripesize
22329         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22330         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22331                 error "Failed to create $dom file"
22332         # now tunable dom_cur_stripesize should reach maximum
22333         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22334                                         lod.${lodname}.dom_stripesize_cur_kb)
22335         [[ $dom_current == $dom_limit ]] ||
22336                 error "Current DOM stripesize is not maximum"
22337         rm $dom
22338
22339         # set threshold for further tests
22340         do_facet mds1 $LCTL set_param -n \
22341                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22342         echo "DOM threshold is $dom_threshold free space"
22343         local dom_def
22344         local dom_set
22345         # Spoof bfree to exceed threshold
22346         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22347         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22348         for spfree in 40 20 0 15 30 55; do
22349                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22350                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22351                         error "Failed to create $dom file"
22352                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22353                                         lod.${lodname}.dom_stripesize_cur_kb)
22354                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22355                 [[ $dom_def != $dom_current ]] ||
22356                         error "Default stripe size was not changed"
22357                 if [[ $spfree > 0 ]] ; then
22358                         dom_set=$($LFS getstripe -S $dom)
22359                         [[ $dom_set == $((dom_def * 1024)) ]] ||
22360                                 error "DOM component size is still old"
22361                 else
22362                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22363                                 error "DoM component is set with no free space"
22364                 fi
22365                 rm $dom
22366                 dom_current=$dom_def
22367         done
22368 }
22369 run_test 270g "DoM: default DoM stripe size depends on free space"
22370
22371 test_270h() {
22372         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22373                 skip "Need MDS version at least 2.13.53"
22374
22375         local mdtname=${FSNAME}-MDT0000-mdtlov
22376         local dom=$DIR/$tdir/$tfile
22377         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22378
22379         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22380         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22381
22382         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22383         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22384                 error "can't create OST file"
22385         # mirrored file with DOM entry in the second mirror
22386         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22387                 error "can't create mirror with DoM component"
22388
22389         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22390
22391         # DOM component in the middle and has other enries in the same mirror,
22392         # should succeed but lost DoM component
22393         $LFS setstripe --copy=${dom}_1 $dom ||
22394                 error "Can't create file from OST|DOM mirror layout"
22395         # check new file has no DoM layout after all
22396         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22397                 error "File has DoM component while DoM is disabled"
22398 }
22399 run_test 270h "DoM: DoM stripe removal when disabled on server"
22400
22401 test_270i() {
22402         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22403                 skip "Need MDS version at least 2.14.54"
22404
22405         mkdir $DIR/$tdir
22406         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22407                 error "setstripe should fail" || true
22408 }
22409 run_test 270i "DoM: setting invalid DoM striping should fail"
22410
22411 test_271a() {
22412         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22413                 skip "Need MDS version at least 2.10.55"
22414
22415         local dom=$DIR/$tdir/dom
22416
22417         mkdir -p $DIR/$tdir
22418
22419         $LFS setstripe -E 1024K -L mdt $dom
22420
22421         lctl set_param -n mdc.*.stats=clear
22422         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22423         cat $dom > /dev/null
22424         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22425         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22426         ls $dom
22427         rm -f $dom
22428 }
22429 run_test 271a "DoM: data is cached for read after write"
22430
22431 test_271b() {
22432         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22433                 skip "Need MDS version at least 2.10.55"
22434
22435         local dom=$DIR/$tdir/dom
22436
22437         mkdir -p $DIR/$tdir
22438
22439         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22440
22441         lctl set_param -n mdc.*.stats=clear
22442         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22443         cancel_lru_locks mdc
22444         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22445         # second stat to check size is cached on client
22446         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22447         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22448         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22449         rm -f $dom
22450 }
22451 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22452
22453 test_271ba() {
22454         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22455                 skip "Need MDS version at least 2.10.55"
22456
22457         local dom=$DIR/$tdir/dom
22458
22459         mkdir -p $DIR/$tdir
22460
22461         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22462
22463         lctl set_param -n mdc.*.stats=clear
22464         lctl set_param -n osc.*.stats=clear
22465         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22466         cancel_lru_locks mdc
22467         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22468         # second stat to check size is cached on client
22469         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22470         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22471         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22472         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22473         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22474         rm -f $dom
22475 }
22476 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22477
22478
22479 get_mdc_stats() {
22480         local mdtidx=$1
22481         local param=$2
22482         local mdt=MDT$(printf %04x $mdtidx)
22483
22484         if [ -z $param ]; then
22485                 lctl get_param -n mdc.*$mdt*.stats
22486         else
22487                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22488         fi
22489 }
22490
22491 test_271c() {
22492         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22493                 skip "Need MDS version at least 2.10.55"
22494
22495         local dom=$DIR/$tdir/dom
22496
22497         mkdir -p $DIR/$tdir
22498
22499         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22500
22501         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22502         local facet=mds$((mdtidx + 1))
22503
22504         cancel_lru_locks mdc
22505         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22506         createmany -o $dom 1000
22507         lctl set_param -n mdc.*.stats=clear
22508         smalliomany -w $dom 1000 200
22509         get_mdc_stats $mdtidx
22510         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22511         # Each file has 1 open, 1 IO enqueues, total 2000
22512         # but now we have also +1 getxattr for security.capability, total 3000
22513         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22514         unlinkmany $dom 1000
22515
22516         cancel_lru_locks mdc
22517         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22518         createmany -o $dom 1000
22519         lctl set_param -n mdc.*.stats=clear
22520         smalliomany -w $dom 1000 200
22521         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22522         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22523         # for OPEN and IO lock.
22524         [ $((enq - enq_2)) -ge 1000 ] ||
22525                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22526         unlinkmany $dom 1000
22527         return 0
22528 }
22529 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22530
22531 cleanup_271def_tests() {
22532         trap 0
22533         rm -f $1
22534 }
22535
22536 test_271d() {
22537         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22538                 skip "Need MDS version at least 2.10.57"
22539
22540         local dom=$DIR/$tdir/dom
22541         local tmp=$TMP/$tfile
22542         trap "cleanup_271def_tests $tmp" EXIT
22543
22544         mkdir -p $DIR/$tdir
22545
22546         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22547
22548         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22549
22550         cancel_lru_locks mdc
22551         dd if=/dev/urandom of=$tmp bs=1000 count=1
22552         dd if=$tmp of=$dom bs=1000 count=1
22553         cancel_lru_locks mdc
22554
22555         cat /etc/hosts >> $tmp
22556         lctl set_param -n mdc.*.stats=clear
22557
22558         # append data to the same file it should update local page
22559         echo "Append to the same page"
22560         cat /etc/hosts >> $dom
22561         local num=$(get_mdc_stats $mdtidx ost_read)
22562         local ra=$(get_mdc_stats $mdtidx req_active)
22563         local rw=$(get_mdc_stats $mdtidx req_waittime)
22564
22565         [ -z $num ] || error "$num READ RPC occured"
22566         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22567         echo "... DONE"
22568
22569         # compare content
22570         cmp $tmp $dom || error "file miscompare"
22571
22572         cancel_lru_locks mdc
22573         lctl set_param -n mdc.*.stats=clear
22574
22575         echo "Open and read file"
22576         cat $dom > /dev/null
22577         local num=$(get_mdc_stats $mdtidx ost_read)
22578         local ra=$(get_mdc_stats $mdtidx req_active)
22579         local rw=$(get_mdc_stats $mdtidx req_waittime)
22580
22581         [ -z $num ] || error "$num READ RPC occured"
22582         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22583         echo "... DONE"
22584
22585         # compare content
22586         cmp $tmp $dom || error "file miscompare"
22587
22588         return 0
22589 }
22590 run_test 271d "DoM: read on open (1K file in reply buffer)"
22591
22592 test_271f() {
22593         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22594                 skip "Need MDS version at least 2.10.57"
22595
22596         local dom=$DIR/$tdir/dom
22597         local tmp=$TMP/$tfile
22598         trap "cleanup_271def_tests $tmp" EXIT
22599
22600         mkdir -p $DIR/$tdir
22601
22602         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22603
22604         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22605
22606         cancel_lru_locks mdc
22607         dd if=/dev/urandom of=$tmp bs=265000 count=1
22608         dd if=$tmp of=$dom bs=265000 count=1
22609         cancel_lru_locks mdc
22610         cat /etc/hosts >> $tmp
22611         lctl set_param -n mdc.*.stats=clear
22612
22613         echo "Append to the same page"
22614         cat /etc/hosts >> $dom
22615         local num=$(get_mdc_stats $mdtidx ost_read)
22616         local ra=$(get_mdc_stats $mdtidx req_active)
22617         local rw=$(get_mdc_stats $mdtidx req_waittime)
22618
22619         [ -z $num ] || error "$num READ RPC occured"
22620         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22621         echo "... DONE"
22622
22623         # compare content
22624         cmp $tmp $dom || error "file miscompare"
22625
22626         cancel_lru_locks mdc
22627         lctl set_param -n mdc.*.stats=clear
22628
22629         echo "Open and read file"
22630         cat $dom > /dev/null
22631         local num=$(get_mdc_stats $mdtidx ost_read)
22632         local ra=$(get_mdc_stats $mdtidx req_active)
22633         local rw=$(get_mdc_stats $mdtidx req_waittime)
22634
22635         [ -z $num ] && num=0
22636         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22637         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22638         echo "... DONE"
22639
22640         # compare content
22641         cmp $tmp $dom || error "file miscompare"
22642
22643         return 0
22644 }
22645 run_test 271f "DoM: read on open (200K file and read tail)"
22646
22647 test_271g() {
22648         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22649                 skip "Skipping due to old client or server version"
22650
22651         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22652         # to get layout
22653         $CHECKSTAT -t file $DIR1/$tfile
22654
22655         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22656         MULTIOP_PID=$!
22657         sleep 1
22658         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22659         $LCTL set_param fail_loc=0x80000314
22660         rm $DIR1/$tfile || error "Unlink fails"
22661         RC=$?
22662         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22663         [ $RC -eq 0 ] || error "Failed write to stale object"
22664 }
22665 run_test 271g "Discard DoM data vs client flush race"
22666
22667 test_272a() {
22668         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22669                 skip "Need MDS version at least 2.11.50"
22670
22671         local dom=$DIR/$tdir/dom
22672         mkdir -p $DIR/$tdir
22673
22674         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22675         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22676                 error "failed to write data into $dom"
22677         local old_md5=$(md5sum $dom)
22678
22679         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22680                 error "failed to migrate to the same DoM component"
22681
22682         local new_md5=$(md5sum $dom)
22683
22684         [ "$old_md5" == "$new_md5" ] ||
22685                 error "md5sum differ: $old_md5, $new_md5"
22686
22687         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22688                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22689 }
22690 run_test 272a "DoM migration: new layout with the same DOM component"
22691
22692 test_272b() {
22693         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22694                 skip "Need MDS version at least 2.11.50"
22695
22696         local dom=$DIR/$tdir/dom
22697         mkdir -p $DIR/$tdir
22698         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22699
22700         local mdtidx=$($LFS getstripe -m $dom)
22701         local mdtname=MDT$(printf %04x $mdtidx)
22702         local facet=mds$((mdtidx + 1))
22703
22704         local mdtfree1=$(do_facet $facet \
22705                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22706         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22707                 error "failed to write data into $dom"
22708         local old_md5=$(md5sum $dom)
22709         cancel_lru_locks mdc
22710         local mdtfree1=$(do_facet $facet \
22711                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22712
22713         $LFS migrate -c2 $dom ||
22714                 error "failed to migrate to the new composite layout"
22715         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22716                 error "MDT stripe was not removed"
22717
22718         cancel_lru_locks mdc
22719         local new_md5=$(md5sum $dom)
22720         [ "$old_md5" == "$new_md5" ] ||
22721                 error "$old_md5 != $new_md5"
22722
22723         # Skip free space checks with ZFS
22724         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22725                 local mdtfree2=$(do_facet $facet \
22726                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22727                 [ $mdtfree2 -gt $mdtfree1 ] ||
22728                         error "MDT space is not freed after migration"
22729         fi
22730         return 0
22731 }
22732 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22733
22734 test_272c() {
22735         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22736                 skip "Need MDS version at least 2.11.50"
22737
22738         local dom=$DIR/$tdir/$tfile
22739         mkdir -p $DIR/$tdir
22740         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22741
22742         local mdtidx=$($LFS getstripe -m $dom)
22743         local mdtname=MDT$(printf %04x $mdtidx)
22744         local facet=mds$((mdtidx + 1))
22745
22746         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22747                 error "failed to write data into $dom"
22748         local old_md5=$(md5sum $dom)
22749         cancel_lru_locks mdc
22750         local mdtfree1=$(do_facet $facet \
22751                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22752
22753         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22754                 error "failed to migrate to the new composite layout"
22755         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22756                 error "MDT stripe was not removed"
22757
22758         cancel_lru_locks mdc
22759         local new_md5=$(md5sum $dom)
22760         [ "$old_md5" == "$new_md5" ] ||
22761                 error "$old_md5 != $new_md5"
22762
22763         # Skip free space checks with ZFS
22764         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22765                 local mdtfree2=$(do_facet $facet \
22766                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22767                 [ $mdtfree2 -gt $mdtfree1 ] ||
22768                         error "MDS space is not freed after migration"
22769         fi
22770         return 0
22771 }
22772 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22773
22774 test_272d() {
22775         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22776                 skip "Need MDS version at least 2.12.55"
22777
22778         local dom=$DIR/$tdir/$tfile
22779         mkdir -p $DIR/$tdir
22780         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22781
22782         local mdtidx=$($LFS getstripe -m $dom)
22783         local mdtname=MDT$(printf %04x $mdtidx)
22784         local facet=mds$((mdtidx + 1))
22785
22786         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22787                 error "failed to write data into $dom"
22788         local old_md5=$(md5sum $dom)
22789         cancel_lru_locks mdc
22790         local mdtfree1=$(do_facet $facet \
22791                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22792
22793         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22794                 error "failed mirroring to the new composite layout"
22795         $LFS mirror resync $dom ||
22796                 error "failed mirror resync"
22797         $LFS mirror split --mirror-id 1 -d $dom ||
22798                 error "failed mirror split"
22799
22800         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22801                 error "MDT stripe was not removed"
22802
22803         cancel_lru_locks mdc
22804         local new_md5=$(md5sum $dom)
22805         [ "$old_md5" == "$new_md5" ] ||
22806                 error "$old_md5 != $new_md5"
22807
22808         # Skip free space checks with ZFS
22809         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22810                 local mdtfree2=$(do_facet $facet \
22811                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22812                 [ $mdtfree2 -gt $mdtfree1 ] ||
22813                         error "MDS space is not freed after DOM mirror deletion"
22814         fi
22815         return 0
22816 }
22817 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22818
22819 test_272e() {
22820         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22821                 skip "Need MDS version at least 2.12.55"
22822
22823         local dom=$DIR/$tdir/$tfile
22824         mkdir -p $DIR/$tdir
22825         $LFS setstripe -c 2 $dom
22826
22827         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22828                 error "failed to write data into $dom"
22829         local old_md5=$(md5sum $dom)
22830         cancel_lru_locks
22831
22832         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22833                 error "failed mirroring to the DOM layout"
22834         $LFS mirror resync $dom ||
22835                 error "failed mirror resync"
22836         $LFS mirror split --mirror-id 1 -d $dom ||
22837                 error "failed mirror split"
22838
22839         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22840                 error "MDT stripe wasn't set"
22841
22842         cancel_lru_locks
22843         local new_md5=$(md5sum $dom)
22844         [ "$old_md5" == "$new_md5" ] ||
22845                 error "$old_md5 != $new_md5"
22846
22847         return 0
22848 }
22849 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22850
22851 test_272f() {
22852         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22853                 skip "Need MDS version at least 2.12.55"
22854
22855         local dom=$DIR/$tdir/$tfile
22856         mkdir -p $DIR/$tdir
22857         $LFS setstripe -c 2 $dom
22858
22859         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22860                 error "failed to write data into $dom"
22861         local old_md5=$(md5sum $dom)
22862         cancel_lru_locks
22863
22864         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22865                 error "failed migrating to the DOM file"
22866
22867         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22868                 error "MDT stripe wasn't set"
22869
22870         cancel_lru_locks
22871         local new_md5=$(md5sum $dom)
22872         [ "$old_md5" != "$new_md5" ] &&
22873                 error "$old_md5 != $new_md5"
22874
22875         return 0
22876 }
22877 run_test 272f "DoM migration: OST-striped file to DOM file"
22878
22879 test_273a() {
22880         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22881                 skip "Need MDS version at least 2.11.50"
22882
22883         # Layout swap cannot be done if either file has DOM component,
22884         # this will never be supported, migration should be used instead
22885
22886         local dom=$DIR/$tdir/$tfile
22887         mkdir -p $DIR/$tdir
22888
22889         $LFS setstripe -c2 ${dom}_plain
22890         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22891         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22892                 error "can swap layout with DoM component"
22893         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22894                 error "can swap layout with DoM component"
22895
22896         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22897         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22898                 error "can swap layout with DoM component"
22899         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22900                 error "can swap layout with DoM component"
22901         return 0
22902 }
22903 run_test 273a "DoM: layout swapping should fail with DOM"
22904
22905 test_273b() {
22906         mkdir -p $DIR/$tdir
22907         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22908
22909 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22910         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22911
22912         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22913 }
22914 run_test 273b "DoM: race writeback and object destroy"
22915
22916 test_275() {
22917         remote_ost_nodsh && skip "remote OST with nodsh"
22918         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22919                 skip "Need OST version >= 2.10.57"
22920
22921         local file=$DIR/$tfile
22922         local oss
22923
22924         oss=$(comma_list $(osts_nodes))
22925
22926         dd if=/dev/urandom of=$file bs=1M count=2 ||
22927                 error "failed to create a file"
22928         cancel_lru_locks osc
22929
22930         #lock 1
22931         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22932                 error "failed to read a file"
22933
22934 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22935         $LCTL set_param fail_loc=0x8000031f
22936
22937         cancel_lru_locks osc &
22938         sleep 1
22939
22940 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22941         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22942         #IO takes another lock, but matches the PENDING one
22943         #and places it to the IO RPC
22944         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22945                 error "failed to read a file with PENDING lock"
22946 }
22947 run_test 275 "Read on a canceled duplicate lock"
22948
22949 test_276() {
22950         remote_ost_nodsh && skip "remote OST with nodsh"
22951         local pid
22952
22953         do_facet ost1 "(while true; do \
22954                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22955                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22956         pid=$!
22957
22958         for LOOP in $(seq 20); do
22959                 stop ost1
22960                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22961         done
22962         kill -9 $pid
22963         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22964                 rm $TMP/sanity_276_pid"
22965 }
22966 run_test 276 "Race between mount and obd_statfs"
22967
22968 test_277() {
22969         $LCTL set_param ldlm.namespaces.*.lru_size=0
22970         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22971         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22972                         grep ^used_mb | awk '{print $2}')
22973         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22974         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22975                 oflag=direct conv=notrunc
22976         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22977                         grep ^used_mb | awk '{print $2}')
22978         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22979 }
22980 run_test 277 "Direct IO shall drop page cache"
22981
22982 test_278() {
22983         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22984         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22985         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22986                 skip "needs the same host for mdt1 mdt2" && return
22987
22988         local pid1
22989         local pid2
22990
22991 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22992         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22993         stop mds2 &
22994         pid2=$!
22995
22996         stop mds1
22997
22998         echo "Starting MDTs"
22999         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23000         wait $pid2
23001 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23002 #will return NULL
23003         do_facet mds2 $LCTL set_param fail_loc=0
23004
23005         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23006         wait_recovery_complete mds2
23007 }
23008 run_test 278 "Race starting MDS between MDTs stop/start"
23009
23010 test_280() {
23011         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23012                 skip "Need MGS version at least 2.13.52"
23013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23014         combined_mgs_mds || skip "needs combined MGS/MDT"
23015
23016         umount_client $MOUNT
23017 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23018         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23019
23020         mount_client $MOUNT &
23021         sleep 1
23022         stop mgs || error "stop mgs failed"
23023         #for a race mgs would crash
23024         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23025         # make sure we unmount client before remounting
23026         wait
23027         umount_client $MOUNT
23028         mount_client $MOUNT || error "mount client failed"
23029 }
23030 run_test 280 "Race between MGS umount and client llog processing"
23031
23032 cleanup_test_300() {
23033         trap 0
23034         umask $SAVE_UMASK
23035 }
23036 test_striped_dir() {
23037         local mdt_index=$1
23038         local stripe_count
23039         local stripe_index
23040
23041         mkdir -p $DIR/$tdir
23042
23043         SAVE_UMASK=$(umask)
23044         trap cleanup_test_300 RETURN EXIT
23045
23046         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23047                                                 $DIR/$tdir/striped_dir ||
23048                 error "set striped dir error"
23049
23050         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23051         [ "$mode" = "755" ] || error "expect 755 got $mode"
23052
23053         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23054                 error "getdirstripe failed"
23055         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23056         if [ "$stripe_count" != "2" ]; then
23057                 error "1:stripe_count is $stripe_count, expect 2"
23058         fi
23059         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23060         if [ "$stripe_count" != "2" ]; then
23061                 error "2:stripe_count is $stripe_count, expect 2"
23062         fi
23063
23064         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23065         if [ "$stripe_index" != "$mdt_index" ]; then
23066                 error "stripe_index is $stripe_index, expect $mdt_index"
23067         fi
23068
23069         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23070                 error "nlink error after create striped dir"
23071
23072         mkdir $DIR/$tdir/striped_dir/a
23073         mkdir $DIR/$tdir/striped_dir/b
23074
23075         stat $DIR/$tdir/striped_dir/a ||
23076                 error "create dir under striped dir failed"
23077         stat $DIR/$tdir/striped_dir/b ||
23078                 error "create dir under striped dir failed"
23079
23080         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23081                 error "nlink error after mkdir"
23082
23083         rmdir $DIR/$tdir/striped_dir/a
23084         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23085                 error "nlink error after rmdir"
23086
23087         rmdir $DIR/$tdir/striped_dir/b
23088         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23089                 error "nlink error after rmdir"
23090
23091         chattr +i $DIR/$tdir/striped_dir
23092         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23093                 error "immutable flags not working under striped dir!"
23094         chattr -i $DIR/$tdir/striped_dir
23095
23096         rmdir $DIR/$tdir/striped_dir ||
23097                 error "rmdir striped dir error"
23098
23099         cleanup_test_300
23100
23101         true
23102 }
23103
23104 test_300a() {
23105         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23106                 skip "skipped for lustre < 2.7.0"
23107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23108         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23109
23110         test_striped_dir 0 || error "failed on striped dir on MDT0"
23111         test_striped_dir 1 || error "failed on striped dir on MDT0"
23112 }
23113 run_test 300a "basic striped dir sanity test"
23114
23115 test_300b() {
23116         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23117                 skip "skipped for lustre < 2.7.0"
23118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23119         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23120
23121         local i
23122         local mtime1
23123         local mtime2
23124         local mtime3
23125
23126         test_mkdir $DIR/$tdir || error "mkdir fail"
23127         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23128                 error "set striped dir error"
23129         for i in {0..9}; do
23130                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23131                 sleep 1
23132                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23133                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23134                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23135                 sleep 1
23136                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23137                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23138                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23139         done
23140         true
23141 }
23142 run_test 300b "check ctime/mtime for striped dir"
23143
23144 test_300c() {
23145         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23146                 skip "skipped for lustre < 2.7.0"
23147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23148         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23149
23150         local file_count
23151
23152         mkdir_on_mdt0 $DIR/$tdir
23153         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23154                 error "set striped dir error"
23155
23156         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23157                 error "chown striped dir failed"
23158
23159         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23160                 error "create 5k files failed"
23161
23162         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23163
23164         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23165
23166         rm -rf $DIR/$tdir
23167 }
23168 run_test 300c "chown && check ls under striped directory"
23169
23170 test_300d() {
23171         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23172                 skip "skipped for lustre < 2.7.0"
23173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23174         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23175
23176         local stripe_count
23177         local file
23178
23179         mkdir -p $DIR/$tdir
23180         $LFS setstripe -c 2 $DIR/$tdir
23181
23182         #local striped directory
23183         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23184                 error "set striped dir error"
23185         #look at the directories for debug purposes
23186         ls -l $DIR/$tdir
23187         $LFS getdirstripe $DIR/$tdir
23188         ls -l $DIR/$tdir/striped_dir
23189         $LFS getdirstripe $DIR/$tdir/striped_dir
23190         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23191                 error "create 10 files failed"
23192
23193         #remote striped directory
23194         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23195                 error "set striped dir error"
23196         #look at the directories for debug purposes
23197         ls -l $DIR/$tdir
23198         $LFS getdirstripe $DIR/$tdir
23199         ls -l $DIR/$tdir/remote_striped_dir
23200         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23201         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23202                 error "create 10 files failed"
23203
23204         for file in $(find $DIR/$tdir); do
23205                 stripe_count=$($LFS getstripe -c $file)
23206                 [ $stripe_count -eq 2 ] ||
23207                         error "wrong stripe $stripe_count for $file"
23208         done
23209
23210         rm -rf $DIR/$tdir
23211 }
23212 run_test 300d "check default stripe under striped directory"
23213
23214 test_300e() {
23215         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23216                 skip "Need MDS version at least 2.7.55"
23217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23218         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23219
23220         local stripe_count
23221         local file
23222
23223         mkdir -p $DIR/$tdir
23224
23225         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23226                 error "set striped dir error"
23227
23228         touch $DIR/$tdir/striped_dir/a
23229         touch $DIR/$tdir/striped_dir/b
23230         touch $DIR/$tdir/striped_dir/c
23231
23232         mkdir $DIR/$tdir/striped_dir/dir_a
23233         mkdir $DIR/$tdir/striped_dir/dir_b
23234         mkdir $DIR/$tdir/striped_dir/dir_c
23235
23236         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23237                 error "set striped adir under striped dir error"
23238
23239         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23240                 error "set striped bdir under striped dir error"
23241
23242         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23243                 error "set striped cdir under striped dir error"
23244
23245         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23246                 error "rename dir under striped dir fails"
23247
23248         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23249                 error "rename dir under different stripes fails"
23250
23251         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23252                 error "rename file under striped dir should succeed"
23253
23254         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23255                 error "rename dir under striped dir should succeed"
23256
23257         rm -rf $DIR/$tdir
23258 }
23259 run_test 300e "check rename under striped directory"
23260
23261 test_300f() {
23262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23263         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23264         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23265                 skip "Need MDS version at least 2.7.55"
23266
23267         local stripe_count
23268         local file
23269
23270         rm -rf $DIR/$tdir
23271         mkdir -p $DIR/$tdir
23272
23273         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23274                 error "set striped dir error"
23275
23276         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23277                 error "set striped dir error"
23278
23279         touch $DIR/$tdir/striped_dir/a
23280         mkdir $DIR/$tdir/striped_dir/dir_a
23281         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23282                 error "create striped dir under striped dir fails"
23283
23284         touch $DIR/$tdir/striped_dir1/b
23285         mkdir $DIR/$tdir/striped_dir1/dir_b
23286         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23287                 error "create striped dir under striped dir fails"
23288
23289         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23290                 error "rename dir under different striped dir should fail"
23291
23292         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23293                 error "rename striped dir under diff striped dir should fail"
23294
23295         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23296                 error "rename file under diff striped dirs fails"
23297
23298         rm -rf $DIR/$tdir
23299 }
23300 run_test 300f "check rename cross striped directory"
23301
23302 test_300_check_default_striped_dir()
23303 {
23304         local dirname=$1
23305         local default_count=$2
23306         local default_index=$3
23307         local stripe_count
23308         local stripe_index
23309         local dir_stripe_index
23310         local dir
23311
23312         echo "checking $dirname $default_count $default_index"
23313         $LFS setdirstripe -D -c $default_count -i $default_index \
23314                                 -H all_char $DIR/$tdir/$dirname ||
23315                 error "set default stripe on striped dir error"
23316         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23317         [ $stripe_count -eq $default_count ] ||
23318                 error "expect $default_count get $stripe_count for $dirname"
23319
23320         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23321         [ $stripe_index -eq $default_index ] ||
23322                 error "expect $default_index get $stripe_index for $dirname"
23323
23324         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23325                                                 error "create dirs failed"
23326
23327         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23328         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23329         for dir in $(find $DIR/$tdir/$dirname/*); do
23330                 stripe_count=$($LFS getdirstripe -c $dir)
23331                 (( $stripe_count == $default_count )) ||
23332                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23333                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23334                 error "stripe count $default_count != $stripe_count for $dir"
23335
23336                 stripe_index=$($LFS getdirstripe -i $dir)
23337                 [ $default_index -eq -1 ] ||
23338                         [ $stripe_index -eq $default_index ] ||
23339                         error "$stripe_index != $default_index for $dir"
23340
23341                 #check default stripe
23342                 stripe_count=$($LFS getdirstripe -D -c $dir)
23343                 [ $stripe_count -eq $default_count ] ||
23344                 error "default count $default_count != $stripe_count for $dir"
23345
23346                 stripe_index=$($LFS getdirstripe -D -i $dir)
23347                 [ $stripe_index -eq $default_index ] ||
23348                 error "default index $default_index != $stripe_index for $dir"
23349         done
23350         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23351 }
23352
23353 test_300g() {
23354         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23355         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23356                 skip "Need MDS version at least 2.7.55"
23357
23358         local dir
23359         local stripe_count
23360         local stripe_index
23361
23362         mkdir_on_mdt0 $DIR/$tdir
23363         mkdir $DIR/$tdir/normal_dir
23364
23365         #Checking when client cache stripe index
23366         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23367         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23368                 error "create striped_dir failed"
23369
23370         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23371                 error "create dir0 fails"
23372         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23373         [ $stripe_index -eq 0 ] ||
23374                 error "dir0 expect index 0 got $stripe_index"
23375
23376         mkdir $DIR/$tdir/striped_dir/dir1 ||
23377                 error "create dir1 fails"
23378         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23379         [ $stripe_index -eq 1 ] ||
23380                 error "dir1 expect index 1 got $stripe_index"
23381
23382         #check default stripe count/stripe index
23383         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23384         test_300_check_default_striped_dir normal_dir 1 0
23385         test_300_check_default_striped_dir normal_dir -1 1
23386         test_300_check_default_striped_dir normal_dir 2 -1
23387
23388         #delete default stripe information
23389         echo "delete default stripeEA"
23390         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23391                 error "set default stripe on striped dir error"
23392
23393         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23394         for dir in $(find $DIR/$tdir/normal_dir/*); do
23395                 stripe_count=$($LFS getdirstripe -c $dir)
23396                 [ $stripe_count -eq 0 ] ||
23397                         error "expect 1 get $stripe_count for $dir"
23398         done
23399 }
23400 run_test 300g "check default striped directory for normal directory"
23401
23402 test_300h() {
23403         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23404         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23405                 skip "Need MDS version at least 2.7.55"
23406
23407         local dir
23408         local stripe_count
23409
23410         mkdir $DIR/$tdir
23411         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23412                 error "set striped dir error"
23413
23414         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23415         test_300_check_default_striped_dir striped_dir 1 0
23416         test_300_check_default_striped_dir striped_dir -1 1
23417         test_300_check_default_striped_dir striped_dir 2 -1
23418
23419         #delete default stripe information
23420         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23421                 error "set default stripe on striped dir error"
23422
23423         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23424         for dir in $(find $DIR/$tdir/striped_dir/*); do
23425                 stripe_count=$($LFS getdirstripe -c $dir)
23426                 [ $stripe_count -eq 0 ] ||
23427                         error "expect 1 get $stripe_count for $dir"
23428         done
23429 }
23430 run_test 300h "check default striped directory for striped directory"
23431
23432 test_300i() {
23433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23434         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23435         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23436                 skip "Need MDS version at least 2.7.55"
23437
23438         local stripe_count
23439         local file
23440
23441         mkdir $DIR/$tdir
23442
23443         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23444                 error "set striped dir error"
23445
23446         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23447                 error "create files under striped dir failed"
23448
23449         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23450                 error "set striped hashdir error"
23451
23452         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23453                 error "create dir0 under hash dir failed"
23454         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23455                 error "create dir1 under hash dir failed"
23456         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23457                 error "create dir2 under hash dir failed"
23458
23459         # unfortunately, we need to umount to clear dir layout cache for now
23460         # once we fully implement dir layout, we can drop this
23461         umount_client $MOUNT || error "umount failed"
23462         mount_client $MOUNT || error "mount failed"
23463
23464         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23465         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23466         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23467
23468         #set the stripe to be unknown hash type
23469         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23470         $LCTL set_param fail_loc=0x1901
23471         for ((i = 0; i < 10; i++)); do
23472                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23473                         error "stat f-$i failed"
23474                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23475         done
23476
23477         touch $DIR/$tdir/striped_dir/f0 &&
23478                 error "create under striped dir with unknown hash should fail"
23479
23480         $LCTL set_param fail_loc=0
23481
23482         umount_client $MOUNT || error "umount failed"
23483         mount_client $MOUNT || error "mount failed"
23484
23485         return 0
23486 }
23487 run_test 300i "client handle unknown hash type striped directory"
23488
23489 test_300j() {
23490         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23492         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23493                 skip "Need MDS version at least 2.7.55"
23494
23495         local stripe_count
23496         local file
23497
23498         mkdir $DIR/$tdir
23499
23500         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23501         $LCTL set_param fail_loc=0x1702
23502         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23503                 error "set striped dir error"
23504
23505         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23506                 error "create files under striped dir failed"
23507
23508         $LCTL set_param fail_loc=0
23509
23510         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23511
23512         return 0
23513 }
23514 run_test 300j "test large update record"
23515
23516 test_300k() {
23517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23518         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23519         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23520                 skip "Need MDS version at least 2.7.55"
23521
23522         # this test needs a huge transaction
23523         local kb
23524         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23525              osd*.$FSNAME-MDT0000.kbytestotal")
23526         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23527
23528         local stripe_count
23529         local file
23530
23531         mkdir $DIR/$tdir
23532
23533         #define OBD_FAIL_LARGE_STRIPE   0x1703
23534         $LCTL set_param fail_loc=0x1703
23535         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23536                 error "set striped dir error"
23537         $LCTL set_param fail_loc=0
23538
23539         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23540                 error "getstripeddir fails"
23541         rm -rf $DIR/$tdir/striped_dir ||
23542                 error "unlink striped dir fails"
23543
23544         return 0
23545 }
23546 run_test 300k "test large striped directory"
23547
23548 test_300l() {
23549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23550         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23551         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23552                 skip "Need MDS version at least 2.7.55"
23553
23554         local stripe_index
23555
23556         test_mkdir -p $DIR/$tdir/striped_dir
23557         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23558                         error "chown $RUNAS_ID failed"
23559         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23560                 error "set default striped dir failed"
23561
23562         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23563         $LCTL set_param fail_loc=0x80000158
23564         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23565
23566         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23567         [ $stripe_index -eq 1 ] ||
23568                 error "expect 1 get $stripe_index for $dir"
23569 }
23570 run_test 300l "non-root user to create dir under striped dir with stale layout"
23571
23572 test_300m() {
23573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23574         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23575         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23576                 skip "Need MDS version at least 2.7.55"
23577
23578         mkdir -p $DIR/$tdir/striped_dir
23579         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23580                 error "set default stripes dir error"
23581
23582         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23583
23584         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23585         [ $stripe_count -eq 0 ] ||
23586                         error "expect 0 get $stripe_count for a"
23587
23588         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23589                 error "set default stripes dir error"
23590
23591         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23592
23593         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23594         [ $stripe_count -eq 0 ] ||
23595                         error "expect 0 get $stripe_count for b"
23596
23597         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23598                 error "set default stripes dir error"
23599
23600         mkdir $DIR/$tdir/striped_dir/c &&
23601                 error "default stripe_index is invalid, mkdir c should fails"
23602
23603         rm -rf $DIR/$tdir || error "rmdir fails"
23604 }
23605 run_test 300m "setstriped directory on single MDT FS"
23606
23607 cleanup_300n() {
23608         local list=$(comma_list $(mdts_nodes))
23609
23610         trap 0
23611         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23612 }
23613
23614 test_300n() {
23615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23616         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23617         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23618                 skip "Need MDS version at least 2.7.55"
23619         remote_mds_nodsh && skip "remote MDS with nodsh"
23620
23621         local stripe_index
23622         local list=$(comma_list $(mdts_nodes))
23623
23624         trap cleanup_300n RETURN EXIT
23625         mkdir -p $DIR/$tdir
23626         chmod 777 $DIR/$tdir
23627         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23628                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23629                 error "create striped dir succeeds with gid=0"
23630
23631         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23632         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23633                 error "create striped dir fails with gid=-1"
23634
23635         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23636         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23637                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23638                 error "set default striped dir succeeds with gid=0"
23639
23640
23641         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23642         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23643                 error "set default striped dir fails with gid=-1"
23644
23645
23646         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23647         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23648                                         error "create test_dir fails"
23649         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23650                                         error "create test_dir1 fails"
23651         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23652                                         error "create test_dir2 fails"
23653         cleanup_300n
23654 }
23655 run_test 300n "non-root user to create dir under striped dir with default EA"
23656
23657 test_300o() {
23658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23659         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23660         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23661                 skip "Need MDS version at least 2.7.55"
23662
23663         local numfree1
23664         local numfree2
23665
23666         mkdir -p $DIR/$tdir
23667
23668         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23669         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23670         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23671                 skip "not enough free inodes $numfree1 $numfree2"
23672         fi
23673
23674         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23675         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23676         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23677                 skip "not enough free space $numfree1 $numfree2"
23678         fi
23679
23680         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23681                 error "setdirstripe fails"
23682
23683         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23684                 error "create dirs fails"
23685
23686         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23687         ls $DIR/$tdir/striped_dir > /dev/null ||
23688                 error "ls striped dir fails"
23689         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23690                 error "unlink big striped dir fails"
23691 }
23692 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23693
23694 test_300p() {
23695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23696         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23697         remote_mds_nodsh && skip "remote MDS with nodsh"
23698
23699         mkdir_on_mdt0 $DIR/$tdir
23700
23701         #define OBD_FAIL_OUT_ENOSPC     0x1704
23702         do_facet mds2 lctl set_param fail_loc=0x80001704
23703         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23704                  && error "create striped directory should fail"
23705
23706         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23707
23708         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23709         true
23710 }
23711 run_test 300p "create striped directory without space"
23712
23713 test_300q() {
23714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23715         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23716
23717         local fd=$(free_fd)
23718         local cmd="exec $fd<$tdir"
23719         cd $DIR
23720         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23721         eval $cmd
23722         cmd="exec $fd<&-"
23723         trap "eval $cmd" EXIT
23724         cd $tdir || error "cd $tdir fails"
23725         rmdir  ../$tdir || error "rmdir $tdir fails"
23726         mkdir local_dir && error "create dir succeeds"
23727         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23728         eval $cmd
23729         return 0
23730 }
23731 run_test 300q "create remote directory under orphan directory"
23732
23733 test_300r() {
23734         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23735                 skip "Need MDS version at least 2.7.55" && return
23736         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23737
23738         mkdir $DIR/$tdir
23739
23740         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23741                 error "set striped dir error"
23742
23743         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23744                 error "getstripeddir fails"
23745
23746         local stripe_count
23747         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23748                       awk '/lmv_stripe_count:/ { print $2 }')
23749
23750         [ $MDSCOUNT -ne $stripe_count ] &&
23751                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23752
23753         rm -rf $DIR/$tdir/striped_dir ||
23754                 error "unlink striped dir fails"
23755 }
23756 run_test 300r "test -1 striped directory"
23757
23758 test_300s_helper() {
23759         local count=$1
23760
23761         local stripe_dir=$DIR/$tdir/striped_dir.$count
23762
23763         $LFS mkdir -c $count $stripe_dir ||
23764                 error "lfs mkdir -c error"
23765
23766         $LFS getdirstripe $stripe_dir ||
23767                 error "lfs getdirstripe fails"
23768
23769         local stripe_count
23770         stripe_count=$($LFS getdirstripe $stripe_dir |
23771                       awk '/lmv_stripe_count:/ { print $2 }')
23772
23773         [ $count -ne $stripe_count ] &&
23774                 error_noexit "bad stripe count $stripe_count expected $count"
23775
23776         local dupe_stripes
23777         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23778                 awk '/0x/ {count[$1] += 1}; END {
23779                         for (idx in count) {
23780                                 if (count[idx]>1) {
23781                                         print "index " idx " count " count[idx]
23782                                 }
23783                         }
23784                 }')
23785
23786         if [[ -n "$dupe_stripes" ]] ; then
23787                 lfs getdirstripe $stripe_dir
23788                 error_noexit "Dupe MDT above: $dupe_stripes "
23789         fi
23790
23791         rm -rf $stripe_dir ||
23792                 error_noexit "unlink $stripe_dir fails"
23793 }
23794
23795 test_300s() {
23796         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23797                 skip "Need MDS version at least 2.7.55" && return
23798         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23799
23800         mkdir $DIR/$tdir
23801         for count in $(seq 2 $MDSCOUNT); do
23802                 test_300s_helper $count
23803         done
23804 }
23805 run_test 300s "test lfs mkdir -c without -i"
23806
23807 test_300t() {
23808         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
23809                 skip "need MDS 2.14.55 or later"
23810         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
23811
23812         local testdir="$DIR/$tdir/striped_dir"
23813         local dir1=$testdir/dir1
23814         local dir2=$testdir/dir2
23815
23816         mkdir -p $testdir
23817
23818         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
23819                 error "failed to set default stripe count for $testdir"
23820
23821         mkdir $dir1
23822         local stripe_count=$($LFS getdirstripe -c $dir1)
23823
23824         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
23825
23826         local max_count=$((MDSCOUNT - 1))
23827         local mdts=$(comma_list $(mdts_nodes))
23828
23829         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
23830         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
23831
23832         mkdir $dir2
23833         stripe_count=$($LFS getdirstripe -c $dir2)
23834
23835         (( $stripe_count == $max_count )) || error "wrong stripe count"
23836 }
23837 run_test 300t "test max_mdt_stripecount"
23838
23839 prepare_remote_file() {
23840         mkdir $DIR/$tdir/src_dir ||
23841                 error "create remote source failed"
23842
23843         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23844                  error "cp to remote source failed"
23845         touch $DIR/$tdir/src_dir/a
23846
23847         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23848                 error "create remote target dir failed"
23849
23850         touch $DIR/$tdir/tgt_dir/b
23851
23852         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23853                 error "rename dir cross MDT failed!"
23854
23855         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23856                 error "src_child still exists after rename"
23857
23858         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23859                 error "missing file(a) after rename"
23860
23861         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23862                 error "diff after rename"
23863 }
23864
23865 test_310a() {
23866         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23868
23869         local remote_file=$DIR/$tdir/tgt_dir/b
23870
23871         mkdir -p $DIR/$tdir
23872
23873         prepare_remote_file || error "prepare remote file failed"
23874
23875         #open-unlink file
23876         $OPENUNLINK $remote_file $remote_file ||
23877                 error "openunlink $remote_file failed"
23878         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23879 }
23880 run_test 310a "open unlink remote file"
23881
23882 test_310b() {
23883         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23885
23886         local remote_file=$DIR/$tdir/tgt_dir/b
23887
23888         mkdir -p $DIR/$tdir
23889
23890         prepare_remote_file || error "prepare remote file failed"
23891
23892         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23893         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23894         $CHECKSTAT -t file $remote_file || error "check file failed"
23895 }
23896 run_test 310b "unlink remote file with multiple links while open"
23897
23898 test_310c() {
23899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23900         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23901
23902         local remote_file=$DIR/$tdir/tgt_dir/b
23903
23904         mkdir -p $DIR/$tdir
23905
23906         prepare_remote_file || error "prepare remote file failed"
23907
23908         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23909         multiop_bg_pause $remote_file O_uc ||
23910                         error "mulitop failed for remote file"
23911         MULTIPID=$!
23912         $MULTIOP $DIR/$tfile Ouc
23913         kill -USR1 $MULTIPID
23914         wait $MULTIPID
23915 }
23916 run_test 310c "open-unlink remote file with multiple links"
23917
23918 #LU-4825
23919 test_311() {
23920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23921         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23922         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23923                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23924         remote_mds_nodsh && skip "remote MDS with nodsh"
23925
23926         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23927         local mdts=$(comma_list $(mdts_nodes))
23928
23929         mkdir -p $DIR/$tdir
23930         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23931         createmany -o $DIR/$tdir/$tfile. 1000
23932
23933         # statfs data is not real time, let's just calculate it
23934         old_iused=$((old_iused + 1000))
23935
23936         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23937                         osp.*OST0000*MDT0000.create_count")
23938         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23939                                 osp.*OST0000*MDT0000.max_create_count")
23940         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23941
23942         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23943         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23944         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23945
23946         unlinkmany $DIR/$tdir/$tfile. 1000
23947
23948         do_nodes $mdts "$LCTL set_param -n \
23949                         osp.*OST0000*.max_create_count=$max_count"
23950         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23951                 do_nodes $mdts "$LCTL set_param -n \
23952                                 osp.*OST0000*.create_count=$count"
23953         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23954                         grep "=0" && error "create_count is zero"
23955
23956         local new_iused
23957         for i in $(seq 120); do
23958                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23959                 # system may be too busy to destroy all objs in time, use
23960                 # a somewhat small value to not fail autotest
23961                 [ $((old_iused - new_iused)) -gt 400 ] && break
23962                 sleep 1
23963         done
23964
23965         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23966         [ $((old_iused - new_iused)) -gt 400 ] ||
23967                 error "objs not destroyed after unlink"
23968 }
23969 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23970
23971 zfs_oid_to_objid()
23972 {
23973         local ost=$1
23974         local objid=$2
23975
23976         local vdevdir=$(dirname $(facet_vdevice $ost))
23977         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23978         local zfs_zapid=$(do_facet $ost $cmd |
23979                           grep -w "/O/0/d$((objid%32))" -C 5 |
23980                           awk '/Object/{getline; print $1}')
23981         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23982                           awk "/$objid = /"'{printf $3}')
23983
23984         echo $zfs_objid
23985 }
23986
23987 zfs_object_blksz() {
23988         local ost=$1
23989         local objid=$2
23990
23991         local vdevdir=$(dirname $(facet_vdevice $ost))
23992         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23993         local blksz=$(do_facet $ost $cmd $objid |
23994                       awk '/dblk/{getline; printf $4}')
23995
23996         case "${blksz: -1}" in
23997                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23998                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23999                 *) ;;
24000         esac
24001
24002         echo $blksz
24003 }
24004
24005 test_312() { # LU-4856
24006         remote_ost_nodsh && skip "remote OST with nodsh"
24007         [ "$ost1_FSTYPE" = "zfs" ] ||
24008                 skip_env "the test only applies to zfs"
24009
24010         local max_blksz=$(do_facet ost1 \
24011                           $ZFS get -p recordsize $(facet_device ost1) |
24012                           awk '!/VALUE/{print $3}')
24013
24014         # to make life a little bit easier
24015         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24016         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24017
24018         local tf=$DIR/$tdir/$tfile
24019         touch $tf
24020         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24021
24022         # Get ZFS object id
24023         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24024         # block size change by sequential overwrite
24025         local bs
24026
24027         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24028                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24029
24030                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24031                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24032         done
24033         rm -f $tf
24034
24035         # block size change by sequential append write
24036         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24037         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24038         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24039         local count
24040
24041         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24042                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24043                         oflag=sync conv=notrunc
24044
24045                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24046                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24047                         error "blksz error, actual $blksz, " \
24048                                 "expected: 2 * $count * $PAGE_SIZE"
24049         done
24050         rm -f $tf
24051
24052         # random write
24053         touch $tf
24054         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24055         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24056
24057         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24058         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24059         [ $blksz -eq $PAGE_SIZE ] ||
24060                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24061
24062         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24063         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24064         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24065
24066         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24067         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24068         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24069 }
24070 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24071
24072 test_313() {
24073         remote_ost_nodsh && skip "remote OST with nodsh"
24074
24075         local file=$DIR/$tfile
24076
24077         rm -f $file
24078         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24079
24080         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24081         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24082         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24083                 error "write should failed"
24084         do_facet ost1 "$LCTL set_param fail_loc=0"
24085         rm -f $file
24086 }
24087 run_test 313 "io should fail after last_rcvd update fail"
24088
24089 test_314() {
24090         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24091
24092         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24093         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24094         rm -f $DIR/$tfile
24095         wait_delete_completed
24096         do_facet ost1 "$LCTL set_param fail_loc=0"
24097 }
24098 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24099
24100 test_315() { # LU-618
24101         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24102
24103         local file=$DIR/$tfile
24104         rm -f $file
24105
24106         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24107                 error "multiop file write failed"
24108         $MULTIOP $file oO_RDONLY:r4063232_c &
24109         PID=$!
24110
24111         sleep 2
24112
24113         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24114         kill -USR1 $PID
24115
24116         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24117         rm -f $file
24118 }
24119 run_test 315 "read should be accounted"
24120
24121 test_316() {
24122         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24123         large_xattr_enabled || skip_env "ea_inode feature disabled"
24124
24125         rm -rf $DIR/$tdir/d
24126         mkdir -p $DIR/$tdir/d
24127         chown nobody $DIR/$tdir/d
24128         touch $DIR/$tdir/d/file
24129
24130         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
24131 }
24132 run_test 316 "lfs mv"
24133
24134 test_317() {
24135         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24136                 skip "Need MDS version at least 2.11.53"
24137         if [ "$ost1_FSTYPE" == "zfs" ]; then
24138                 skip "LU-10370: no implementation for ZFS"
24139         fi
24140
24141         local trunc_sz
24142         local grant_blk_size
24143
24144         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24145                         awk '/grant_block_size:/ { print $2; exit; }')
24146         #
24147         # Create File of size 5M. Truncate it to below size's and verify
24148         # blocks count.
24149         #
24150         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24151                 error "Create file $DIR/$tfile failed"
24152         stack_trap "rm -f $DIR/$tfile" EXIT
24153
24154         for trunc_sz in 2097152 4097 4000 509 0; do
24155                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24156                         error "truncate $tfile to $trunc_sz failed"
24157                 local sz=$(stat --format=%s $DIR/$tfile)
24158                 local blk=$(stat --format=%b $DIR/$tfile)
24159                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24160                                      grant_blk_size) * 8))
24161
24162                 if [[ $blk -ne $trunc_blk ]]; then
24163                         $(which stat) $DIR/$tfile
24164                         error "Expected Block $trunc_blk got $blk for $tfile"
24165                 fi
24166
24167                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24168                         error "Expected Size $trunc_sz got $sz for $tfile"
24169         done
24170
24171         #
24172         # sparse file test
24173         # Create file with a hole and write actual 65536 bytes which aligned
24174         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24175         #
24176         local bs=65536
24177         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24178                 error "Create file : $DIR/$tfile"
24179
24180         #
24181         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24182         # blocks. The block count must drop to 8.
24183         #
24184         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - \
24185                 ((bs - grant_blk_size) + 1)))
24186         $TRUNCATE $DIR/$tfile $trunc_sz ||
24187                 error "truncate $tfile to $trunc_sz failed"
24188
24189         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24190         sz=$(stat --format=%s $DIR/$tfile)
24191         blk=$(stat --format=%b $DIR/$tfile)
24192
24193         if [[ $blk -ne $trunc_bsz ]]; then
24194                 $(which stat) $DIR/$tfile
24195                 error "Expected Block $trunc_bsz got $blk for $tfile"
24196         fi
24197
24198         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24199                 error "Expected Size $trunc_sz got $sz for $tfile"
24200 }
24201 run_test 317 "Verify blocks get correctly update after truncate"
24202
24203 test_318() {
24204         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24205         local old_max_active=$($LCTL get_param -n \
24206                             ${llite_name}.max_read_ahead_async_active \
24207                             2>/dev/null)
24208
24209         $LCTL set_param llite.*.max_read_ahead_async_active=256
24210         local max_active=$($LCTL get_param -n \
24211                            ${llite_name}.max_read_ahead_async_active \
24212                            2>/dev/null)
24213         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24214
24215         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24216                 error "set max_read_ahead_async_active should succeed"
24217
24218         $LCTL set_param llite.*.max_read_ahead_async_active=512
24219         max_active=$($LCTL get_param -n \
24220                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24221         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24222
24223         # restore @max_active
24224         [ $old_max_active -ne 0 ] && $LCTL set_param \
24225                 llite.*.max_read_ahead_async_active=$old_max_active
24226
24227         local old_threshold=$($LCTL get_param -n \
24228                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24229         local max_per_file_mb=$($LCTL get_param -n \
24230                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24231
24232         local invalid=$(($max_per_file_mb + 1))
24233         $LCTL set_param \
24234                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24235                         && error "set $invalid should fail"
24236
24237         local valid=$(($invalid - 1))
24238         $LCTL set_param \
24239                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24240                         error "set $valid should succeed"
24241         local threshold=$($LCTL get_param -n \
24242                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24243         [ $threshold -eq $valid ] || error \
24244                 "expect threshold $valid got $threshold"
24245         $LCTL set_param \
24246                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24247 }
24248 run_test 318 "Verify async readahead tunables"
24249
24250 test_319() {
24251         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
24252
24253         local before=$(date +%s)
24254         local evict
24255         local mdir=$DIR/$tdir
24256         local file=$mdir/xxx
24257
24258         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24259         touch $file
24260
24261 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24262         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24263         $LFS mv -m1 $file &
24264
24265         sleep 1
24266         dd if=$file of=/dev/null
24267         wait
24268         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24269           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24270
24271         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24272 }
24273 run_test 319 "lost lease lock on migrate error"
24274
24275 test_398a() { # LU-4198
24276         local ost1_imp=$(get_osc_import_name client ost1)
24277         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24278                          cut -d'.' -f2)
24279
24280         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24281         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24282
24283         # request a new lock on client
24284         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24285
24286         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24287         local lock_count=$($LCTL get_param -n \
24288                            ldlm.namespaces.$imp_name.lru_size)
24289         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24290
24291         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24292
24293         # no lock cached, should use lockless IO and not enqueue new lock
24294         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24295         lock_count=$($LCTL get_param -n \
24296                      ldlm.namespaces.$imp_name.lru_size)
24297         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24298 }
24299 run_test 398a "direct IO should cancel lock otherwise lockless"
24300
24301 test_398b() { # LU-4198
24302         which fio || skip_env "no fio installed"
24303         $LFS setstripe -c -1 $DIR/$tfile
24304
24305         local size=12
24306         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24307
24308         local njobs=4
24309         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
24310         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24311                 --numjobs=$njobs --fallocate=none \
24312                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24313                 --filename=$DIR/$tfile &
24314         bg_pid=$!
24315
24316         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
24317         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
24318                 --numjobs=$njobs --fallocate=none \
24319                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24320                 --filename=$DIR/$tfile || true
24321         wait $bg_pid
24322
24323         rm -f $DIR/$tfile
24324 }
24325 run_test 398b "DIO and buffer IO race"
24326
24327 test_398c() { # LU-4198
24328         local ost1_imp=$(get_osc_import_name client ost1)
24329         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24330                          cut -d'.' -f2)
24331
24332         which fio || skip_env "no fio installed"
24333
24334         saved_debug=$($LCTL get_param -n debug)
24335         $LCTL set_param debug=0
24336
24337         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24338         ((size /= 1024)) # by megabytes
24339         ((size /= 2)) # write half of the OST at most
24340         [ $size -gt 40 ] && size=40 #reduce test time anyway
24341
24342         $LFS setstripe -c 1 $DIR/$tfile
24343
24344         # it seems like ldiskfs reserves more space than necessary if the
24345         # writing blocks are not mapped, so it extends the file firstly
24346         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24347         cancel_lru_locks osc
24348
24349         # clear and verify rpc_stats later
24350         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24351
24352         local njobs=4
24353         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24354         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24355                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24356                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24357                 --filename=$DIR/$tfile
24358         [ $? -eq 0 ] || error "fio write error"
24359
24360         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24361                 error "Locks were requested while doing AIO"
24362
24363         # get the percentage of 1-page I/O
24364         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24365                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24366                 awk '{print $7}')
24367         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24368
24369         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24370         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24371                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24372                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24373                 --filename=$DIR/$tfile
24374         [ $? -eq 0 ] || error "fio mixed read write error"
24375
24376         echo "AIO with large block size ${size}M"
24377         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24378                 --numjobs=1 --fallocate=none --ioengine=libaio \
24379                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24380                 --filename=$DIR/$tfile
24381         [ $? -eq 0 ] || error "fio large block size failed"
24382
24383         rm -f $DIR/$tfile
24384         $LCTL set_param debug="$saved_debug"
24385 }
24386 run_test 398c "run fio to test AIO"
24387
24388 test_398d() { #  LU-13846
24389         which aiocp || skip_env "no aiocp installed"
24390         local aio_file=$DIR/$tfile.aio
24391
24392         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24393
24394         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24395         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24396         stack_trap "rm -f $DIR/$tfile $aio_file"
24397
24398         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24399
24400         # make sure we don't crash and fail properly
24401         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24402                 error "aio not aligned with PAGE SIZE should fail"
24403
24404         rm -f $DIR/$tfile $aio_file
24405 }
24406 run_test 398d "run aiocp to verify block size > stripe size"
24407
24408 test_398e() {
24409         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24410         touch $DIR/$tfile.new
24411         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24412 }
24413 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24414
24415 test_398f() { #  LU-14687
24416         which aiocp || skip_env "no aiocp installed"
24417         local aio_file=$DIR/$tfile.aio
24418
24419         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24420
24421         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24422         stack_trap "rm -f $DIR/$tfile $aio_file"
24423
24424         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24425         $LCTL set_param fail_loc=0x1418
24426         # make sure we don't crash and fail properly
24427         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24428                 error "aio with page allocation failure succeeded"
24429         $LCTL set_param fail_loc=0
24430         diff $DIR/$tfile $aio_file
24431         [[ $? != 0 ]] || error "no diff after failed aiocp"
24432 }
24433 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24434
24435 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24436 # stripe and i/o size must be > stripe size
24437 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24438 # single RPC in flight.  This test shows async DIO submission is working by
24439 # showing multiple RPCs in flight.
24440 test_398g() { #  LU-13798
24441         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24442
24443         # We need to do some i/o first to acquire enough grant to put our RPCs
24444         # in flight; otherwise a new connection may not have enough grant
24445         # available
24446         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24447                 error "parallel dio failed"
24448         stack_trap "rm -f $DIR/$tfile"
24449
24450         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24451         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24452         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24453         stack_trap "$LCTL set_param -n $pages_per_rpc"
24454
24455         # Recreate file so it's empty
24456         rm -f $DIR/$tfile
24457         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24458         #Pause rpc completion to guarantee we see multiple rpcs in flight
24459         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24460         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24461         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24462
24463         # Clear rpc stats
24464         $LCTL set_param osc.*.rpc_stats=c
24465
24466         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24467                 error "parallel dio failed"
24468         stack_trap "rm -f $DIR/$tfile"
24469
24470         $LCTL get_param osc.*-OST0000-*.rpc_stats
24471         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24472                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24473                 grep "8:" | awk '{print $8}')
24474         # We look at the "8 rpcs in flight" field, and verify A) it is present
24475         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24476         # as expected for an 8M DIO to a file with 1M stripes.
24477         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24478
24479         # Verify turning off parallel dio works as expected
24480         # Clear rpc stats
24481         $LCTL set_param osc.*.rpc_stats=c
24482         $LCTL set_param llite.*.parallel_dio=0
24483         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24484
24485         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24486                 error "dio with parallel dio disabled failed"
24487
24488         # Ideally, we would see only one RPC in flight here, but there is an
24489         # unavoidable race between i/o completion and RPC in flight counting,
24490         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24491         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24492         # So instead we just verify it's always < 8.
24493         $LCTL get_param osc.*-OST0000-*.rpc_stats
24494         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24495                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24496                 grep '^$' -B1 | grep . | awk '{print $1}')
24497         [ $ret != "8:" ] ||
24498                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24499 }
24500 run_test 398g "verify parallel dio async RPC submission"
24501
24502 test_398h() { #  LU-13798
24503         local dio_file=$DIR/$tfile.dio
24504
24505         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24506
24507         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24508         stack_trap "rm -f $DIR/$tfile $dio_file"
24509
24510         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24511                 error "parallel dio failed"
24512         diff $DIR/$tfile $dio_file
24513         [[ $? == 0 ]] || error "file diff after aiocp"
24514 }
24515 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24516
24517 test_398i() { #  LU-13798
24518         local dio_file=$DIR/$tfile.dio
24519
24520         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24521
24522         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24523         stack_trap "rm -f $DIR/$tfile $dio_file"
24524
24525         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24526         $LCTL set_param fail_loc=0x1418
24527         # make sure we don't crash and fail properly
24528         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24529                 error "parallel dio page allocation failure succeeded"
24530         diff $DIR/$tfile $dio_file
24531         [[ $? != 0 ]] || error "no diff after failed aiocp"
24532 }
24533 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24534
24535 test_398j() { #  LU-13798
24536         # Stripe size > RPC size but less than i/o size tests split across
24537         # stripes and RPCs for individual i/o op
24538         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24539
24540         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24541         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24542         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24543         stack_trap "$LCTL set_param -n $pages_per_rpc"
24544
24545         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24546                 error "parallel dio write failed"
24547         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24548
24549         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24550                 error "parallel dio read failed"
24551         diff $DIR/$tfile $DIR/$tfile.2
24552         [[ $? == 0 ]] || error "file diff after parallel dio read"
24553 }
24554 run_test 398j "test parallel dio where stripe size > rpc_size"
24555
24556 test_398k() { #  LU-13798
24557         wait_delete_completed
24558         wait_mds_ost_sync
24559
24560         # 4 stripe file; we will cause out of space on OST0
24561         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24562
24563         # Fill OST0 (if it's not too large)
24564         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24565                    head -n1)
24566         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24567                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24568         fi
24569         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24570         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24571                 error "dd should fill OST0"
24572         stack_trap "rm -f $DIR/$tfile.1"
24573
24574         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24575         err=$?
24576
24577         ls -la $DIR/$tfile
24578         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24579                 error "file is not 0 bytes in size"
24580
24581         # dd above should not succeed, but don't error until here so we can
24582         # get debug info above
24583         [[ $err != 0 ]] ||
24584                 error "parallel dio write with enospc succeeded"
24585         stack_trap "rm -f $DIR/$tfile"
24586 }
24587 run_test 398k "test enospc on first stripe"
24588
24589 test_398l() { #  LU-13798
24590         wait_delete_completed
24591         wait_mds_ost_sync
24592
24593         # 4 stripe file; we will cause out of space on OST0
24594         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24595         # happens on the second i/o chunk we issue
24596         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24597
24598         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24599         stack_trap "rm -f $DIR/$tfile"
24600
24601         # Fill OST0 (if it's not too large)
24602         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24603                    head -n1)
24604         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24605                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24606         fi
24607         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24608         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24609                 error "dd should fill OST0"
24610         stack_trap "rm -f $DIR/$tfile.1"
24611
24612         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24613         err=$?
24614         stack_trap "rm -f $DIR/$tfile.2"
24615
24616         # Check that short write completed as expected
24617         ls -la $DIR/$tfile.2
24618         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24619                 error "file is not 1M in size"
24620
24621         # dd above should not succeed, but don't error until here so we can
24622         # get debug info above
24623         [[ $err != 0 ]] ||
24624                 error "parallel dio write with enospc succeeded"
24625
24626         # Truncate source file to same length as output file and diff them
24627         $TRUNCATE $DIR/$tfile 1048576
24628         diff $DIR/$tfile $DIR/$tfile.2
24629         [[ $? == 0 ]] || error "data incorrect after short write"
24630 }
24631 run_test 398l "test enospc on intermediate stripe/RPC"
24632
24633 test_398m() { #  LU-13798
24634         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24635
24636         # Set up failure on OST0, the first stripe:
24637         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24638         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24639         # So this fail_val specifies OST0
24640         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24641         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24642
24643         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24644                 error "parallel dio write with failure on first stripe succeeded"
24645         stack_trap "rm -f $DIR/$tfile"
24646         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24647
24648         # Place data in file for read
24649         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24650                 error "parallel dio write failed"
24651
24652         # Fail read on OST0, first stripe
24653         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24654         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24655         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24656                 error "parallel dio read with error on first stripe succeeded"
24657         rm -f $DIR/$tfile.2
24658         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24659
24660         # Switch to testing on OST1, second stripe
24661         # Clear file contents, maintain striping
24662         echo > $DIR/$tfile
24663         # Set up failure on OST1, second stripe:
24664         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24665         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24666
24667         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24668                 error "parallel dio write with failure on first stripe succeeded"
24669         stack_trap "rm -f $DIR/$tfile"
24670         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24671
24672         # Place data in file for read
24673         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24674                 error "parallel dio write failed"
24675
24676         # Fail read on OST1, second stripe
24677         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24678         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24679         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24680                 error "parallel dio read with error on first stripe succeeded"
24681         rm -f $DIR/$tfile.2
24682         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24683 }
24684 run_test 398m "test RPC failures with parallel dio"
24685
24686 # Parallel submission of DIO should not cause problems for append, but it's
24687 # important to verify.
24688 test_398n() { #  LU-13798
24689         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24690
24691         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24692                 error "dd to create source file failed"
24693         stack_trap "rm -f $DIR/$tfile"
24694
24695         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24696                 error "parallel dio write with failure on second stripe succeeded"
24697         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24698         diff $DIR/$tfile $DIR/$tfile.1
24699         [[ $? == 0 ]] || error "data incorrect after append"
24700
24701 }
24702 run_test 398n "test append with parallel DIO"
24703
24704 test_fake_rw() {
24705         local read_write=$1
24706         if [ "$read_write" = "write" ]; then
24707                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24708         elif [ "$read_write" = "read" ]; then
24709                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24710         else
24711                 error "argument error"
24712         fi
24713
24714         # turn off debug for performance testing
24715         local saved_debug=$($LCTL get_param -n debug)
24716         $LCTL set_param debug=0
24717
24718         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24719
24720         # get ost1 size - $FSNAME-OST0000
24721         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24722         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24723         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24724
24725         if [ "$read_write" = "read" ]; then
24726                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24727         fi
24728
24729         local start_time=$(date +%s.%N)
24730         $dd_cmd bs=1M count=$blocks oflag=sync ||
24731                 error "real dd $read_write error"
24732         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24733
24734         if [ "$read_write" = "write" ]; then
24735                 rm -f $DIR/$tfile
24736         fi
24737
24738         # define OBD_FAIL_OST_FAKE_RW           0x238
24739         do_facet ost1 $LCTL set_param fail_loc=0x238
24740
24741         local start_time=$(date +%s.%N)
24742         $dd_cmd bs=1M count=$blocks oflag=sync ||
24743                 error "fake dd $read_write error"
24744         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24745
24746         if [ "$read_write" = "write" ]; then
24747                 # verify file size
24748                 cancel_lru_locks osc
24749                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24750                         error "$tfile size not $blocks MB"
24751         fi
24752         do_facet ost1 $LCTL set_param fail_loc=0
24753
24754         echo "fake $read_write $duration_fake vs. normal $read_write" \
24755                 "$duration in seconds"
24756         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24757                 error_not_in_vm "fake write is slower"
24758
24759         $LCTL set_param -n debug="$saved_debug"
24760         rm -f $DIR/$tfile
24761 }
24762 test_399a() { # LU-7655 for OST fake write
24763         remote_ost_nodsh && skip "remote OST with nodsh"
24764
24765         test_fake_rw write
24766 }
24767 run_test 399a "fake write should not be slower than normal write"
24768
24769 test_399b() { # LU-8726 for OST fake read
24770         remote_ost_nodsh && skip "remote OST with nodsh"
24771         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24772                 skip_env "ldiskfs only test"
24773         fi
24774
24775         test_fake_rw read
24776 }
24777 run_test 399b "fake read should not be slower than normal read"
24778
24779 test_400a() { # LU-1606, was conf-sanity test_74
24780         if ! which $CC > /dev/null 2>&1; then
24781                 skip_env "$CC is not installed"
24782         fi
24783
24784         local extra_flags=''
24785         local out=$TMP/$tfile
24786         local prefix=/usr/include/lustre
24787         local prog
24788
24789         # Oleg removes c files in his test rig so test if any c files exist
24790         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24791                 skip_env "Needed c test files are missing"
24792
24793         if ! [[ -d $prefix ]]; then
24794                 # Assume we're running in tree and fixup the include path.
24795                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24796                 extra_flags+=" -L$LUSTRE/utils/.lib"
24797         fi
24798
24799         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24800                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24801                         error "client api broken"
24802         done
24803         rm -f $out
24804 }
24805 run_test 400a "Lustre client api program can compile and link"
24806
24807 test_400b() { # LU-1606, LU-5011
24808         local header
24809         local out=$TMP/$tfile
24810         local prefix=/usr/include/linux/lustre
24811
24812         # We use a hard coded prefix so that this test will not fail
24813         # when run in tree. There are headers in lustre/include/lustre/
24814         # that are not packaged (like lustre_idl.h) and have more
24815         # complicated include dependencies (like config.h and lnet/types.h).
24816         # Since this test about correct packaging we just skip them when
24817         # they don't exist (see below) rather than try to fixup cppflags.
24818
24819         if ! which $CC > /dev/null 2>&1; then
24820                 skip_env "$CC is not installed"
24821         fi
24822
24823         for header in $prefix/*.h; do
24824                 if ! [[ -f "$header" ]]; then
24825                         continue
24826                 fi
24827
24828                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24829                         continue # lustre_ioctl.h is internal header
24830                 fi
24831
24832                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24833                         error "cannot compile '$header'"
24834         done
24835         rm -f $out
24836 }
24837 run_test 400b "packaged headers can be compiled"
24838
24839 test_401a() { #LU-7437
24840         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24841         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24842
24843         #count the number of parameters by "list_param -R"
24844         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24845         #count the number of parameters by listing proc files
24846         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24847         echo "proc_dirs='$proc_dirs'"
24848         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24849         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24850                       sort -u | wc -l)
24851
24852         [ $params -eq $procs ] ||
24853                 error "found $params parameters vs. $procs proc files"
24854
24855         # test the list_param -D option only returns directories
24856         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24857         #count the number of parameters by listing proc directories
24858         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24859                 sort -u | wc -l)
24860
24861         [ $params -eq $procs ] ||
24862                 error "found $params parameters vs. $procs proc files"
24863 }
24864 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24865
24866 test_401b() {
24867         # jobid_var may not allow arbitrary values, so use jobid_name
24868         # if available
24869         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24870                 local testname=jobid_name tmp='testing%p'
24871         else
24872                 local testname=jobid_var tmp=testing
24873         fi
24874
24875         local save=$($LCTL get_param -n $testname)
24876
24877         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24878                 error "no error returned when setting bad parameters"
24879
24880         local jobid_new=$($LCTL get_param -n foe $testname baz)
24881         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24882
24883         $LCTL set_param -n fog=bam $testname=$save bat=fog
24884         local jobid_old=$($LCTL get_param -n foe $testname bag)
24885         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24886 }
24887 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24888
24889 test_401c() {
24890         # jobid_var may not allow arbitrary values, so use jobid_name
24891         # if available
24892         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24893                 local testname=jobid_name
24894         else
24895                 local testname=jobid_var
24896         fi
24897
24898         local jobid_var_old=$($LCTL get_param -n $testname)
24899         local jobid_var_new
24900
24901         $LCTL set_param $testname= &&
24902                 error "no error returned for 'set_param a='"
24903
24904         jobid_var_new=$($LCTL get_param -n $testname)
24905         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24906                 error "$testname was changed by setting without value"
24907
24908         $LCTL set_param $testname &&
24909                 error "no error returned for 'set_param a'"
24910
24911         jobid_var_new=$($LCTL get_param -n $testname)
24912         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24913                 error "$testname was changed by setting without value"
24914 }
24915 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24916
24917 test_401d() {
24918         # jobid_var may not allow arbitrary values, so use jobid_name
24919         # if available
24920         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24921                 local testname=jobid_name new_value='foo=bar%p'
24922         else
24923                 local testname=jobid_var new_valuie=foo=bar
24924         fi
24925
24926         local jobid_var_old=$($LCTL get_param -n $testname)
24927         local jobid_var_new
24928
24929         $LCTL set_param $testname=$new_value ||
24930                 error "'set_param a=b' did not accept a value containing '='"
24931
24932         jobid_var_new=$($LCTL get_param -n $testname)
24933         [[ "$jobid_var_new" == "$new_value" ]] ||
24934                 error "'set_param a=b' failed on a value containing '='"
24935
24936         # Reset the $testname to test the other format
24937         $LCTL set_param $testname=$jobid_var_old
24938         jobid_var_new=$($LCTL get_param -n $testname)
24939         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24940                 error "failed to reset $testname"
24941
24942         $LCTL set_param $testname $new_value ||
24943                 error "'set_param a b' did not accept a value containing '='"
24944
24945         jobid_var_new=$($LCTL get_param -n $testname)
24946         [[ "$jobid_var_new" == "$new_value" ]] ||
24947                 error "'set_param a b' failed on a value containing '='"
24948
24949         $LCTL set_param $testname $jobid_var_old
24950         jobid_var_new=$($LCTL get_param -n $testname)
24951         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24952                 error "failed to reset $testname"
24953 }
24954 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24955
24956 test_401e() { # LU-14779
24957         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24958                 error "lctl list_param MGC* failed"
24959         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24960         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24961                 error "lctl get_param lru_size failed"
24962 }
24963 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24964
24965 test_402() {
24966         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24967         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24968                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24969         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24970                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24971                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24972         remote_mds_nodsh && skip "remote MDS with nodsh"
24973
24974         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24975 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24976         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24977         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24978                 echo "Touch failed - OK"
24979 }
24980 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24981
24982 test_403() {
24983         local file1=$DIR/$tfile.1
24984         local file2=$DIR/$tfile.2
24985         local tfile=$TMP/$tfile
24986
24987         rm -f $file1 $file2 $tfile
24988
24989         touch $file1
24990         ln $file1 $file2
24991
24992         # 30 sec OBD_TIMEOUT in ll_getattr()
24993         # right before populating st_nlink
24994         $LCTL set_param fail_loc=0x80001409
24995         stat -c %h $file1 > $tfile &
24996
24997         # create an alias, drop all locks and reclaim the dentry
24998         < $file2
24999         cancel_lru_locks mdc
25000         cancel_lru_locks osc
25001         sysctl -w vm.drop_caches=2
25002
25003         wait
25004
25005         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25006
25007         rm -f $tfile $file1 $file2
25008 }
25009 run_test 403 "i_nlink should not drop to zero due to aliasing"
25010
25011 test_404() { # LU-6601
25012         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25013                 skip "Need server version newer than 2.8.52"
25014         remote_mds_nodsh && skip "remote MDS with nodsh"
25015
25016         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25017                 awk '/osp .*-osc-MDT/ { print $4}')
25018
25019         local osp
25020         for osp in $mosps; do
25021                 echo "Deactivate: " $osp
25022                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25023                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25024                         awk -vp=$osp '$4 == p { print $2 }')
25025                 [ $stat = IN ] || {
25026                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25027                         error "deactivate error"
25028                 }
25029                 echo "Activate: " $osp
25030                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25031                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25032                         awk -vp=$osp '$4 == p { print $2 }')
25033                 [ $stat = UP ] || {
25034                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25035                         error "activate error"
25036                 }
25037         done
25038 }
25039 run_test 404 "validate manual {de}activated works properly for OSPs"
25040
25041 test_405() {
25042         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25043         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25044                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25045                         skip "Layout swap lock is not supported"
25046
25047         check_swap_layouts_support
25048         check_swap_layout_no_dom $DIR
25049
25050         test_mkdir $DIR/$tdir
25051         swap_lock_test -d $DIR/$tdir ||
25052                 error "One layout swap locked test failed"
25053 }
25054 run_test 405 "Various layout swap lock tests"
25055
25056 test_406() {
25057         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25058         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25059         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25061         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25062                 skip "Need MDS version at least 2.8.50"
25063
25064         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25065         local test_pool=$TESTNAME
25066
25067         pool_add $test_pool || error "pool_add failed"
25068         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25069                 error "pool_add_targets failed"
25070
25071         save_layout_restore_at_exit $MOUNT
25072
25073         # parent set default stripe count only, child will stripe from both
25074         # parent and fs default
25075         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25076                 error "setstripe $MOUNT failed"
25077         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25078         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25079         for i in $(seq 10); do
25080                 local f=$DIR/$tdir/$tfile.$i
25081                 touch $f || error "touch failed"
25082                 local count=$($LFS getstripe -c $f)
25083                 [ $count -eq $OSTCOUNT ] ||
25084                         error "$f stripe count $count != $OSTCOUNT"
25085                 local offset=$($LFS getstripe -i $f)
25086                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25087                 local size=$($LFS getstripe -S $f)
25088                 [ $size -eq $((def_stripe_size * 2)) ] ||
25089                         error "$f stripe size $size != $((def_stripe_size * 2))"
25090                 local pool=$($LFS getstripe -p $f)
25091                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25092         done
25093
25094         # change fs default striping, delete parent default striping, now child
25095         # will stripe from new fs default striping only
25096         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25097                 error "change $MOUNT default stripe failed"
25098         $LFS setstripe -c 0 $DIR/$tdir ||
25099                 error "delete $tdir default stripe failed"
25100         for i in $(seq 11 20); do
25101                 local f=$DIR/$tdir/$tfile.$i
25102                 touch $f || error "touch $f failed"
25103                 local count=$($LFS getstripe -c $f)
25104                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25105                 local offset=$($LFS getstripe -i $f)
25106                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25107                 local size=$($LFS getstripe -S $f)
25108                 [ $size -eq $def_stripe_size ] ||
25109                         error "$f stripe size $size != $def_stripe_size"
25110                 local pool=$($LFS getstripe -p $f)
25111                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25112         done
25113
25114         unlinkmany $DIR/$tdir/$tfile. 1 20
25115
25116         local f=$DIR/$tdir/$tfile
25117         pool_remove_all_targets $test_pool $f
25118         pool_remove $test_pool $f
25119 }
25120 run_test 406 "DNE support fs default striping"
25121
25122 test_407() {
25123         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25124         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25125                 skip "Need MDS version at least 2.8.55"
25126         remote_mds_nodsh && skip "remote MDS with nodsh"
25127
25128         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25129                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25130         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25131                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25132         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25133
25134         #define OBD_FAIL_DT_TXN_STOP    0x2019
25135         for idx in $(seq $MDSCOUNT); do
25136                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25137         done
25138         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25139         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25140                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25141         true
25142 }
25143 run_test 407 "transaction fail should cause operation fail"
25144
25145 test_408() {
25146         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25147
25148         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25149         lctl set_param fail_loc=0x8000040a
25150         # let ll_prepare_partial_page() fail
25151         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25152
25153         rm -f $DIR/$tfile
25154
25155         # create at least 100 unused inodes so that
25156         # shrink_icache_memory(0) should not return 0
25157         touch $DIR/$tfile-{0..100}
25158         rm -f $DIR/$tfile-{0..100}
25159         sync
25160
25161         echo 2 > /proc/sys/vm/drop_caches
25162 }
25163 run_test 408 "drop_caches should not hang due to page leaks"
25164
25165 test_409()
25166 {
25167         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25168
25169         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25170         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25171         touch $DIR/$tdir/guard || error "(2) Fail to create"
25172
25173         local PREFIX=$(str_repeat 'A' 128)
25174         echo "Create 1K hard links start at $(date)"
25175         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25176                 error "(3) Fail to hard link"
25177
25178         echo "Links count should be right although linkEA overflow"
25179         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25180         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25181         [ $linkcount -eq 1001 ] ||
25182                 error "(5) Unexpected hard links count: $linkcount"
25183
25184         echo "List all links start at $(date)"
25185         ls -l $DIR/$tdir/foo > /dev/null ||
25186                 error "(6) Fail to list $DIR/$tdir/foo"
25187
25188         echo "Unlink hard links start at $(date)"
25189         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25190                 error "(7) Fail to unlink"
25191         echo "Unlink hard links finished at $(date)"
25192 }
25193 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25194
25195 test_410()
25196 {
25197         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25198                 skip "Need client version at least 2.9.59"
25199         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25200                 skip "Need MODULES build"
25201
25202         # Create a file, and stat it from the kernel
25203         local testfile=$DIR/$tfile
25204         touch $testfile
25205
25206         local run_id=$RANDOM
25207         local my_ino=$(stat --format "%i" $testfile)
25208
25209         # Try to insert the module. This will always fail as the
25210         # module is designed to not be inserted.
25211         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25212             &> /dev/null
25213
25214         # Anything but success is a test failure
25215         dmesg | grep -q \
25216             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25217             error "no inode match"
25218 }
25219 run_test 410 "Test inode number returned from kernel thread"
25220
25221 cleanup_test411_cgroup() {
25222         trap 0
25223         rmdir "$1"
25224 }
25225
25226 test_411() {
25227         local cg_basedir=/sys/fs/cgroup/memory
25228         # LU-9966
25229         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25230                 skip "no setup for cgroup"
25231
25232         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25233                 error "test file creation failed"
25234         cancel_lru_locks osc
25235
25236         # Create a very small memory cgroup to force a slab allocation error
25237         local cgdir=$cg_basedir/osc_slab_alloc
25238         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25239         trap "cleanup_test411_cgroup $cgdir" EXIT
25240         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25241         echo 1M > $cgdir/memory.limit_in_bytes
25242
25243         # Should not LBUG, just be killed by oom-killer
25244         # dd will return 0 even allocation failure in some environment.
25245         # So don't check return value
25246         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25247         cleanup_test411_cgroup $cgdir
25248
25249         return 0
25250 }
25251 run_test 411 "Slab allocation error with cgroup does not LBUG"
25252
25253 test_412() {
25254         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25255         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25256                 skip "Need server version at least 2.10.55"
25257
25258         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25259                 error "mkdir failed"
25260         $LFS getdirstripe $DIR/$tdir
25261         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25262         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25263                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25264         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25265         [ $stripe_count -eq 2 ] ||
25266                 error "expect 2 get $stripe_count"
25267
25268         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25269
25270         local index
25271         local index2
25272
25273         # subdirs should be on the same MDT as parent
25274         for i in $(seq 0 $((MDSCOUNT - 1))); do
25275                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25276                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25277                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25278                 (( index == i )) || error "mdt$i/sub on MDT$index"
25279         done
25280
25281         # stripe offset -1, ditto
25282         for i in {1..10}; do
25283                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25284                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25285                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25286                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25287                 (( index == index2 )) ||
25288                         error "qos$i on MDT$index, sub on MDT$index2"
25289         done
25290
25291         local testdir=$DIR/$tdir/inherit
25292
25293         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25294         # inherit 2 levels
25295         for i in 1 2; do
25296                 testdir=$testdir/s$i
25297                 mkdir $testdir || error "mkdir $testdir failed"
25298                 index=$($LFS getstripe -m $testdir)
25299                 (( index == 1 )) ||
25300                         error "$testdir on MDT$index"
25301         done
25302
25303         # not inherit any more
25304         testdir=$testdir/s3
25305         mkdir $testdir || error "mkdir $testdir failed"
25306         getfattr -d -m dmv $testdir | grep dmv &&
25307                 error "default LMV set on $testdir" || true
25308 }
25309 run_test 412 "mkdir on specific MDTs"
25310
25311 generate_uneven_mdts() {
25312         local threshold=$1
25313         local lmv_qos_maxage
25314         local lod_qos_maxage
25315         local ffree
25316         local bavail
25317         local max
25318         local min
25319         local max_index
25320         local min_index
25321         local tmp
25322         local i
25323
25324         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25325         $LCTL set_param lmv.*.qos_maxage=1
25326         stack_trap "$LCTL set_param \
25327                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25328         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25329                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25330         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25331                 lod.*.mdt_qos_maxage=1
25332         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25333                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25334
25335         echo
25336         echo "Check for uneven MDTs: "
25337
25338         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25339         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25340         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25341
25342         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25343         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25344         max_index=0
25345         min_index=0
25346         for ((i = 1; i < ${#ffree[@]}; i++)); do
25347                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25348                 if [ $tmp -gt $max ]; then
25349                         max=$tmp
25350                         max_index=$i
25351                 fi
25352                 if [ $tmp -lt $min ]; then
25353                         min=$tmp
25354                         min_index=$i
25355                 fi
25356         done
25357
25358         (( ${ffree[min_index]} > 0 )) ||
25359                 skip "no free files in MDT$min_index"
25360         (( ${ffree[min_index]} < 10000000 )) ||
25361                 skip "too many free files in MDT$min_index"
25362
25363         # Check if we need to generate uneven MDTs
25364         local diff=$(((max - min) * 100 / min))
25365         local testdir=$DIR/$tdir-fillmdt
25366         local start
25367
25368         mkdir -p $testdir
25369
25370         i=0
25371         while (( diff < threshold )); do
25372                 # generate uneven MDTs, create till $threshold% diff
25373                 echo -n "weight diff=$diff% must be > $threshold% ..."
25374                 echo "Fill MDT$min_index with 1000 files: loop $i"
25375                 testdir=$DIR/$tdir-fillmdt/$i
25376                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25377                         error "mkdir $testdir failed"
25378                 $LFS setstripe -E 1M -L mdt $testdir ||
25379                         error "setstripe $testdir failed"
25380                 start=$SECONDS
25381                 for F in f.{0..999}; do
25382                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25383                                 /dev/null 2>&1 || error "dd $F failed"
25384                 done
25385
25386                 # wait for QOS to update
25387                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25388
25389                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25390                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25391                 max=$(((${ffree[max_index]} >> 8) * \
25392                         (${bavail[max_index]} * bsize >> 16)))
25393                 min=$(((${ffree[min_index]} >> 8) * \
25394                         (${bavail[min_index]} * bsize >> 16)))
25395                 diff=$(((max - min) * 100 / min))
25396                 i=$((i + 1))
25397         done
25398
25399         echo "MDT filesfree available: ${ffree[@]}"
25400         echo "MDT blocks available: ${bavail[@]}"
25401         echo "weight diff=$diff%"
25402 }
25403
25404 test_qos_mkdir() {
25405         local mkdir_cmd=$1
25406         local stripe_count=$2
25407         local mdts=$(comma_list $(mdts_nodes))
25408
25409         local testdir
25410         local lmv_qos_prio_free
25411         local lmv_qos_threshold_rr
25412         local lmv_qos_maxage
25413         local lod_qos_prio_free
25414         local lod_qos_threshold_rr
25415         local lod_qos_maxage
25416         local count
25417         local i
25418
25419         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25420         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25421         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25422                 head -n1)
25423         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25424         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25425         stack_trap "$LCTL set_param \
25426                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25427         stack_trap "$LCTL set_param \
25428                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25429         stack_trap "$LCTL set_param \
25430                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25431
25432         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25433                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25434         lod_qos_prio_free=${lod_qos_prio_free%%%}
25435         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25436                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25437         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25438         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25439                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25440         stack_trap "do_nodes $mdts $LCTL set_param \
25441                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25442         stack_trap "do_nodes $mdts $LCTL set_param \
25443                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25444         stack_trap "do_nodes $mdts $LCTL set_param \
25445                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25446
25447         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25448         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25449
25450         testdir=$DIR/$tdir-s$stripe_count/rr
25451
25452         local stripe_index=$($LFS getstripe -m $testdir)
25453         local test_mkdir_rr=true
25454
25455         getfattr -d -m dmv -e hex $testdir | grep dmv
25456         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25457                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25458                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25459                         test_mkdir_rr=false
25460         fi
25461
25462         echo
25463         $test_mkdir_rr &&
25464                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25465                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25466
25467         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25468         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25469                 eval $mkdir_cmd $testdir/subdir$i ||
25470                         error "$mkdir_cmd subdir$i failed"
25471         done
25472
25473         for (( i = 0; i < $MDSCOUNT; i++ )); do
25474                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25475                 echo "$count directories created on MDT$i"
25476                 if $test_mkdir_rr; then
25477                         (( $count == 100 )) ||
25478                                 error "subdirs are not evenly distributed"
25479                 elif (( $i == $stripe_index )); then
25480                         (( $count == 100 * MDSCOUNT )) ||
25481                                 error "$count subdirs created on MDT$i"
25482                 else
25483                         (( $count == 0 )) ||
25484                                 error "$count subdirs created on MDT$i"
25485                 fi
25486
25487                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25488                         count=$($LFS getdirstripe $testdir/* |
25489                                 grep -c -P "^\s+$i\t")
25490                         echo "$count stripes created on MDT$i"
25491                         # deviation should < 5% of average
25492                         (( $count >= 95 * stripe_count &&
25493                            $count <= 105 * stripe_count)) ||
25494                                 error "stripes are not evenly distributed"
25495                 fi
25496         done
25497
25498         echo
25499         echo "Check for uneven MDTs: "
25500
25501         local ffree
25502         local bavail
25503         local max
25504         local min
25505         local max_index
25506         local min_index
25507         local tmp
25508
25509         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25510         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25511         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25512
25513         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25514         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25515         max_index=0
25516         min_index=0
25517         for ((i = 1; i < ${#ffree[@]}; i++)); do
25518                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25519                 if [ $tmp -gt $max ]; then
25520                         max=$tmp
25521                         max_index=$i
25522                 fi
25523                 if [ $tmp -lt $min ]; then
25524                         min=$tmp
25525                         min_index=$i
25526                 fi
25527         done
25528
25529         (( ${ffree[min_index]} > 0 )) ||
25530                 skip "no free files in MDT$min_index"
25531         (( ${ffree[min_index]} < 10000000 )) ||
25532                 skip "too many free files in MDT$min_index"
25533
25534         echo "MDT filesfree available: ${ffree[@]}"
25535         echo "MDT blocks available: ${bavail[@]}"
25536         echo "weight diff=$(((max - min) * 100 / min))%"
25537         echo
25538         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25539
25540         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25541         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25542         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25543         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25544         # decrease statfs age, so that it can be updated in time
25545         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25546         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25547
25548         sleep 1
25549
25550         testdir=$DIR/$tdir-s$stripe_count/qos
25551         local num=200
25552
25553         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25554         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25555                 eval $mkdir_cmd $testdir/subdir$i ||
25556                         error "$mkdir_cmd subdir$i failed"
25557         done
25558
25559         max=0
25560         for (( i = 0; i < $MDSCOUNT; i++ )); do
25561                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25562                 (( count > max )) && max=$count
25563                 echo "$count directories created on MDT$i"
25564         done
25565
25566         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25567
25568         # D-value should > 10% of averge
25569         (( max - min > num / 10 )) ||
25570                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25571
25572         # ditto for stripes
25573         if (( stripe_count > 1 )); then
25574                 max=0
25575                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25576                         count=$($LFS getdirstripe $testdir/* |
25577                                 grep -c -P "^\s+$i\t")
25578                         (( count > max )) && max=$count
25579                         echo "$count stripes created on MDT$i"
25580                 done
25581
25582                 min=$($LFS getdirstripe $testdir/* |
25583                         grep -c -P "^\s+$min_index\t")
25584                 (( max - min > num * stripe_count / 10 )) ||
25585                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25586         fi
25587 }
25588
25589 most_full_mdt() {
25590         local ffree
25591         local bavail
25592         local bsize
25593         local min
25594         local min_index
25595         local tmp
25596
25597         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25598         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25599         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25600
25601         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25602         min_index=0
25603         for ((i = 1; i < ${#ffree[@]}; i++)); do
25604                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25605                 (( tmp < min )) && min=$tmp && min_index=$i
25606         done
25607
25608         echo -n $min_index
25609 }
25610
25611 test_413a() {
25612         [ $MDSCOUNT -lt 2 ] &&
25613                 skip "We need at least 2 MDTs for this test"
25614
25615         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25616                 skip "Need server version at least 2.12.52"
25617
25618         local stripe_count
25619
25620         generate_uneven_mdts 100
25621         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25622                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25623                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25624                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25625                         error "mkdir failed"
25626                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25627         done
25628 }
25629 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25630
25631 test_413b() {
25632         [ $MDSCOUNT -lt 2 ] &&
25633                 skip "We need at least 2 MDTs for this test"
25634
25635         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25636                 skip "Need server version at least 2.12.52"
25637
25638         local testdir
25639         local stripe_count
25640
25641         generate_uneven_mdts 100
25642         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25643                 testdir=$DIR/$tdir-s$stripe_count
25644                 mkdir $testdir || error "mkdir $testdir failed"
25645                 mkdir $testdir/rr || error "mkdir rr failed"
25646                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25647                         error "mkdir qos failed"
25648                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25649                         $testdir/rr || error "setdirstripe rr failed"
25650                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25651                         error "setdirstripe failed"
25652                 test_qos_mkdir "mkdir" $stripe_count
25653         done
25654 }
25655 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25656
25657 test_413c() {
25658         (( $MDSCOUNT >= 2 )) ||
25659                 skip "We need at least 2 MDTs for this test"
25660
25661         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25662                 skip "Need server version at least 2.14.51"
25663
25664         local testdir
25665         local inherit
25666         local inherit_rr
25667
25668         testdir=$DIR/${tdir}-s1
25669         mkdir $testdir || error "mkdir $testdir failed"
25670         mkdir $testdir/rr || error "mkdir rr failed"
25671         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25672         # default max_inherit is -1, default max_inherit_rr is 0
25673         $LFS setdirstripe -D -c 1 $testdir/rr ||
25674                 error "setdirstripe rr failed"
25675         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25676                 error "setdirstripe qos failed"
25677         test_qos_mkdir "mkdir" 1
25678
25679         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25680         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25681         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25682         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25683         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25684
25685         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25686         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25687         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25688         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25689         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25690         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25691         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25692                 error "level2 shouldn't have default LMV" || true
25693 }
25694 run_test 413c "mkdir with default LMV max inherit rr"
25695
25696 test_413d() {
25697         (( MDSCOUNT >= 2 )) ||
25698                 skip "We need at least 2 MDTs for this test"
25699
25700         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25701                 skip "Need server version at least 2.14.51"
25702
25703         local lmv_qos_threshold_rr
25704
25705         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25706                 head -n1)
25707         stack_trap "$LCTL set_param \
25708                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25709
25710         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25711         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25712         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25713                 error "$tdir shouldn't have default LMV"
25714         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25715                 error "mkdir sub failed"
25716
25717         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25718
25719         (( count == 100 )) || error "$count subdirs on MDT0"
25720 }
25721 run_test 413d "inherit ROOT default LMV"
25722
25723 test_413e() {
25724         (( MDSCOUNT >= 2 )) ||
25725                 skip "We need at least 2 MDTs for this test"
25726         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25727                 skip "Need server version at least 2.14.55"
25728
25729         local testdir=$DIR/$tdir
25730         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25731         local max_inherit
25732         local sub_max_inherit
25733
25734         mkdir -p $testdir || error "failed to create $testdir"
25735
25736         # set default max-inherit to -1 if stripe count is 0 or 1
25737         $LFS setdirstripe -D -c 1 $testdir ||
25738                 error "failed to set default LMV"
25739         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25740         (( max_inherit == -1 )) ||
25741                 error "wrong max_inherit value $max_inherit"
25742
25743         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25744         $LFS setdirstripe -D -c -1 $testdir ||
25745                 error "failed to set default LMV"
25746         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25747         (( max_inherit > 0 )) ||
25748                 error "wrong max_inherit value $max_inherit"
25749
25750         # and the subdir will decrease the max_inherit by 1
25751         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25752         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
25753         (( sub_max_inherit == max_inherit - 1)) ||
25754                 error "wrong max-inherit of subdir $sub_max_inherit"
25755
25756         # check specified --max-inherit and warning message
25757         stack_trap "rm -f $tmpfile"
25758         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
25759                 error "failed to set default LMV"
25760         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25761         (( max_inherit == -1 )) ||
25762                 error "wrong max_inherit value $max_inherit"
25763
25764         # check the warning messages
25765         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
25766                 error "failed to detect warning string"
25767         fi
25768 }
25769 run_test 413e "check default max-inherit value"
25770
25771 test_413f() {
25772         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
25773
25774         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25775                 skip "Need server version at least 2.14.55"
25776
25777         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
25778                 error "dump $DIR default LMV failed"
25779         stack_trap "setfattr --restore=$TMP/dmv.ea"
25780
25781         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
25782                 error "set $DIR default LMV failed"
25783
25784         local testdir=$DIR/$tdir
25785
25786         local count
25787         local inherit
25788         local inherit_rr
25789
25790         for i in $(seq 3); do
25791                 mkdir $testdir || error "mkdir $testdir failed"
25792                 count=$($LFS getdirstripe -D -c $testdir)
25793                 (( count == 1 )) ||
25794                         error "$testdir default LMV count mismatch $count != 1"
25795                 inherit=$($LFS getdirstripe -D -X $testdir)
25796                 (( inherit == 3 - i )) ||
25797                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
25798                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
25799                 (( inherit_rr == 3 - i )) ||
25800                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
25801                 testdir=$testdir/sub
25802         done
25803
25804         mkdir $testdir || error "mkdir $testdir failed"
25805         count=$($LFS getdirstripe -D -c $testdir)
25806         (( count == 0 )) ||
25807                 error "$testdir default LMV count not zero: $count"
25808 }
25809 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
25810
25811 test_413z() {
25812         local pids=""
25813         local subdir
25814         local pid
25815
25816         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25817                 unlinkmany $subdir/f. 1000 &
25818                 pids="$pids $!"
25819         done
25820
25821         for pid in $pids; do
25822                 wait $pid
25823         done
25824 }
25825 run_test 413z "413 test cleanup"
25826
25827 test_414() {
25828 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25829         $LCTL set_param fail_loc=0x80000521
25830         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25831         rm -f $DIR/$tfile
25832 }
25833 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25834
25835 test_415() {
25836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25837         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25838                 skip "Need server version at least 2.11.52"
25839
25840         # LU-11102
25841         local total
25842         local setattr_pid
25843         local start_time
25844         local end_time
25845         local duration
25846
25847         total=500
25848         # this test may be slow on ZFS
25849         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25850
25851         # though this test is designed for striped directory, let's test normal
25852         # directory too since lock is always saved as CoS lock.
25853         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25854         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25855
25856         (
25857                 while true; do
25858                         touch $DIR/$tdir
25859                 done
25860         ) &
25861         setattr_pid=$!
25862
25863         start_time=$(date +%s)
25864         for i in $(seq $total); do
25865                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25866                         > /dev/null
25867         done
25868         end_time=$(date +%s)
25869         duration=$((end_time - start_time))
25870
25871         kill -9 $setattr_pid
25872
25873         echo "rename $total files took $duration sec"
25874         [ $duration -lt 100 ] || error "rename took $duration sec"
25875 }
25876 run_test 415 "lock revoke is not missing"
25877
25878 test_416() {
25879         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25880                 skip "Need server version at least 2.11.55"
25881
25882         # define OBD_FAIL_OSD_TXN_START    0x19a
25883         do_facet mds1 lctl set_param fail_loc=0x19a
25884
25885         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25886
25887         true
25888 }
25889 run_test 416 "transaction start failure won't cause system hung"
25890
25891 cleanup_417() {
25892         trap 0
25893         do_nodes $(comma_list $(mdts_nodes)) \
25894                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25895         do_nodes $(comma_list $(mdts_nodes)) \
25896                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25897         do_nodes $(comma_list $(mdts_nodes)) \
25898                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25899 }
25900
25901 test_417() {
25902         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25903         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25904                 skip "Need MDS version at least 2.11.56"
25905
25906         trap cleanup_417 RETURN EXIT
25907
25908         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25909         do_nodes $(comma_list $(mdts_nodes)) \
25910                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25911         $LFS migrate -m 0 $DIR/$tdir.1 &&
25912                 error "migrate dir $tdir.1 should fail"
25913
25914         do_nodes $(comma_list $(mdts_nodes)) \
25915                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25916         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25917                 error "create remote dir $tdir.2 should fail"
25918
25919         do_nodes $(comma_list $(mdts_nodes)) \
25920                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25921         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25922                 error "create striped dir $tdir.3 should fail"
25923         true
25924 }
25925 run_test 417 "disable remote dir, striped dir and dir migration"
25926
25927 # Checks that the outputs of df [-i] and lfs df [-i] match
25928 #
25929 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25930 check_lfs_df() {
25931         local dir=$2
25932         local inodes
25933         local df_out
25934         local lfs_df_out
25935         local count
25936         local passed=false
25937
25938         # blocks or inodes
25939         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25940
25941         for count in {1..100}; do
25942                 do_nodes "$CLIENTS" \
25943                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25944                 sync; sleep 0.2
25945
25946                 # read the lines of interest
25947                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25948                         error "df $inodes $dir | tail -n +2 failed"
25949                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25950                         error "lfs df $inodes $dir | grep summary: failed"
25951
25952                 # skip first substrings of each output as they are different
25953                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25954                 # compare the two outputs
25955                 passed=true
25956                 #  skip "available" on MDT until LU-13997 is fixed.
25957                 #for i in {1..5}; do
25958                 for i in 1 2 4 5; do
25959                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25960                 done
25961                 $passed && break
25962         done
25963
25964         if ! $passed; then
25965                 df -P $inodes $dir
25966                 echo
25967                 lfs df $inodes $dir
25968                 error "df and lfs df $1 output mismatch: "      \
25969                       "df ${inodes}: ${df_out[*]}, "            \
25970                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25971         fi
25972 }
25973
25974 test_418() {
25975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25976
25977         local dir=$DIR/$tdir
25978         local numfiles=$((RANDOM % 4096 + 2))
25979         local numblocks=$((RANDOM % 256 + 1))
25980
25981         wait_delete_completed
25982         test_mkdir $dir
25983
25984         # check block output
25985         check_lfs_df blocks $dir
25986         # check inode output
25987         check_lfs_df inodes $dir
25988
25989         # create a single file and retest
25990         echo "Creating a single file and testing"
25991         createmany -o $dir/$tfile- 1 &>/dev/null ||
25992                 error "creating 1 file in $dir failed"
25993         check_lfs_df blocks $dir
25994         check_lfs_df inodes $dir
25995
25996         # create a random number of files
25997         echo "Creating $((numfiles - 1)) files and testing"
25998         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25999                 error "creating $((numfiles - 1)) files in $dir failed"
26000
26001         # write a random number of blocks to the first test file
26002         echo "Writing $numblocks 4K blocks and testing"
26003         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26004                 count=$numblocks &>/dev/null ||
26005                 error "dd to $dir/${tfile}-0 failed"
26006
26007         # retest
26008         check_lfs_df blocks $dir
26009         check_lfs_df inodes $dir
26010
26011         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26012                 error "unlinking $numfiles files in $dir failed"
26013 }
26014 run_test 418 "df and lfs df outputs match"
26015
26016 test_419()
26017 {
26018         local dir=$DIR/$tdir
26019
26020         mkdir -p $dir
26021         touch $dir/file
26022
26023         cancel_lru_locks mdc
26024
26025         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26026         $LCTL set_param fail_loc=0x1410
26027         cat $dir/file
26028         $LCTL set_param fail_loc=0
26029         rm -rf $dir
26030 }
26031 run_test 419 "Verify open file by name doesn't crash kernel"
26032
26033 test_420()
26034 {
26035         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26036                 skip "Need MDS version at least 2.12.53"
26037
26038         local SAVE_UMASK=$(umask)
26039         local dir=$DIR/$tdir
26040         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26041
26042         mkdir -p $dir
26043         umask 0000
26044         mkdir -m03777 $dir/testdir
26045         ls -dn $dir/testdir
26046         # Need to remove trailing '.' when SELinux is enabled
26047         local dirperms=$(ls -dn $dir/testdir |
26048                          awk '{ sub(/\.$/, "", $1); print $1}')
26049         [ $dirperms == "drwxrwsrwt" ] ||
26050                 error "incorrect perms on $dir/testdir"
26051
26052         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26053                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26054         ls -n $dir/testdir/testfile
26055         local fileperms=$(ls -n $dir/testdir/testfile |
26056                           awk '{ sub(/\.$/, "", $1); print $1}')
26057         [ $fileperms == "-rwxr-xr-x" ] ||
26058                 error "incorrect perms on $dir/testdir/testfile"
26059
26060         umask $SAVE_UMASK
26061 }
26062 run_test 420 "clear SGID bit on non-directories for non-members"
26063
26064 test_421a() {
26065         local cnt
26066         local fid1
26067         local fid2
26068
26069         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26070                 skip "Need MDS version at least 2.12.54"
26071
26072         test_mkdir $DIR/$tdir
26073         createmany -o $DIR/$tdir/f 3
26074         cnt=$(ls -1 $DIR/$tdir | wc -l)
26075         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26076
26077         fid1=$(lfs path2fid $DIR/$tdir/f1)
26078         fid2=$(lfs path2fid $DIR/$tdir/f2)
26079         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26080
26081         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26082         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26083
26084         cnt=$(ls -1 $DIR/$tdir | wc -l)
26085         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26086
26087         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26088         createmany -o $DIR/$tdir/f 3
26089         cnt=$(ls -1 $DIR/$tdir | wc -l)
26090         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26091
26092         fid1=$(lfs path2fid $DIR/$tdir/f1)
26093         fid2=$(lfs path2fid $DIR/$tdir/f2)
26094         echo "remove using fsname $FSNAME"
26095         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26096
26097         cnt=$(ls -1 $DIR/$tdir | wc -l)
26098         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26099 }
26100 run_test 421a "simple rm by fid"
26101
26102 test_421b() {
26103         local cnt
26104         local FID1
26105         local FID2
26106
26107         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26108                 skip "Need MDS version at least 2.12.54"
26109
26110         test_mkdir $DIR/$tdir
26111         createmany -o $DIR/$tdir/f 3
26112         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26113         MULTIPID=$!
26114
26115         FID1=$(lfs path2fid $DIR/$tdir/f1)
26116         FID2=$(lfs path2fid $DIR/$tdir/f2)
26117         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26118
26119         kill -USR1 $MULTIPID
26120         wait
26121
26122         cnt=$(ls $DIR/$tdir | wc -l)
26123         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26124 }
26125 run_test 421b "rm by fid on open file"
26126
26127 test_421c() {
26128         local cnt
26129         local FIDS
26130
26131         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26132                 skip "Need MDS version at least 2.12.54"
26133
26134         test_mkdir $DIR/$tdir
26135         createmany -o $DIR/$tdir/f 3
26136         touch $DIR/$tdir/$tfile
26137         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26138         cnt=$(ls -1 $DIR/$tdir | wc -l)
26139         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26140
26141         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26142         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26143
26144         cnt=$(ls $DIR/$tdir | wc -l)
26145         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26146 }
26147 run_test 421c "rm by fid against hardlinked files"
26148
26149 test_421d() {
26150         local cnt
26151         local FIDS
26152
26153         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26154                 skip "Need MDS version at least 2.12.54"
26155
26156         test_mkdir $DIR/$tdir
26157         createmany -o $DIR/$tdir/f 4097
26158         cnt=$(ls -1 $DIR/$tdir | wc -l)
26159         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26160
26161         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26162         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26163
26164         cnt=$(ls $DIR/$tdir | wc -l)
26165         rm -rf $DIR/$tdir
26166         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26167 }
26168 run_test 421d "rmfid en masse"
26169
26170 test_421e() {
26171         local cnt
26172         local FID
26173
26174         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26175         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26176                 skip "Need MDS version at least 2.12.54"
26177
26178         mkdir -p $DIR/$tdir
26179         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26180         createmany -o $DIR/$tdir/striped_dir/f 512
26181         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26182         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26183
26184         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26185                 sed "s/[/][^:]*://g")
26186         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26187
26188         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26189         rm -rf $DIR/$tdir
26190         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26191 }
26192 run_test 421e "rmfid in DNE"
26193
26194 test_421f() {
26195         local cnt
26196         local FID
26197
26198         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26199                 skip "Need MDS version at least 2.12.54"
26200
26201         test_mkdir $DIR/$tdir
26202         touch $DIR/$tdir/f
26203         cnt=$(ls -1 $DIR/$tdir | wc -l)
26204         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26205
26206         FID=$(lfs path2fid $DIR/$tdir/f)
26207         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26208         # rmfid should fail
26209         cnt=$(ls -1 $DIR/$tdir | wc -l)
26210         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26211
26212         chmod a+rw $DIR/$tdir
26213         ls -la $DIR/$tdir
26214         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26215         # rmfid should fail
26216         cnt=$(ls -1 $DIR/$tdir | wc -l)
26217         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26218
26219         rm -f $DIR/$tdir/f
26220         $RUNAS touch $DIR/$tdir/f
26221         FID=$(lfs path2fid $DIR/$tdir/f)
26222         echo "rmfid as root"
26223         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26224         cnt=$(ls -1 $DIR/$tdir | wc -l)
26225         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26226
26227         rm -f $DIR/$tdir/f
26228         $RUNAS touch $DIR/$tdir/f
26229         cnt=$(ls -1 $DIR/$tdir | wc -l)
26230         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26231         FID=$(lfs path2fid $DIR/$tdir/f)
26232         # rmfid w/o user_fid2path mount option should fail
26233         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26234         cnt=$(ls -1 $DIR/$tdir | wc -l)
26235         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26236
26237         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26238         stack_trap "rmdir $tmpdir"
26239         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26240                 error "failed to mount client'"
26241         stack_trap "umount_client $tmpdir"
26242
26243         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26244         # rmfid should succeed
26245         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26246         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26247
26248         # rmfid shouldn't allow to remove files due to dir's permission
26249         chmod a+rwx $tmpdir/$tdir
26250         touch $tmpdir/$tdir/f
26251         ls -la $tmpdir/$tdir
26252         FID=$(lfs path2fid $tmpdir/$tdir/f)
26253         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26254         return 0
26255 }
26256 run_test 421f "rmfid checks permissions"
26257
26258 test_421g() {
26259         local cnt
26260         local FIDS
26261
26262         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26263         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26264                 skip "Need MDS version at least 2.12.54"
26265
26266         mkdir -p $DIR/$tdir
26267         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26268         createmany -o $DIR/$tdir/striped_dir/f 512
26269         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26270         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26271
26272         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26273                 sed "s/[/][^:]*://g")
26274
26275         rm -f $DIR/$tdir/striped_dir/f1*
26276         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26277         removed=$((512 - cnt))
26278
26279         # few files have been just removed, so we expect
26280         # rmfid to fail on their fids
26281         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26282         [ $removed != $errors ] && error "$errors != $removed"
26283
26284         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26285         rm -rf $DIR/$tdir
26286         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26287 }
26288 run_test 421g "rmfid to return errors properly"
26289
26290 test_422() {
26291         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26292         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26293         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26294         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26295         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26296
26297         local amc=$(at_max_get client)
26298         local amo=$(at_max_get mds1)
26299         local timeout=`lctl get_param -n timeout`
26300
26301         at_max_set 0 client
26302         at_max_set 0 mds1
26303
26304 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26305         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26306                         fail_val=$(((2*timeout + 10)*1000))
26307         touch $DIR/$tdir/d3/file &
26308         sleep 2
26309 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26310         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26311                         fail_val=$((2*timeout + 5))
26312         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26313         local pid=$!
26314         sleep 1
26315         kill -9 $pid
26316         sleep $((2 * timeout))
26317         echo kill $pid
26318         kill -9 $pid
26319         lctl mark touch
26320         touch $DIR/$tdir/d2/file3
26321         touch $DIR/$tdir/d2/file4
26322         touch $DIR/$tdir/d2/file5
26323
26324         wait
26325         at_max_set $amc client
26326         at_max_set $amo mds1
26327
26328         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26329         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26330                 error "Watchdog is always throttled"
26331 }
26332 run_test 422 "kill a process with RPC in progress"
26333
26334 stat_test() {
26335     df -h $MOUNT &
26336     df -h $MOUNT &
26337     df -h $MOUNT &
26338     df -h $MOUNT &
26339     df -h $MOUNT &
26340     df -h $MOUNT &
26341 }
26342
26343 test_423() {
26344     local _stats
26345     # ensure statfs cache is expired
26346     sleep 2;
26347
26348     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26349     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26350
26351     return 0
26352 }
26353 run_test 423 "statfs should return a right data"
26354
26355 test_424() {
26356 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26357         $LCTL set_param fail_loc=0x80000522
26358         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26359         rm -f $DIR/$tfile
26360 }
26361 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26362
26363 test_425() {
26364         test_mkdir -c -1 $DIR/$tdir
26365         $LFS setstripe -c -1 $DIR/$tdir
26366
26367         lru_resize_disable "" 100
26368         stack_trap "lru_resize_enable" EXIT
26369
26370         sleep 5
26371
26372         for i in $(seq $((MDSCOUNT * 125))); do
26373                 local t=$DIR/$tdir/$tfile_$i
26374
26375                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26376                         error_noexit "Create file $t"
26377         done
26378         stack_trap "rm -rf $DIR/$tdir" EXIT
26379
26380         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26381                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26382                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26383
26384                 [ $lock_count -le $lru_size ] ||
26385                         error "osc lock count $lock_count > lru size $lru_size"
26386         done
26387
26388         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26389                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26390                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26391
26392                 [ $lock_count -le $lru_size ] ||
26393                         error "mdc lock count $lock_count > lru size $lru_size"
26394         done
26395 }
26396 run_test 425 "lock count should not exceed lru size"
26397
26398 test_426() {
26399         splice-test -r $DIR/$tfile
26400         splice-test -rd $DIR/$tfile
26401         splice-test $DIR/$tfile
26402         splice-test -d $DIR/$tfile
26403 }
26404 run_test 426 "splice test on Lustre"
26405
26406 test_427() {
26407         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26408         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26409                 skip "Need MDS version at least 2.12.4"
26410         local log
26411
26412         mkdir $DIR/$tdir
26413         mkdir $DIR/$tdir/1
26414         mkdir $DIR/$tdir/2
26415         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26416         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26417
26418         $LFS getdirstripe $DIR/$tdir/1/dir
26419
26420         #first setfattr for creating updatelog
26421         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26422
26423 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26424         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26425         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26426         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26427
26428         sleep 2
26429         fail mds2
26430         wait_recovery_complete mds2 $((2*TIMEOUT))
26431
26432         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26433         echo $log | grep "get update log failed" &&
26434                 error "update log corruption is detected" || true
26435 }
26436 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26437
26438 test_428() {
26439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26440         local cache_limit=$CACHE_MAX
26441
26442         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26443         $LCTL set_param -n llite.*.max_cached_mb=64
26444
26445         mkdir $DIR/$tdir
26446         $LFS setstripe -c 1 $DIR/$tdir
26447         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26448         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26449         #test write
26450         for f in $(seq 4); do
26451                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26452         done
26453         wait
26454
26455         cancel_lru_locks osc
26456         # Test read
26457         for f in $(seq 4); do
26458                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26459         done
26460         wait
26461 }
26462 run_test 428 "large block size IO should not hang"
26463
26464 test_429() { # LU-7915 / LU-10948
26465         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26466         local testfile=$DIR/$tfile
26467         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26468         local new_flag=1
26469         local first_rpc
26470         local second_rpc
26471         local third_rpc
26472
26473         $LCTL get_param $ll_opencache_threshold_count ||
26474                 skip "client does not have opencache parameter"
26475
26476         set_opencache $new_flag
26477         stack_trap "restore_opencache"
26478         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26479                 error "enable opencache failed"
26480         touch $testfile
26481         # drop MDC DLM locks
26482         cancel_lru_locks mdc
26483         # clear MDC RPC stats counters
26484         $LCTL set_param $mdc_rpcstats=clear
26485
26486         # According to the current implementation, we need to run 3 times
26487         # open & close file to verify if opencache is enabled correctly.
26488         # 1st, RPCs are sent for lookup/open and open handle is released on
26489         #      close finally.
26490         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26491         #      so open handle won't be released thereafter.
26492         # 3rd, No RPC is sent out.
26493         $MULTIOP $testfile oc || error "multiop failed"
26494         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26495         echo "1st: $first_rpc RPCs in flight"
26496
26497         $MULTIOP $testfile oc || error "multiop failed"
26498         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26499         echo "2nd: $second_rpc RPCs in flight"
26500
26501         $MULTIOP $testfile oc || error "multiop failed"
26502         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26503         echo "3rd: $third_rpc RPCs in flight"
26504
26505         #verify no MDC RPC is sent
26506         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26507 }
26508 run_test 429 "verify if opencache flag on client side does work"
26509
26510 lseek_test_430() {
26511         local offset
26512         local file=$1
26513
26514         # data at [200K, 400K)
26515         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26516                 error "256K->512K dd fails"
26517         # data at [2M, 3M)
26518         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26519                 error "2M->3M dd fails"
26520         # data at [4M, 5M)
26521         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26522                 error "4M->5M dd fails"
26523         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26524         # start at first component hole #1
26525         printf "Seeking hole from 1000 ... "
26526         offset=$(lseek_test -l 1000 $file)
26527         echo $offset
26528         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26529         printf "Seeking data from 1000 ... "
26530         offset=$(lseek_test -d 1000 $file)
26531         echo $offset
26532         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26533
26534         # start at first component data block
26535         printf "Seeking hole from 300000 ... "
26536         offset=$(lseek_test -l 300000 $file)
26537         echo $offset
26538         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26539         printf "Seeking data from 300000 ... "
26540         offset=$(lseek_test -d 300000 $file)
26541         echo $offset
26542         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26543
26544         # start at the first component but beyond end of object size
26545         printf "Seeking hole from 1000000 ... "
26546         offset=$(lseek_test -l 1000000 $file)
26547         echo $offset
26548         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26549         printf "Seeking data from 1000000 ... "
26550         offset=$(lseek_test -d 1000000 $file)
26551         echo $offset
26552         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26553
26554         # start at second component stripe 2 (empty file)
26555         printf "Seeking hole from 1500000 ... "
26556         offset=$(lseek_test -l 1500000 $file)
26557         echo $offset
26558         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26559         printf "Seeking data from 1500000 ... "
26560         offset=$(lseek_test -d 1500000 $file)
26561         echo $offset
26562         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26563
26564         # start at second component stripe 1 (all data)
26565         printf "Seeking hole from 3000000 ... "
26566         offset=$(lseek_test -l 3000000 $file)
26567         echo $offset
26568         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26569         printf "Seeking data from 3000000 ... "
26570         offset=$(lseek_test -d 3000000 $file)
26571         echo $offset
26572         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26573
26574         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26575                 error "2nd dd fails"
26576         echo "Add data block at 640K...1280K"
26577
26578         # start at before new data block, in hole
26579         printf "Seeking hole from 600000 ... "
26580         offset=$(lseek_test -l 600000 $file)
26581         echo $offset
26582         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26583         printf "Seeking data from 600000 ... "
26584         offset=$(lseek_test -d 600000 $file)
26585         echo $offset
26586         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26587
26588         # start at the first component new data block
26589         printf "Seeking hole from 1000000 ... "
26590         offset=$(lseek_test -l 1000000 $file)
26591         echo $offset
26592         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26593         printf "Seeking data from 1000000 ... "
26594         offset=$(lseek_test -d 1000000 $file)
26595         echo $offset
26596         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26597
26598         # start at second component stripe 2, new data
26599         printf "Seeking hole from 1200000 ... "
26600         offset=$(lseek_test -l 1200000 $file)
26601         echo $offset
26602         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26603         printf "Seeking data from 1200000 ... "
26604         offset=$(lseek_test -d 1200000 $file)
26605         echo $offset
26606         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26607
26608         # start beyond file end
26609         printf "Using offset > filesize ... "
26610         lseek_test -l 4000000 $file && error "lseek should fail"
26611         printf "Using offset > filesize ... "
26612         lseek_test -d 4000000 $file && error "lseek should fail"
26613
26614         printf "Done\n\n"
26615 }
26616
26617 test_430a() {
26618         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26619                 skip "MDT does not support SEEK_HOLE"
26620
26621         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26622                 skip "OST does not support SEEK_HOLE"
26623
26624         local file=$DIR/$tdir/$tfile
26625
26626         mkdir -p $DIR/$tdir
26627
26628         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26629         # OST stripe #1 will have continuous data at [1M, 3M)
26630         # OST stripe #2 is empty
26631         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26632         lseek_test_430 $file
26633         rm $file
26634         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26635         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26636         lseek_test_430 $file
26637         rm $file
26638         $LFS setstripe -c2 -S 512K $file
26639         echo "Two stripes, stripe size 512K"
26640         lseek_test_430 $file
26641         rm $file
26642         # FLR with stale mirror
26643         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26644                        -N -c2 -S 1M $file
26645         echo "Mirrored file:"
26646         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26647         echo "Plain 2 stripes 1M"
26648         lseek_test_430 $file
26649         rm $file
26650 }
26651 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26652
26653 test_430b() {
26654         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26655                 skip "OST does not support SEEK_HOLE"
26656
26657         local offset
26658         local file=$DIR/$tdir/$tfile
26659
26660         mkdir -p $DIR/$tdir
26661         # Empty layout lseek should fail
26662         $MCREATE $file
26663         # seek from 0
26664         printf "Seeking hole from 0 ... "
26665         lseek_test -l 0 $file && error "lseek should fail"
26666         printf "Seeking data from 0 ... "
26667         lseek_test -d 0 $file && error "lseek should fail"
26668         rm $file
26669
26670         # 1M-hole file
26671         $LFS setstripe -E 1M -c2 -E eof $file
26672         $TRUNCATE $file 1048576
26673         printf "Seeking hole from 1000000 ... "
26674         offset=$(lseek_test -l 1000000 $file)
26675         echo $offset
26676         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26677         printf "Seeking data from 1000000 ... "
26678         lseek_test -d 1000000 $file && error "lseek should fail"
26679         rm $file
26680
26681         # full component followed by non-inited one
26682         $LFS setstripe -E 1M -c2 -E eof $file
26683         dd if=/dev/urandom of=$file bs=1M count=1
26684         printf "Seeking hole from 1000000 ... "
26685         offset=$(lseek_test -l 1000000 $file)
26686         echo $offset
26687         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26688         printf "Seeking hole from 1048576 ... "
26689         lseek_test -l 1048576 $file && error "lseek should fail"
26690         # init second component and truncate back
26691         echo "123" >> $file
26692         $TRUNCATE $file 1048576
26693         printf "Seeking hole from 1000000 ... "
26694         offset=$(lseek_test -l 1000000 $file)
26695         echo $offset
26696         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26697         printf "Seeking hole from 1048576 ... "
26698         lseek_test -l 1048576 $file && error "lseek should fail"
26699         # boundary checks for big values
26700         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26701         offset=$(lseek_test -d 0 $file.10g)
26702         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26703         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26704         offset=$(lseek_test -d 0 $file.100g)
26705         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26706         return 0
26707 }
26708 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26709
26710 test_430c() {
26711         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26712                 skip "OST does not support SEEK_HOLE"
26713
26714         local file=$DIR/$tdir/$tfile
26715         local start
26716
26717         mkdir -p $DIR/$tdir
26718         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26719
26720         # cp version 8.33+ prefers lseek over fiemap
26721         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26722                 start=$SECONDS
26723                 time cp $file /dev/null
26724                 (( SECONDS - start < 5 )) ||
26725                         error "cp: too long runtime $((SECONDS - start))"
26726
26727         fi
26728         # tar version 1.29+ supports SEEK_HOLE/DATA
26729         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26730                 start=$SECONDS
26731                 time tar cS $file - | cat > /dev/null
26732                 (( SECONDS - start < 5 )) ||
26733                         error "tar: too long runtime $((SECONDS - start))"
26734         fi
26735 }
26736 run_test 430c "lseek: external tools check"
26737
26738 test_431() { # LU-14187
26739         local file=$DIR/$tdir/$tfile
26740
26741         mkdir -p $DIR/$tdir
26742         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26743         dd if=/dev/urandom of=$file bs=4k count=1
26744         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26745         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26746         #define OBD_FAIL_OST_RESTART_IO 0x251
26747         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26748         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26749         cp $file $file.0
26750         cancel_lru_locks
26751         sync_all_data
26752         echo 3 > /proc/sys/vm/drop_caches
26753         diff  $file $file.0 || error "data diff"
26754 }
26755 run_test 431 "Restart transaction for IO"
26756
26757 cleanup_test_432() {
26758         do_facet mgs $LCTL nodemap_activate 0
26759         wait_nm_sync active
26760 }
26761
26762 test_432() {
26763         local tmpdir=$TMP/dir432
26764
26765         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26766                 skip "Need MDS version at least 2.14.52"
26767
26768         stack_trap cleanup_test_432 EXIT
26769         mkdir $DIR/$tdir
26770         mkdir $tmpdir
26771
26772         do_facet mgs $LCTL nodemap_activate 1
26773         wait_nm_sync active
26774         do_facet mgs $LCTL nodemap_modify --name default \
26775                 --property admin --value 1
26776         do_facet mgs $LCTL nodemap_modify --name default \
26777                 --property trusted --value 1
26778         cancel_lru_locks mdc
26779         wait_nm_sync default admin_nodemap
26780         wait_nm_sync default trusted_nodemap
26781
26782         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26783                grep -ci "Operation not permitted") -ne 0 ]; then
26784                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26785         fi
26786 }
26787 run_test 432 "mv dir from outside Lustre"
26788
26789 prep_801() {
26790         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26791         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26792                 skip "Need server version at least 2.9.55"
26793
26794         start_full_debug_logging
26795 }
26796
26797 post_801() {
26798         stop_full_debug_logging
26799 }
26800
26801 barrier_stat() {
26802         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26803                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26804                            awk '/The barrier for/ { print $7 }')
26805                 echo $st
26806         else
26807                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26808                 echo \'$st\'
26809         fi
26810 }
26811
26812 barrier_expired() {
26813         local expired
26814
26815         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26816                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26817                           awk '/will be expired/ { print $7 }')
26818         else
26819                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26820         fi
26821
26822         echo $expired
26823 }
26824
26825 test_801a() {
26826         prep_801
26827
26828         echo "Start barrier_freeze at: $(date)"
26829         #define OBD_FAIL_BARRIER_DELAY          0x2202
26830         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26831         # Do not reduce barrier time - See LU-11873
26832         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26833
26834         sleep 2
26835         local b_status=$(barrier_stat)
26836         echo "Got barrier status at: $(date)"
26837         [ "$b_status" = "'freezing_p1'" ] ||
26838                 error "(1) unexpected barrier status $b_status"
26839
26840         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26841         wait
26842         b_status=$(barrier_stat)
26843         [ "$b_status" = "'frozen'" ] ||
26844                 error "(2) unexpected barrier status $b_status"
26845
26846         local expired=$(barrier_expired)
26847         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26848         sleep $((expired + 3))
26849
26850         b_status=$(barrier_stat)
26851         [ "$b_status" = "'expired'" ] ||
26852                 error "(3) unexpected barrier status $b_status"
26853
26854         # Do not reduce barrier time - See LU-11873
26855         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26856                 error "(4) fail to freeze barrier"
26857
26858         b_status=$(barrier_stat)
26859         [ "$b_status" = "'frozen'" ] ||
26860                 error "(5) unexpected barrier status $b_status"
26861
26862         echo "Start barrier_thaw at: $(date)"
26863         #define OBD_FAIL_BARRIER_DELAY          0x2202
26864         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26865         do_facet mgs $LCTL barrier_thaw $FSNAME &
26866
26867         sleep 2
26868         b_status=$(barrier_stat)
26869         echo "Got barrier status at: $(date)"
26870         [ "$b_status" = "'thawing'" ] ||
26871                 error "(6) unexpected barrier status $b_status"
26872
26873         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26874         wait
26875         b_status=$(barrier_stat)
26876         [ "$b_status" = "'thawed'" ] ||
26877                 error "(7) unexpected barrier status $b_status"
26878
26879         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26880         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26881         do_facet mgs $LCTL barrier_freeze $FSNAME
26882
26883         b_status=$(barrier_stat)
26884         [ "$b_status" = "'failed'" ] ||
26885                 error "(8) unexpected barrier status $b_status"
26886
26887         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26888         do_facet mgs $LCTL barrier_thaw $FSNAME
26889
26890         post_801
26891 }
26892 run_test 801a "write barrier user interfaces and stat machine"
26893
26894 test_801b() {
26895         prep_801
26896
26897         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26898         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
26899         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26900         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26901         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26902
26903         cancel_lru_locks mdc
26904
26905         # 180 seconds should be long enough
26906         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26907
26908         local b_status=$(barrier_stat)
26909         [ "$b_status" = "'frozen'" ] ||
26910                 error "(6) unexpected barrier status $b_status"
26911
26912         mkdir $DIR/$tdir/d0/d10 &
26913         mkdir_pid=$!
26914
26915         touch $DIR/$tdir/d1/f13 &
26916         touch_pid=$!
26917
26918         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26919         ln_pid=$!
26920
26921         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26922         mv_pid=$!
26923
26924         rm -f $DIR/$tdir/d4/f12 &
26925         rm_pid=$!
26926
26927         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26928
26929         # To guarantee taht the 'stat' is not blocked
26930         b_status=$(barrier_stat)
26931         [ "$b_status" = "'frozen'" ] ||
26932                 error "(8) unexpected barrier status $b_status"
26933
26934         # let above commands to run at background
26935         sleep 5
26936
26937         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26938         ps -p $touch_pid || error "(10) touch should be blocked"
26939         ps -p $ln_pid || error "(11) link should be blocked"
26940         ps -p $mv_pid || error "(12) rename should be blocked"
26941         ps -p $rm_pid || error "(13) unlink should be blocked"
26942
26943         b_status=$(barrier_stat)
26944         [ "$b_status" = "'frozen'" ] ||
26945                 error "(14) unexpected barrier status $b_status"
26946
26947         do_facet mgs $LCTL barrier_thaw $FSNAME
26948         b_status=$(barrier_stat)
26949         [ "$b_status" = "'thawed'" ] ||
26950                 error "(15) unexpected barrier status $b_status"
26951
26952         wait $mkdir_pid || error "(16) mkdir should succeed"
26953         wait $touch_pid || error "(17) touch should succeed"
26954         wait $ln_pid || error "(18) link should succeed"
26955         wait $mv_pid || error "(19) rename should succeed"
26956         wait $rm_pid || error "(20) unlink should succeed"
26957
26958         post_801
26959 }
26960 run_test 801b "modification will be blocked by write barrier"
26961
26962 test_801c() {
26963         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26964
26965         prep_801
26966
26967         stop mds2 || error "(1) Fail to stop mds2"
26968
26969         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26970
26971         local b_status=$(barrier_stat)
26972         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26973                 do_facet mgs $LCTL barrier_thaw $FSNAME
26974                 error "(2) unexpected barrier status $b_status"
26975         }
26976
26977         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26978                 error "(3) Fail to rescan barrier bitmap"
26979
26980         # Do not reduce barrier time - See LU-11873
26981         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26982
26983         b_status=$(barrier_stat)
26984         [ "$b_status" = "'frozen'" ] ||
26985                 error "(4) unexpected barrier status $b_status"
26986
26987         do_facet mgs $LCTL barrier_thaw $FSNAME
26988         b_status=$(barrier_stat)
26989         [ "$b_status" = "'thawed'" ] ||
26990                 error "(5) unexpected barrier status $b_status"
26991
26992         local devname=$(mdsdevname 2)
26993
26994         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26995
26996         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26997                 error "(7) Fail to rescan barrier bitmap"
26998
26999         post_801
27000 }
27001 run_test 801c "rescan barrier bitmap"
27002
27003 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27004 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27005 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27006 saved_MOUNT_OPTS=$MOUNT_OPTS
27007
27008 cleanup_802a() {
27009         trap 0
27010
27011         stopall
27012         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27013         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27014         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27015         MOUNT_OPTS=$saved_MOUNT_OPTS
27016         setupall
27017 }
27018
27019 test_802a() {
27020         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27021         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27022         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27023                 skip "Need server version at least 2.9.55"
27024
27025         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27026
27027         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27028
27029         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27030                 error "(2) Fail to copy"
27031
27032         trap cleanup_802a EXIT
27033
27034         # sync by force before remount as readonly
27035         sync; sync_all_data; sleep 3; sync_all_data
27036
27037         stopall
27038
27039         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27040         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27041         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27042
27043         echo "Mount the server as read only"
27044         setupall server_only || error "(3) Fail to start servers"
27045
27046         echo "Mount client without ro should fail"
27047         mount_client $MOUNT &&
27048                 error "(4) Mount client without 'ro' should fail"
27049
27050         echo "Mount client with ro should succeed"
27051         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27052         mount_client $MOUNT ||
27053                 error "(5) Mount client with 'ro' should succeed"
27054
27055         echo "Modify should be refused"
27056         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27057
27058         echo "Read should be allowed"
27059         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27060                 error "(7) Read should succeed under ro mode"
27061
27062         cleanup_802a
27063 }
27064 run_test 802a "simulate readonly device"
27065
27066 test_802b() {
27067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27068         remote_mds_nodsh && skip "remote MDS with nodsh"
27069
27070         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27071                 skip "readonly option not available"
27072
27073         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27074
27075         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27076                 error "(2) Fail to copy"
27077
27078         # write back all cached data before setting MDT to readonly
27079         cancel_lru_locks
27080         sync_all_data
27081
27082         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27083         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27084
27085         echo "Modify should be refused"
27086         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27087
27088         echo "Read should be allowed"
27089         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27090                 error "(7) Read should succeed under ro mode"
27091
27092         # disable readonly
27093         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27094 }
27095 run_test 802b "be able to set MDTs to readonly"
27096
27097 test_803a() {
27098         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27099         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27100                 skip "MDS needs to be newer than 2.10.54"
27101
27102         mkdir_on_mdt0 $DIR/$tdir
27103         # Create some objects on all MDTs to trigger related logs objects
27104         for idx in $(seq $MDSCOUNT); do
27105                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27106                         $DIR/$tdir/dir${idx} ||
27107                         error "Fail to create $DIR/$tdir/dir${idx}"
27108         done
27109
27110         sync; sleep 3
27111         wait_delete_completed # ensure old test cleanups are finished
27112         echo "before create:"
27113         $LFS df -i $MOUNT
27114         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27115
27116         for i in {1..10}; do
27117                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27118                         error "Fail to create $DIR/$tdir/foo$i"
27119         done
27120
27121         sync; sleep 3
27122         echo "after create:"
27123         $LFS df -i $MOUNT
27124         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27125
27126         # allow for an llog to be cleaned up during the test
27127         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27128                 error "before ($before_used) + 10 > after ($after_used)"
27129
27130         for i in {1..10}; do
27131                 rm -rf $DIR/$tdir/foo$i ||
27132                         error "Fail to remove $DIR/$tdir/foo$i"
27133         done
27134
27135         sleep 3 # avoid MDT return cached statfs
27136         wait_delete_completed
27137         echo "after unlink:"
27138         $LFS df -i $MOUNT
27139         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27140
27141         # allow for an llog to be created during the test
27142         [ $after_used -le $((before_used + 1)) ] ||
27143                 error "after ($after_used) > before ($before_used) + 1"
27144 }
27145 run_test 803a "verify agent object for remote object"
27146
27147 test_803b() {
27148         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27149         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27150                 skip "MDS needs to be newer than 2.13.56"
27151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27152
27153         for i in $(seq 0 $((MDSCOUNT - 1))); do
27154                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27155         done
27156
27157         local before=0
27158         local after=0
27159
27160         local tmp
27161
27162         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27163         for i in $(seq 0 $((MDSCOUNT - 1))); do
27164                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27165                         awk '/getattr/ { print $2 }')
27166                 before=$((before + tmp))
27167         done
27168         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27169         for i in $(seq 0 $((MDSCOUNT - 1))); do
27170                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27171                         awk '/getattr/ { print $2 }')
27172                 after=$((after + tmp))
27173         done
27174
27175         [ $before -eq $after ] || error "getattr count $before != $after"
27176 }
27177 run_test 803b "remote object can getattr from cache"
27178
27179 test_804() {
27180         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27181         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27182                 skip "MDS needs to be newer than 2.10.54"
27183         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27184
27185         mkdir -p $DIR/$tdir
27186         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27187                 error "Fail to create $DIR/$tdir/dir0"
27188
27189         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27190         local dev=$(mdsdevname 2)
27191
27192         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27193                 grep ${fid} || error "NOT found agent entry for dir0"
27194
27195         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27196                 error "Fail to create $DIR/$tdir/dir1"
27197
27198         touch $DIR/$tdir/dir1/foo0 ||
27199                 error "Fail to create $DIR/$tdir/dir1/foo0"
27200         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27201         local rc=0
27202
27203         for idx in $(seq $MDSCOUNT); do
27204                 dev=$(mdsdevname $idx)
27205                 do_facet mds${idx} \
27206                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27207                         grep ${fid} && rc=$idx
27208         done
27209
27210         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27211                 error "Fail to rename foo0 to foo1"
27212         if [ $rc -eq 0 ]; then
27213                 for idx in $(seq $MDSCOUNT); do
27214                         dev=$(mdsdevname $idx)
27215                         do_facet mds${idx} \
27216                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27217                         grep ${fid} && rc=$idx
27218                 done
27219         fi
27220
27221         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27222                 error "Fail to rename foo1 to foo2"
27223         if [ $rc -eq 0 ]; then
27224                 for idx in $(seq $MDSCOUNT); do
27225                         dev=$(mdsdevname $idx)
27226                         do_facet mds${idx} \
27227                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27228                         grep ${fid} && rc=$idx
27229                 done
27230         fi
27231
27232         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27233
27234         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27235                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27236         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27237                 error "Fail to rename foo2 to foo0"
27238         unlink $DIR/$tdir/dir1/foo0 ||
27239                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27240         rm -rf $DIR/$tdir/dir0 ||
27241                 error "Fail to rm $DIR/$tdir/dir0"
27242
27243         for idx in $(seq $MDSCOUNT); do
27244                 rc=0
27245
27246                 stop mds${idx}
27247                 dev=$(mdsdevname $idx)
27248                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27249                         rc=$?
27250                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27251                         error "mount mds$idx failed"
27252                 df $MOUNT > /dev/null 2>&1
27253
27254                 # e2fsck should not return error
27255                 [ $rc -eq 0 ] ||
27256                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27257         done
27258 }
27259 run_test 804 "verify agent entry for remote entry"
27260
27261 cleanup_805() {
27262         do_facet $SINGLEMDS zfs set quota=$old $fsset
27263         unlinkmany $DIR/$tdir/f- 1000000
27264         trap 0
27265 }
27266
27267 test_805() {
27268         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27269         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27270         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27271                 skip "netfree not implemented before 0.7"
27272         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27273                 skip "Need MDS version at least 2.10.57"
27274
27275         local fsset
27276         local freekb
27277         local usedkb
27278         local old
27279         local quota
27280         local pref="osd-zfs.$FSNAME-MDT0000."
27281
27282         # limit available space on MDS dataset to meet nospace issue
27283         # quickly. then ZFS 0.7.2 can use reserved space if asked
27284         # properly (using netfree flag in osd_declare_destroy()
27285         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27286         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27287                 gawk '{print $3}')
27288         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27289         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27290         let "usedkb=usedkb-freekb"
27291         let "freekb=freekb/2"
27292         if let "freekb > 5000"; then
27293                 let "freekb=5000"
27294         fi
27295         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27296         trap cleanup_805 EXIT
27297         mkdir_on_mdt0 $DIR/$tdir
27298         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27299                 error "Can't set PFL layout"
27300         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27301         rm -rf $DIR/$tdir || error "not able to remove"
27302         do_facet $SINGLEMDS zfs set quota=$old $fsset
27303         trap 0
27304 }
27305 run_test 805 "ZFS can remove from full fs"
27306
27307 # Size-on-MDS test
27308 check_lsom_data()
27309 {
27310         local file=$1
27311         local expect=$(stat -c %s $file)
27312
27313         check_lsom_size $1 $expect
27314
27315         local blocks=$($LFS getsom -b $file)
27316         expect=$(stat -c %b $file)
27317         [[ $blocks == $expect ]] ||
27318                 error "$file expected blocks: $expect, got: $blocks"
27319 }
27320
27321 check_lsom_size()
27322 {
27323         local size
27324         local expect=$2
27325
27326         cancel_lru_locks mdc
27327
27328         size=$($LFS getsom -s $1)
27329         [[ $size == $expect ]] ||
27330                 error "$file expected size: $expect, got: $size"
27331 }
27332
27333 test_806() {
27334         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27335                 skip "Need MDS version at least 2.11.52"
27336
27337         local bs=1048576
27338
27339         touch $DIR/$tfile || error "touch $tfile failed"
27340
27341         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27342         save_lustre_params client "llite.*.xattr_cache" > $save
27343         lctl set_param llite.*.xattr_cache=0
27344         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27345
27346         # single-threaded write
27347         echo "Test SOM for single-threaded write"
27348         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27349                 error "write $tfile failed"
27350         check_lsom_size $DIR/$tfile $bs
27351
27352         local num=32
27353         local size=$(($num * $bs))
27354         local offset=0
27355         local i
27356
27357         echo "Test SOM for single client multi-threaded($num) write"
27358         $TRUNCATE $DIR/$tfile 0
27359         for ((i = 0; i < $num; i++)); do
27360                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27361                 local pids[$i]=$!
27362                 offset=$((offset + $bs))
27363         done
27364         for (( i=0; i < $num; i++ )); do
27365                 wait ${pids[$i]}
27366         done
27367         check_lsom_size $DIR/$tfile $size
27368
27369         $TRUNCATE $DIR/$tfile 0
27370         for ((i = 0; i < $num; i++)); do
27371                 offset=$((offset - $bs))
27372                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27373                 local pids[$i]=$!
27374         done
27375         for (( i=0; i < $num; i++ )); do
27376                 wait ${pids[$i]}
27377         done
27378         check_lsom_size $DIR/$tfile $size
27379
27380         # multi-client writes
27381         num=$(get_node_count ${CLIENTS//,/ })
27382         size=$(($num * $bs))
27383         offset=0
27384         i=0
27385
27386         echo "Test SOM for multi-client ($num) writes"
27387         $TRUNCATE $DIR/$tfile 0
27388         for client in ${CLIENTS//,/ }; do
27389                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27390                 local pids[$i]=$!
27391                 i=$((i + 1))
27392                 offset=$((offset + $bs))
27393         done
27394         for (( i=0; i < $num; i++ )); do
27395                 wait ${pids[$i]}
27396         done
27397         check_lsom_size $DIR/$tfile $offset
27398
27399         i=0
27400         $TRUNCATE $DIR/$tfile 0
27401         for client in ${CLIENTS//,/ }; do
27402                 offset=$((offset - $bs))
27403                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27404                 local pids[$i]=$!
27405                 i=$((i + 1))
27406         done
27407         for (( i=0; i < $num; i++ )); do
27408                 wait ${pids[$i]}
27409         done
27410         check_lsom_size $DIR/$tfile $size
27411
27412         # verify truncate
27413         echo "Test SOM for truncate"
27414         $TRUNCATE $DIR/$tfile 1048576
27415         check_lsom_size $DIR/$tfile 1048576
27416         $TRUNCATE $DIR/$tfile 1234
27417         check_lsom_size $DIR/$tfile 1234
27418
27419         # verify SOM blocks count
27420         echo "Verify SOM block count"
27421         $TRUNCATE $DIR/$tfile 0
27422         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27423                 error "failed to write file $tfile"
27424         check_lsom_data $DIR/$tfile
27425 }
27426 run_test 806 "Verify Lazy Size on MDS"
27427
27428 test_807() {
27429         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27430         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27431                 skip "Need MDS version at least 2.11.52"
27432
27433         # Registration step
27434         changelog_register || error "changelog_register failed"
27435         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27436         changelog_users $SINGLEMDS | grep -q $cl_user ||
27437                 error "User $cl_user not found in changelog_users"
27438
27439         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27440         save_lustre_params client "llite.*.xattr_cache" > $save
27441         lctl set_param llite.*.xattr_cache=0
27442         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27443
27444         rm -rf $DIR/$tdir || error "rm $tdir failed"
27445         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27446         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27447         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27448         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27449                 error "truncate $tdir/trunc failed"
27450
27451         local bs=1048576
27452         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27453                 error "write $tfile failed"
27454
27455         # multi-client wirtes
27456         local num=$(get_node_count ${CLIENTS//,/ })
27457         local offset=0
27458         local i=0
27459
27460         echo "Test SOM for multi-client ($num) writes"
27461         touch $DIR/$tfile || error "touch $tfile failed"
27462         $TRUNCATE $DIR/$tfile 0
27463         for client in ${CLIENTS//,/ }; do
27464                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27465                 local pids[$i]=$!
27466                 i=$((i + 1))
27467                 offset=$((offset + $bs))
27468         done
27469         for (( i=0; i < $num; i++ )); do
27470                 wait ${pids[$i]}
27471         done
27472
27473         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27474         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27475         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27476         check_lsom_data $DIR/$tdir/trunc
27477         check_lsom_data $DIR/$tdir/single_dd
27478         check_lsom_data $DIR/$tfile
27479
27480         rm -rf $DIR/$tdir
27481         # Deregistration step
27482         changelog_deregister || error "changelog_deregister failed"
27483 }
27484 run_test 807 "verify LSOM syncing tool"
27485
27486 check_som_nologged()
27487 {
27488         local lines=$($LFS changelog $FSNAME-MDT0000 |
27489                 grep 'x=trusted.som' | wc -l)
27490         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27491 }
27492
27493 test_808() {
27494         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27495                 skip "Need MDS version at least 2.11.55"
27496
27497         # Registration step
27498         changelog_register || error "changelog_register failed"
27499
27500         touch $DIR/$tfile || error "touch $tfile failed"
27501         check_som_nologged
27502
27503         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27504                 error "write $tfile failed"
27505         check_som_nologged
27506
27507         $TRUNCATE $DIR/$tfile 1234
27508         check_som_nologged
27509
27510         $TRUNCATE $DIR/$tfile 1048576
27511         check_som_nologged
27512
27513         # Deregistration step
27514         changelog_deregister || error "changelog_deregister failed"
27515 }
27516 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27517
27518 check_som_nodata()
27519 {
27520         $LFS getsom $1
27521         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27522 }
27523
27524 test_809() {
27525         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27526                 skip "Need MDS version at least 2.11.56"
27527
27528         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27529                 error "failed to create DoM-only file $DIR/$tfile"
27530         touch $DIR/$tfile || error "touch $tfile failed"
27531         check_som_nodata $DIR/$tfile
27532
27533         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27534                 error "write $tfile failed"
27535         check_som_nodata $DIR/$tfile
27536
27537         $TRUNCATE $DIR/$tfile 1234
27538         check_som_nodata $DIR/$tfile
27539
27540         $TRUNCATE $DIR/$tfile 4097
27541         check_som_nodata $DIR/$file
27542 }
27543 run_test 809 "Verify no SOM xattr store for DoM-only files"
27544
27545 test_810() {
27546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27547         $GSS && skip_env "could not run with gss"
27548         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27549                 skip "OST < 2.12.58 doesn't align checksum"
27550
27551         set_checksums 1
27552         stack_trap "set_checksums $ORIG_CSUM" EXIT
27553         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27554
27555         local csum
27556         local before
27557         local after
27558         for csum in $CKSUM_TYPES; do
27559                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27560                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27561                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27562                         eval set -- $i
27563                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27564                         before=$(md5sum $DIR/$tfile)
27565                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27566                         after=$(md5sum $DIR/$tfile)
27567                         [ "$before" == "$after" ] ||
27568                                 error "$csum: $before != $after bs=$1 seek=$2"
27569                 done
27570         done
27571 }
27572 run_test 810 "partial page writes on ZFS (LU-11663)"
27573
27574 test_812a() {
27575         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27576                 skip "OST < 2.12.51 doesn't support this fail_loc"
27577
27578         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27579         # ensure ost1 is connected
27580         stat $DIR/$tfile >/dev/null || error "can't stat"
27581         wait_osc_import_state client ost1 FULL
27582         # no locks, no reqs to let the connection idle
27583         cancel_lru_locks osc
27584
27585         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27586 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27587         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27588         wait_osc_import_state client ost1 CONNECTING
27589         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27590
27591         stat $DIR/$tfile >/dev/null || error "can't stat file"
27592 }
27593 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27594
27595 test_812b() { # LU-12378
27596         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27597                 skip "OST < 2.12.51 doesn't support this fail_loc"
27598
27599         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27600         # ensure ost1 is connected
27601         stat $DIR/$tfile >/dev/null || error "can't stat"
27602         wait_osc_import_state client ost1 FULL
27603         # no locks, no reqs to let the connection idle
27604         cancel_lru_locks osc
27605
27606         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27607 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27608         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27609         wait_osc_import_state client ost1 CONNECTING
27610         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27611
27612         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27613         wait_osc_import_state client ost1 IDLE
27614 }
27615 run_test 812b "do not drop no resend request for idle connect"
27616
27617 test_812c() {
27618         local old
27619
27620         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27621
27622         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27623         $LFS getstripe $DIR/$tfile
27624         $LCTL set_param osc.*.idle_timeout=10
27625         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27626         # ensure ost1 is connected
27627         stat $DIR/$tfile >/dev/null || error "can't stat"
27628         wait_osc_import_state client ost1 FULL
27629         # no locks, no reqs to let the connection idle
27630         cancel_lru_locks osc
27631
27632 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27633         $LCTL set_param fail_loc=0x80000533
27634         sleep 15
27635         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27636 }
27637 run_test 812c "idle import vs lock enqueue race"
27638
27639 test_813() {
27640         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27641         [ -z "$file_heat_sav" ] && skip "no file heat support"
27642
27643         local readsample
27644         local writesample
27645         local readbyte
27646         local writebyte
27647         local readsample1
27648         local writesample1
27649         local readbyte1
27650         local writebyte1
27651
27652         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27653         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27654
27655         $LCTL set_param -n llite.*.file_heat=1
27656         echo "Turn on file heat"
27657         echo "Period second: $period_second, Decay percentage: $decay_pct"
27658
27659         echo "QQQQ" > $DIR/$tfile
27660         echo "QQQQ" > $DIR/$tfile
27661         echo "QQQQ" > $DIR/$tfile
27662         cat $DIR/$tfile > /dev/null
27663         cat $DIR/$tfile > /dev/null
27664         cat $DIR/$tfile > /dev/null
27665         cat $DIR/$tfile > /dev/null
27666
27667         local out=$($LFS heat_get $DIR/$tfile)
27668
27669         $LFS heat_get $DIR/$tfile
27670         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27671         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27672         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27673         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27674
27675         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27676         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27677         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27678         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27679
27680         sleep $((period_second + 3))
27681         echo "Sleep $((period_second + 3)) seconds..."
27682         # The recursion formula to calculate the heat of the file f is as
27683         # follow:
27684         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27685         # Where Hi is the heat value in the period between time points i*I and
27686         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27687         # to the weight of Ci.
27688         out=$($LFS heat_get $DIR/$tfile)
27689         $LFS heat_get $DIR/$tfile
27690         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27691         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27692         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27693         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27694
27695         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27696                 error "read sample ($readsample) is wrong"
27697         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27698                 error "write sample ($writesample) is wrong"
27699         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27700                 error "read bytes ($readbyte) is wrong"
27701         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27702                 error "write bytes ($writebyte) is wrong"
27703
27704         echo "QQQQ" > $DIR/$tfile
27705         echo "QQQQ" > $DIR/$tfile
27706         echo "QQQQ" > $DIR/$tfile
27707         cat $DIR/$tfile > /dev/null
27708         cat $DIR/$tfile > /dev/null
27709         cat $DIR/$tfile > /dev/null
27710         cat $DIR/$tfile > /dev/null
27711
27712         sleep $((period_second + 3))
27713         echo "Sleep $((period_second + 3)) seconds..."
27714
27715         out=$($LFS heat_get $DIR/$tfile)
27716         $LFS heat_get $DIR/$tfile
27717         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27718         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27719         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27720         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27721
27722         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27723                 4 * $decay_pct) / 100") -eq 1 ] ||
27724                 error "read sample ($readsample1) is wrong"
27725         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27726                 3 * $decay_pct) / 100") -eq 1 ] ||
27727                 error "write sample ($writesample1) is wrong"
27728         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27729                 20 * $decay_pct) / 100") -eq 1 ] ||
27730                 error "read bytes ($readbyte1) is wrong"
27731         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27732                 15 * $decay_pct) / 100") -eq 1 ] ||
27733                 error "write bytes ($writebyte1) is wrong"
27734
27735         echo "Turn off file heat for the file $DIR/$tfile"
27736         $LFS heat_set -o $DIR/$tfile
27737
27738         echo "QQQQ" > $DIR/$tfile
27739         echo "QQQQ" > $DIR/$tfile
27740         echo "QQQQ" > $DIR/$tfile
27741         cat $DIR/$tfile > /dev/null
27742         cat $DIR/$tfile > /dev/null
27743         cat $DIR/$tfile > /dev/null
27744         cat $DIR/$tfile > /dev/null
27745
27746         out=$($LFS heat_get $DIR/$tfile)
27747         $LFS heat_get $DIR/$tfile
27748         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27749         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27750         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27751         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27752
27753         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27754         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27755         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27756         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27757
27758         echo "Trun on file heat for the file $DIR/$tfile"
27759         $LFS heat_set -O $DIR/$tfile
27760
27761         echo "QQQQ" > $DIR/$tfile
27762         echo "QQQQ" > $DIR/$tfile
27763         echo "QQQQ" > $DIR/$tfile
27764         cat $DIR/$tfile > /dev/null
27765         cat $DIR/$tfile > /dev/null
27766         cat $DIR/$tfile > /dev/null
27767         cat $DIR/$tfile > /dev/null
27768
27769         out=$($LFS heat_get $DIR/$tfile)
27770         $LFS heat_get $DIR/$tfile
27771         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27772         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27773         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27774         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27775
27776         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27777         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27778         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27779         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27780
27781         $LFS heat_set -c $DIR/$tfile
27782         $LCTL set_param -n llite.*.file_heat=0
27783         echo "Turn off file heat support for the Lustre filesystem"
27784
27785         echo "QQQQ" > $DIR/$tfile
27786         echo "QQQQ" > $DIR/$tfile
27787         echo "QQQQ" > $DIR/$tfile
27788         cat $DIR/$tfile > /dev/null
27789         cat $DIR/$tfile > /dev/null
27790         cat $DIR/$tfile > /dev/null
27791         cat $DIR/$tfile > /dev/null
27792
27793         out=$($LFS heat_get $DIR/$tfile)
27794         $LFS heat_get $DIR/$tfile
27795         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27796         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27797         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27798         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27799
27800         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27801         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27802         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27803         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27804
27805         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27806         rm -f $DIR/$tfile
27807 }
27808 run_test 813 "File heat verfication"
27809
27810 test_814()
27811 {
27812         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27813         echo -n y >> $DIR/$tfile
27814         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27815         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27816 }
27817 run_test 814 "sparse cp works as expected (LU-12361)"
27818
27819 test_815()
27820 {
27821         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27822         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27823 }
27824 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27825
27826 test_816() {
27827         local ost1_imp=$(get_osc_import_name client ost1)
27828         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27829                          cut -d'.' -f2)
27830
27831         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27832         # ensure ost1 is connected
27833
27834         stat $DIR/$tfile >/dev/null || error "can't stat"
27835         wait_osc_import_state client ost1 FULL
27836         # no locks, no reqs to let the connection idle
27837         cancel_lru_locks osc
27838         lru_resize_disable osc
27839         local before
27840         local now
27841         before=$($LCTL get_param -n \
27842                  ldlm.namespaces.$imp_name.lru_size)
27843
27844         wait_osc_import_state client ost1 IDLE
27845         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27846         now=$($LCTL get_param -n \
27847               ldlm.namespaces.$imp_name.lru_size)
27848         [ $before == $now ] || error "lru_size changed $before != $now"
27849 }
27850 run_test 816 "do not reset lru_resize on idle reconnect"
27851
27852 cleanup_817() {
27853         umount $tmpdir
27854         exportfs -u localhost:$DIR/nfsexp
27855         rm -rf $DIR/nfsexp
27856 }
27857
27858 test_817() {
27859         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27860
27861         mkdir -p $DIR/nfsexp
27862         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27863                 error "failed to export nfs"
27864
27865         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27866         stack_trap cleanup_817 EXIT
27867
27868         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27869                 error "failed to mount nfs to $tmpdir"
27870
27871         cp /bin/true $tmpdir
27872         $DIR/nfsexp/true || error "failed to execute 'true' command"
27873 }
27874 run_test 817 "nfsd won't cache write lock for exec file"
27875
27876 test_818() {
27877         test_mkdir -i0 -c1 $DIR/$tdir
27878         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
27879         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
27880         stop $SINGLEMDS
27881
27882         # restore osp-syn threads
27883         stack_trap "fail $SINGLEMDS"
27884
27885         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27886         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27887         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27888                 error "start $SINGLEMDS failed"
27889         rm -rf $DIR/$tdir
27890
27891         local testid=$(echo $TESTNAME | tr '_' ' ')
27892
27893         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
27894                 grep "run LFSCK" || error "run LFSCK is not suggested"
27895 }
27896 run_test 818 "unlink with failed llog"
27897
27898 test_819a() {
27899         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27900         cancel_lru_locks osc
27901         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27902         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27903         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27904         rm -f $TDIR/$tfile
27905 }
27906 run_test 819a "too big niobuf in read"
27907
27908 test_819b() {
27909         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27910         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27911         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27912         cancel_lru_locks osc
27913         sleep 1
27914         rm -f $TDIR/$tfile
27915 }
27916 run_test 819b "too big niobuf in write"
27917
27918
27919 function test_820_start_ost() {
27920         sleep 5
27921
27922         for num in $(seq $OSTCOUNT); do
27923                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27924         done
27925 }
27926
27927 test_820() {
27928         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27929
27930         mkdir $DIR/$tdir
27931         umount_client $MOUNT || error "umount failed"
27932         for num in $(seq $OSTCOUNT); do
27933                 stop ost$num
27934         done
27935
27936         # mount client with no active OSTs
27937         # so that the client can't initialize max LOV EA size
27938         # from OSC notifications
27939         mount_client $MOUNT || error "mount failed"
27940         # delay OST starting to keep this 0 max EA size for a while
27941         test_820_start_ost &
27942
27943         # create a directory on MDS2
27944         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27945                 error "Failed to create directory"
27946         # open intent should update default EA size
27947         # see mdc_update_max_ea_from_body()
27948         # notice this is the very first RPC to MDS2
27949         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27950         ret=$?
27951         echo $out
27952         # With SSK, this situation can lead to -EPERM being returned.
27953         # In that case, simply retry.
27954         if [ $ret -ne 0 ] && $SHARED_KEY; then
27955                 if echo "$out" | grep -q "not permitted"; then
27956                         cp /etc/services $DIR/$tdir/mds2
27957                         ret=$?
27958                 fi
27959         fi
27960         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27961 }
27962 run_test 820 "update max EA from open intent"
27963
27964 test_822() {
27965         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27966
27967         save_lustre_params mds1 \
27968                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27969         do_facet $SINGLEMDS "$LCTL set_param -n \
27970                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27971         do_facet $SINGLEMDS "$LCTL set_param -n \
27972                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27973
27974         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27975         local maxage=$(do_facet mds1 $LCTL get_param -n \
27976                        osp.$FSNAME-OST0000*MDT0000.maxage)
27977         sleep $((maxage + 1))
27978
27979         #define OBD_FAIL_NET_ERROR_RPC          0x532
27980         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27981
27982         stack_trap "restore_lustre_params < $p; rm $p"
27983
27984         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27985                       osp.$FSNAME-OST0000*MDT0000.create_count")
27986         for i in $(seq 1 $count); do
27987                 touch $DIR/$tfile.${i} || error "touch failed"
27988         done
27989 }
27990 run_test 822 "test precreate failure"
27991
27992 test_823() {
27993         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27994         local OST_MAX_PRECREATE=20000
27995
27996         save_lustre_params mds1 \
27997                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27998         do_facet $SINGLEMDS "$LCTL set_param -n \
27999                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28000         do_facet $SINGLEMDS "$LCTL set_param -n \
28001                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28002
28003         stack_trap "restore_lustre_params < $p; rm $p"
28004
28005         do_facet $SINGLEMDS "$LCTL set_param -n \
28006                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28007
28008         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28009                       osp.$FSNAME-OST0000*MDT0000.create_count")
28010         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28011                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28012         local expect_count=$(((($max/2)/256) * 256))
28013
28014         log "setting create_count to 100200:"
28015         log " -result- count: $count with max: $max, expecting: $expect_count"
28016
28017         [[ $count -eq expect_count ]] ||
28018                 error "Create count not set to max precreate."
28019 }
28020 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28021
28022 test_831() {
28023         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28024                 skip "Need MDS version 2.14.56"
28025
28026         local sync_changes=$(do_facet $SINGLEMDS \
28027                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28028
28029         [ "$sync_changes" -gt 100 ] &&
28030                 skip "Sync changes $sync_changes > 100 already"
28031
28032         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28033
28034         $LFS mkdir -i 0 $DIR/$tdir
28035         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28036
28037         save_lustre_params mds1 \
28038                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28039         save_lustre_params mds1 \
28040                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28041
28042         do_facet mds1 "$LCTL set_param -n \
28043                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28044                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28045         stack_trap "restore_lustre_params < $p" EXIT
28046
28047         createmany -o $DIR/$tdir/f- 1000
28048         unlinkmany $DIR/$tdir/f- 1000 &
28049         local UNLINK_PID=$!
28050
28051         while sleep 1; do
28052                 sync_changes=$(do_facet mds1 \
28053                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28054                 # the check in the code is racy, fail the test
28055                 # if the value above the limit by 10.
28056                 [ $sync_changes -gt 110 ] && {
28057                         kill -2 $UNLINK_PID
28058                         wait
28059                         error "osp changes throttling failed, $sync_changes>110"
28060                 }
28061                 kill -0 $UNLINK_PID 2> /dev/null || break
28062         done
28063         wait
28064 }
28065 run_test 831 "throttling unlink/setattr queuing on OSP"
28066
28067 #
28068 # tests that do cleanup/setup should be run at the end
28069 #
28070
28071 test_900() {
28072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28073         local ls
28074
28075         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28076         $LCTL set_param fail_loc=0x903
28077
28078         cancel_lru_locks MGC
28079
28080         FAIL_ON_ERROR=true cleanup
28081         FAIL_ON_ERROR=true setup
28082 }
28083 run_test 900 "umount should not race with any mgc requeue thread"
28084
28085 # LUS-6253/LU-11185
28086 test_901() {
28087         local old
28088         local count
28089         local oldc
28090         local newc
28091         local olds
28092         local news
28093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28094
28095         # some get_param have a bug to handle dot in param name
28096         cancel_lru_locks MGC
28097         old=$(mount -t lustre | wc -l)
28098         # 1 config+sptlrpc
28099         # 2 params
28100         # 3 nodemap
28101         # 4 IR
28102         old=$((old * 4))
28103         oldc=0
28104         count=0
28105         while [ $old -ne $oldc ]; do
28106                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28107                 sleep 1
28108                 ((count++))
28109                 if [ $count -ge $TIMEOUT ]; then
28110                         error "too large timeout"
28111                 fi
28112         done
28113         umount_client $MOUNT || error "umount failed"
28114         mount_client $MOUNT || error "mount failed"
28115         cancel_lru_locks MGC
28116         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28117
28118         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28119
28120         return 0
28121 }
28122 run_test 901 "don't leak a mgc lock on client umount"
28123
28124 # LU-13377
28125 test_902() {
28126         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28127                 skip "client does not have LU-13377 fix"
28128         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28129         $LCTL set_param fail_loc=0x1415
28130         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28131         cancel_lru_locks osc
28132         rm -f $DIR/$tfile
28133 }
28134 run_test 902 "test short write doesn't hang lustre"
28135
28136 # LU-14711
28137 test_903() {
28138         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28139         echo "blah" > $DIR/${tfile}-2
28140         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28141         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28142         $LCTL set_param fail_loc=0x417 fail_val=20
28143
28144         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28145         sleep 1 # To start the destroy
28146         wait_destroy_complete 150 || error "Destroy taking too long"
28147         cat $DIR/$tfile > /dev/null || error "Evicted"
28148 }
28149 run_test 903 "Test long page discard does not cause evictions"
28150
28151 test_904() {
28152         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28153         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28154                 grep -q project || skip "skip project quota not supported"
28155
28156         local testfile="$DIR/$tdir/$tfile"
28157         local xattr="trusted.projid"
28158         local projid
28159
28160         mkdir -p $DIR/$tdir
28161         touch $testfile
28162         #should be hidden when projid is 0
28163         $LFS project -p 0 $testfile ||
28164                 error "set $testfile project id failed"
28165         getfattr -m - $testfile | grep $xattr &&
28166                 error "do not show trusted.projid with project ID 0"
28167
28168         #still can getxattr explicitly
28169         projid=$(getfattr -n $xattr $testfile |
28170                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28171         [ $projid == "0" ] ||
28172                 error "projid expected 0 not $projid"
28173
28174         #set the projid via setxattr
28175         setfattr -n $xattr -v "1000" $testfile ||
28176                 error "setattr failed with $?"
28177         projid=($($LFS project $testfile))
28178         [ ${projid[0]} == "1000" ] ||
28179                 error "projid expected 1000 not $projid"
28180
28181         #check the new projid via getxattr
28182         $LFS project -p 1001 $testfile ||
28183                 error "set $testfile project id failed"
28184         projid=$(getfattr -n $xattr $testfile |
28185                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28186         [ $projid == "1001" ] ||
28187                 error "projid expected 1001 not $projid"
28188
28189         #try to set invalid projid
28190         setfattr -n $xattr -v "4294967295" $testfile &&
28191                 error "set invalid projid should fail"
28192
28193         #remove the xattr means setting projid to 0
28194         setfattr -x $xattr $testfile ||
28195                 error "setfattr failed with $?"
28196         projid=($($LFS project $testfile))
28197         [ ${projid[0]} == "0" ] ||
28198                 error "projid expected 0 not $projid"
28199
28200         #should be hidden when parent has inherit flag and same projid
28201         $LFS project -srp 1002 $DIR/$tdir ||
28202                 error "set $tdir project id failed"
28203         getfattr -m - $testfile | grep $xattr &&
28204                 error "do not show trusted.projid with inherit flag"
28205
28206         #still can getxattr explicitly
28207         projid=$(getfattr -n $xattr $testfile |
28208                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28209         [ $projid == "1002" ] ||
28210                 error "projid expected 1002 not $projid"
28211 }
28212 run_test 904 "virtual project ID xattr"
28213
28214 complete $SECONDS
28215 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28216 check_and_cleanup_lustre
28217 if [ "$I_MOUNTED" != "yes" ]; then
28218         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28219 fi
28220 exit_status