Whamcloud - gitweb
LU-15445 tests: sanity test_160p() fix
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11671
61         ALWAYS_EXCEPT+=" 45"
62         # bug number:    LU-14067 LU-14067
63         ALWAYS_EXCEPT+=" 400a     400b"
64 fi
65
66 # skip nfs tests on kernels >= 4.12.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
68         # bug number:   LU-12661
69         ALWAYS_EXCEPT+=" 817"
70 fi
71 # skip cgroup tests on RHEL8.1 kernels until they are fixed
72 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
73       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
74         # bug number:   LU-13063
75         ALWAYS_EXCEPT+=" 411"
76 fi
77
78 #skip ACL tests on RHEL8 and SLES15 until tests changed to use other users
79 if (( $(egrep -cw "^bin|^daemon" /etc/passwd) < 2 )); then
80         # bug number:   LU-15259 LU-15259
81         ALWAYS_EXCEPT+=" 103a  125   154a"
82 fi
83
84 #                                  5              12     8   12  15   (min)"
85 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
86
87 if [ "$mds1_FSTYPE" = "zfs" ]; then
88         # bug number for skipped test:
89         ALWAYS_EXCEPT+="              "
90         #                                               13    (min)"
91         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
92 fi
93
94 if [ "$ost1_FSTYPE" = "zfs" ]; then
95         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
96         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
97 fi
98
99 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
100
101 # Get the SLES distro version
102 #
103 # Returns a version string that should only be used in comparing
104 # strings returned by version_code()
105 sles_version_code()
106 {
107         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
108
109         # All SuSE Linux versions have one decimal. version_code expects two
110         local sles_version=$version.0
111         version_code $sles_version
112 }
113
114 # Check if we are running on Ubuntu or SLES so we can make decisions on
115 # what tests to run
116 if [ -r /etc/SuSE-release ]; then
117         sles_version=$(sles_version_code)
118         [ $sles_version -lt $(version_code 11.4.0) ] &&
119                 # bug number for skipped test: LU-4341
120                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
121         [ $sles_version -lt $(version_code 12.0.0) ] &&
122                 # bug number for skipped test: LU-3703
123                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
124 elif [ -r /etc/os-release ]; then
125         if grep -qi ubuntu /etc/os-release; then
126                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
127                                                 -e 's/^VERSION=//p' \
128                                                 /etc/os-release |
129                                                 awk '{ print $1 }'))
130
131                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
132                         # bug number for skipped test:
133                         #                LU-10334 LU-10366
134                         ALWAYS_EXCEPT+=" 103a     410"
135                 fi
136         fi
137 fi
138
139 build_test_filter
140 FAIL_ON_ERROR=false
141
142 cleanup() {
143         echo -n "cln.."
144         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
145         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
146 }
147 setup() {
148         echo -n "mnt.."
149         load_modules
150         setupall || exit 10
151         echo "done"
152 }
153
154 check_swap_layouts_support()
155 {
156         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
157                 skip "Does not support layout lock."
158 }
159
160 check_swap_layout_no_dom()
161 {
162         local FOLDER=$1
163         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
164         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
165 }
166
167 check_and_setup_lustre
168 DIR=${DIR:-$MOUNT}
169 assert_DIR
170
171 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
172
173 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
174 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
175 rm -rf $DIR/[Rdfs][0-9]*
176
177 # $RUNAS_ID may get set incorrectly somewhere else
178 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
179         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
180
181 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
182
183 if [ "${ONLY}" = "MOUNT" ] ; then
184         echo "Lustre is up, please go on"
185         exit
186 fi
187
188 echo "preparing for tests involving mounts"
189 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
190 touch $EXT2_DEV
191 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
192 echo # add a newline after mke2fs.
193
194 umask 077
195
196 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
197 lctl set_param debug=-1 2> /dev/null || true
198 test_0a() {
199         touch $DIR/$tfile
200         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
201         rm $DIR/$tfile
202         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
203 }
204 run_test 0a "touch; rm ====================="
205
206 test_0b() {
207         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
208         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
209 }
210 run_test 0b "chmod 0755 $DIR ============================="
211
212 test_0c() {
213         $LCTL get_param mdc.*.import | grep "state: FULL" ||
214                 error "import not FULL"
215         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
216                 error "bad target"
217 }
218 run_test 0c "check import proc"
219
220 test_0d() { # LU-3397
221         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
222                 skip "proc exports not supported before 2.10.57"
223
224         local mgs_exp="mgs.MGS.exports"
225         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
226         local exp_client_nid
227         local exp_client_version
228         local exp_val
229         local imp_val
230         local temp_imp=$DIR/$tfile.import
231         local temp_exp=$DIR/$tfile.export
232
233         # save mgc import file to $temp_imp
234         $LCTL get_param mgc.*.import | tee $temp_imp
235         # Check if client uuid is found in MGS export
236         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
237                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
238                         $client_uuid ] &&
239                         break;
240         done
241         # save mgs export file to $temp_exp
242         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
243
244         # Compare the value of field "connect_flags"
245         imp_val=$(grep "connect_flags" $temp_imp)
246         exp_val=$(grep "connect_flags" $temp_exp)
247         [ "$exp_val" == "$imp_val" ] ||
248                 error "export flags '$exp_val' != import flags '$imp_val'"
249
250         # Compare client versions.  Only compare top-3 fields for compatibility
251         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
252         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
253         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
254         [ "$exp_val" == "$imp_val" ] ||
255                 error "exp version '$exp_client_version'($exp_val) != " \
256                         "'$(lustre_build_version client)'($imp_val)"
257 }
258 run_test 0d "check export proc ============================="
259
260 test_0e() { # LU-13417
261         (( $MDSCOUNT > 1 )) ||
262                 skip "We need at least 2 MDTs for this test"
263
264         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
265                 skip "Need server version at least 2.14.51"
266
267         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
268         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
269
270         [ $default_lmv_count -eq 1 ] ||
271                 error "$MOUNT default stripe count $default_lmv_count"
272
273         [ $default_lmv_index -eq -1 ] ||
274                 error "$MOUNT default stripe index $default_lmv_index"
275
276         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
277         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
278
279         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
280         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
281
282         [ $mdt_index1 -eq $mdt_index2 ] &&
283                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
284
285         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
286 }
287 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
288
289 test_1() {
290         test_mkdir $DIR/$tdir
291         test_mkdir $DIR/$tdir/d2
292         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
293         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
294         rmdir $DIR/$tdir/d2
295         rmdir $DIR/$tdir
296         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
297 }
298 run_test 1 "mkdir; remkdir; rmdir"
299
300 test_2() {
301         test_mkdir $DIR/$tdir
302         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
303         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
304         rm -r $DIR/$tdir
305         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
306 }
307 run_test 2 "mkdir; touch; rmdir; check file"
308
309 test_3() {
310         test_mkdir $DIR/$tdir
311         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
312         touch $DIR/$tdir/$tfile
313         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
314         rm -r $DIR/$tdir
315         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
316 }
317 run_test 3 "mkdir; touch; rmdir; check dir"
318
319 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
320 test_4() {
321         test_mkdir -i 1 $DIR/$tdir
322
323         touch $DIR/$tdir/$tfile ||
324                 error "Create file under remote directory failed"
325
326         rmdir $DIR/$tdir &&
327                 error "Expect error removing in-use dir $DIR/$tdir"
328
329         test -d $DIR/$tdir || error "Remote directory disappeared"
330
331         rm -rf $DIR/$tdir || error "remove remote dir error"
332 }
333 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
334
335 test_5() {
336         test_mkdir $DIR/$tdir
337         test_mkdir $DIR/$tdir/d2
338         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
339         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
340         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
341 }
342 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
343
344 test_6a() {
345         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
346         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
347         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
348                 error "$tfile does not have perm 0666 or UID $UID"
349         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
350         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
351                 error "$tfile should be 0666 and owned by UID $UID"
352 }
353 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
354
355 test_6c() {
356         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
357
358         touch $DIR/$tfile
359         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
360         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
361                 error "$tfile should be owned by UID $RUNAS_ID"
362         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
363         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
364                 error "$tfile should be owned by UID $RUNAS_ID"
365 }
366 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
367
368 test_6e() {
369         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
370
371         touch $DIR/$tfile
372         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
373         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
374                 error "$tfile should be owned by GID $UID"
375         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
376         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
377                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
378 }
379 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
380
381 test_6g() {
382         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
383
384         test_mkdir $DIR/$tdir
385         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
386         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
387         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
388         test_mkdir $DIR/$tdir/d/subdir
389         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
390                 error "$tdir/d/subdir should be GID $RUNAS_GID"
391         if [[ $MDSCOUNT -gt 1 ]]; then
392                 # check remote dir sgid inherite
393                 $LFS mkdir -i 0 $DIR/$tdir.local ||
394                         error "mkdir $tdir.local failed"
395                 chmod g+s $DIR/$tdir.local ||
396                         error "chmod $tdir.local failed"
397                 chgrp $RUNAS_GID $DIR/$tdir.local ||
398                         error "chgrp $tdir.local failed"
399                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
400                         error "mkdir $tdir.remote failed"
401                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
402                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
403                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
404                         error "$tdir.remote should be mode 02755"
405         fi
406 }
407 run_test 6g "verify new dir in sgid dir inherits group"
408
409 test_6h() { # bug 7331
410         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
411
412         touch $DIR/$tfile || error "touch failed"
413         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
414         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
415                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
416         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
417                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
418 }
419 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
420
421 test_7a() {
422         test_mkdir $DIR/$tdir
423         $MCREATE $DIR/$tdir/$tfile
424         chmod 0666 $DIR/$tdir/$tfile
425         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
426                 error "$tdir/$tfile should be mode 0666"
427 }
428 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
429
430 test_7b() {
431         if [ ! -d $DIR/$tdir ]; then
432                 test_mkdir $DIR/$tdir
433         fi
434         $MCREATE $DIR/$tdir/$tfile
435         echo -n foo > $DIR/$tdir/$tfile
436         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
437         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
438 }
439 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
440
441 test_8() {
442         test_mkdir $DIR/$tdir
443         touch $DIR/$tdir/$tfile
444         chmod 0666 $DIR/$tdir/$tfile
445         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
446                 error "$tfile mode not 0666"
447 }
448 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
449
450 test_9() {
451         test_mkdir $DIR/$tdir
452         test_mkdir $DIR/$tdir/d2
453         test_mkdir $DIR/$tdir/d2/d3
454         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
455 }
456 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
457
458 test_10() {
459         test_mkdir $DIR/$tdir
460         test_mkdir $DIR/$tdir/d2
461         touch $DIR/$tdir/d2/$tfile
462         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
463                 error "$tdir/d2/$tfile not a file"
464 }
465 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
466
467 test_11() {
468         test_mkdir $DIR/$tdir
469         test_mkdir $DIR/$tdir/d2
470         chmod 0666 $DIR/$tdir/d2
471         chmod 0705 $DIR/$tdir/d2
472         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
473                 error "$tdir/d2 mode not 0705"
474 }
475 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
476
477 test_12() {
478         test_mkdir $DIR/$tdir
479         touch $DIR/$tdir/$tfile
480         chmod 0666 $DIR/$tdir/$tfile
481         chmod 0654 $DIR/$tdir/$tfile
482         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
483                 error "$tdir/d2 mode not 0654"
484 }
485 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
486
487 test_13() {
488         test_mkdir $DIR/$tdir
489         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
490         >  $DIR/$tdir/$tfile
491         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
492                 error "$tdir/$tfile size not 0 after truncate"
493 }
494 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
495
496 test_14() {
497         test_mkdir $DIR/$tdir
498         touch $DIR/$tdir/$tfile
499         rm $DIR/$tdir/$tfile
500         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
501 }
502 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
503
504 test_15() {
505         test_mkdir $DIR/$tdir
506         touch $DIR/$tdir/$tfile
507         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
508         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
509                 error "$tdir/${tfile_2} not a file after rename"
510         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
511 }
512 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
513
514 test_16() {
515         test_mkdir $DIR/$tdir
516         touch $DIR/$tdir/$tfile
517         rm -rf $DIR/$tdir/$tfile
518         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
519 }
520 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
521
522 test_17a() {
523         test_mkdir $DIR/$tdir
524         touch $DIR/$tdir/$tfile
525         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
526         ls -l $DIR/$tdir
527         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
528                 error "$tdir/l-exist not a symlink"
529         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
530                 error "$tdir/l-exist not referencing a file"
531         rm -f $DIR/$tdir/l-exist
532         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
533 }
534 run_test 17a "symlinks: create, remove (real)"
535
536 test_17b() {
537         test_mkdir $DIR/$tdir
538         ln -s no-such-file $DIR/$tdir/l-dangle
539         ls -l $DIR/$tdir
540         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
541                 error "$tdir/l-dangle not referencing no-such-file"
542         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
543                 error "$tdir/l-dangle not referencing non-existent file"
544         rm -f $DIR/$tdir/l-dangle
545         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
546 }
547 run_test 17b "symlinks: create, remove (dangling)"
548
549 test_17c() { # bug 3440 - don't save failed open RPC for replay
550         test_mkdir $DIR/$tdir
551         ln -s foo $DIR/$tdir/$tfile
552         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
553 }
554 run_test 17c "symlinks: open dangling (should return error)"
555
556 test_17d() {
557         test_mkdir $DIR/$tdir
558         ln -s foo $DIR/$tdir/$tfile
559         touch $DIR/$tdir/$tfile || error "creating to new symlink"
560 }
561 run_test 17d "symlinks: create dangling"
562
563 test_17e() {
564         test_mkdir $DIR/$tdir
565         local foo=$DIR/$tdir/$tfile
566         ln -s $foo $foo || error "create symlink failed"
567         ls -l $foo || error "ls -l failed"
568         ls $foo && error "ls not failed" || true
569 }
570 run_test 17e "symlinks: create recursive symlink (should return error)"
571
572 test_17f() {
573         test_mkdir $DIR/$tdir
574         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
575         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
576         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
577         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
578         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
579         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
580         ls -l  $DIR/$tdir
581 }
582 run_test 17f "symlinks: long and very long symlink name"
583
584 # str_repeat(S, N) generate a string that is string S repeated N times
585 str_repeat() {
586         local s=$1
587         local n=$2
588         local ret=''
589         while [ $((n -= 1)) -ge 0 ]; do
590                 ret=$ret$s
591         done
592         echo $ret
593 }
594
595 # Long symlinks and LU-2241
596 test_17g() {
597         test_mkdir $DIR/$tdir
598         local TESTS="59 60 61 4094 4095"
599
600         # Fix for inode size boundary in 2.1.4
601         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
602                 TESTS="4094 4095"
603
604         # Patch not applied to 2.2 or 2.3 branches
605         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
606         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
607                 TESTS="4094 4095"
608
609         for i in $TESTS; do
610                 local SYMNAME=$(str_repeat 'x' $i)
611                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
612                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
613         done
614 }
615 run_test 17g "symlinks: really long symlink name and inode boundaries"
616
617 test_17h() { #bug 17378
618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
619         remote_mds_nodsh && skip "remote MDS with nodsh"
620
621         local mdt_idx
622
623         test_mkdir $DIR/$tdir
624         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
625         $LFS setstripe -c -1 $DIR/$tdir
626         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
627         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
628         touch $DIR/$tdir/$tfile || true
629 }
630 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
631
632 test_17i() { #bug 20018
633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
634         remote_mds_nodsh && skip "remote MDS with nodsh"
635
636         local foo=$DIR/$tdir/$tfile
637         local mdt_idx
638
639         test_mkdir -c1 $DIR/$tdir
640         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
641         ln -s $foo $foo || error "create symlink failed"
642 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
643         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
644         ls -l $foo && error "error not detected"
645         return 0
646 }
647 run_test 17i "don't panic on short symlink (should return error)"
648
649 test_17k() { #bug 22301
650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
651         [[ -z "$(which rsync 2>/dev/null)" ]] &&
652                 skip "no rsync command"
653         rsync --help | grep -q xattr ||
654                 skip_env "$(rsync --version | head -n1) does not support xattrs"
655         test_mkdir $DIR/$tdir
656         test_mkdir $DIR/$tdir.new
657         touch $DIR/$tdir/$tfile
658         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
659         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
660                 error "rsync failed with xattrs enabled"
661 }
662 run_test 17k "symlinks: rsync with xattrs enabled"
663
664 test_17l() { # LU-279
665         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
666                 skip "no getfattr command"
667
668         test_mkdir $DIR/$tdir
669         touch $DIR/$tdir/$tfile
670         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
671         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
672                 # -h to not follow symlinks. -m '' to list all the xattrs.
673                 # grep to remove first line: '# file: $path'.
674                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
675                 do
676                         lgetxattr_size_check $path $xattr ||
677                                 error "lgetxattr_size_check $path $xattr failed"
678                 done
679         done
680 }
681 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
682
683 # LU-1540
684 test_17m() {
685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
686         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
687         remote_mds_nodsh && skip "remote MDS with nodsh"
688         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
689         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
690                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
691
692         local short_sym="0123456789"
693         local wdir=$DIR/$tdir
694         local i
695
696         test_mkdir $wdir
697         long_sym=$short_sym
698         # create a long symlink file
699         for ((i = 0; i < 4; ++i)); do
700                 long_sym=${long_sym}${long_sym}
701         done
702
703         echo "create 512 short and long symlink files under $wdir"
704         for ((i = 0; i < 256; ++i)); do
705                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
706                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
707         done
708
709         echo "erase them"
710         rm -f $wdir/*
711         sync
712         wait_delete_completed
713
714         echo "recreate the 512 symlink files with a shorter string"
715         for ((i = 0; i < 512; ++i)); do
716                 # rewrite the symlink file with a shorter string
717                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
718                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
719         done
720
721         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
722         local devname=$(mdsdevname $mds_index)
723
724         echo "stop and checking mds${mds_index}:"
725         # e2fsck should not return error
726         stop mds${mds_index}
727         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
728         rc=$?
729
730         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
731                 error "start mds${mds_index} failed"
732         df $MOUNT > /dev/null 2>&1
733         [ $rc -eq 0 ] ||
734                 error "e2fsck detected error for short/long symlink: rc=$rc"
735         rm -f $wdir/*
736 }
737 run_test 17m "run e2fsck against MDT which contains short/long symlink"
738
739 check_fs_consistency_17n() {
740         local mdt_index
741         local rc=0
742
743         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
744         # so it only check MDT1/MDT2 instead of all of MDTs.
745         for mdt_index in 1 2; do
746                 local devname=$(mdsdevname $mdt_index)
747                 # e2fsck should not return error
748                 stop mds${mdt_index}
749                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
750                         rc=$((rc + $?))
751
752                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
753                         error "mount mds$mdt_index failed"
754                 df $MOUNT > /dev/null 2>&1
755         done
756         return $rc
757 }
758
759 test_17n() {
760         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
762         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
763         remote_mds_nodsh && skip "remote MDS with nodsh"
764         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
765         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
766                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
767
768         local i
769
770         test_mkdir $DIR/$tdir
771         for ((i=0; i<10; i++)); do
772                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
773                         error "create remote dir error $i"
774                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
775                         error "create files under remote dir failed $i"
776         done
777
778         check_fs_consistency_17n ||
779                 error "e2fsck report error after create files under remote dir"
780
781         for ((i = 0; i < 10; i++)); do
782                 rm -rf $DIR/$tdir/remote_dir_${i} ||
783                         error "destroy remote dir error $i"
784         done
785
786         check_fs_consistency_17n ||
787                 error "e2fsck report error after unlink files under remote dir"
788
789         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
790                 skip "lustre < 2.4.50 does not support migrate mv"
791
792         for ((i = 0; i < 10; i++)); do
793                 mkdir -p $DIR/$tdir/remote_dir_${i}
794                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
795                         error "create files under remote dir failed $i"
796                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
797                         error "migrate remote dir error $i"
798         done
799         check_fs_consistency_17n || error "e2fsck report error after migration"
800
801         for ((i = 0; i < 10; i++)); do
802                 rm -rf $DIR/$tdir/remote_dir_${i} ||
803                         error "destroy remote dir error $i"
804         done
805
806         check_fs_consistency_17n || error "e2fsck report error after unlink"
807 }
808 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
809
810 test_17o() {
811         remote_mds_nodsh && skip "remote MDS with nodsh"
812         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
813                 skip "Need MDS version at least 2.3.64"
814
815         local wdir=$DIR/${tdir}o
816         local mdt_index
817         local rc=0
818
819         test_mkdir $wdir
820         touch $wdir/$tfile
821         mdt_index=$($LFS getstripe -m $wdir/$tfile)
822         mdt_index=$((mdt_index + 1))
823
824         cancel_lru_locks mdc
825         #fail mds will wait the failover finish then set
826         #following fail_loc to avoid interfer the recovery process.
827         fail mds${mdt_index}
828
829         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
830         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
831         ls -l $wdir/$tfile && rc=1
832         do_facet mds${mdt_index} lctl set_param fail_loc=0
833         [[ $rc -eq 0 ]] || error "stat file should fail"
834 }
835 run_test 17o "stat file with incompat LMA feature"
836
837 test_18() {
838         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
839         ls $DIR || error "Failed to ls $DIR: $?"
840 }
841 run_test 18 "touch .../f ; ls ... =============================="
842
843 test_19a() {
844         touch $DIR/$tfile
845         ls -l $DIR
846         rm $DIR/$tfile
847         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
848 }
849 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
850
851 test_19b() {
852         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
853 }
854 run_test 19b "ls -l .../f19 (should return error) =============="
855
856 test_19c() {
857         [ $RUNAS_ID -eq $UID ] &&
858                 skip_env "RUNAS_ID = UID = $UID -- skipping"
859
860         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
861 }
862 run_test 19c "$RUNAS touch .../f19 (should return error) =="
863
864 test_19d() {
865         cat $DIR/f19 && error || true
866 }
867 run_test 19d "cat .../f19 (should return error) =============="
868
869 test_20() {
870         touch $DIR/$tfile
871         rm $DIR/$tfile
872         touch $DIR/$tfile
873         rm $DIR/$tfile
874         touch $DIR/$tfile
875         rm $DIR/$tfile
876         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
877 }
878 run_test 20 "touch .../f ; ls -l ..."
879
880 test_21() {
881         test_mkdir $DIR/$tdir
882         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
883         ln -s dangle $DIR/$tdir/link
884         echo foo >> $DIR/$tdir/link
885         cat $DIR/$tdir/dangle
886         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
887         $CHECKSTAT -f -t file $DIR/$tdir/link ||
888                 error "$tdir/link not linked to a file"
889 }
890 run_test 21 "write to dangling link"
891
892 test_22() {
893         local wdir=$DIR/$tdir
894         test_mkdir $wdir
895         chown $RUNAS_ID:$RUNAS_GID $wdir
896         (cd $wdir || error "cd $wdir failed";
897                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
898                 $RUNAS tar xf -)
899         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
900         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
901         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
902                 error "checkstat -u failed"
903 }
904 run_test 22 "unpack tar archive as non-root user"
905
906 # was test_23
907 test_23a() {
908         test_mkdir $DIR/$tdir
909         local file=$DIR/$tdir/$tfile
910
911         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
912         openfile -f O_CREAT:O_EXCL $file &&
913                 error "$file recreate succeeded" || true
914 }
915 run_test 23a "O_CREAT|O_EXCL in subdir"
916
917 test_23b() { # bug 18988
918         test_mkdir $DIR/$tdir
919         local file=$DIR/$tdir/$tfile
920
921         rm -f $file
922         echo foo > $file || error "write filed"
923         echo bar >> $file || error "append filed"
924         $CHECKSTAT -s 8 $file || error "wrong size"
925         rm $file
926 }
927 run_test 23b "O_APPEND check"
928
929 # LU-9409, size with O_APPEND and tiny writes
930 test_23c() {
931         local file=$DIR/$tfile
932
933         # single dd
934         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
935         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
936         rm -f $file
937
938         # racing tiny writes
939         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
940         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
941         wait
942         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
943         rm -f $file
944
945         #racing tiny & normal writes
946         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
947         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
948         wait
949         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
950         rm -f $file
951
952         #racing tiny & normal writes 2, ugly numbers
953         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
954         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
955         wait
956         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
957         rm -f $file
958 }
959 run_test 23c "O_APPEND size checks for tiny writes"
960
961 # LU-11069 file offset is correct after appending writes
962 test_23d() {
963         local file=$DIR/$tfile
964         local offset
965
966         echo CentaurHauls > $file
967         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
968         if ((offset != 26)); then
969                 error "wrong offset, expected 26, got '$offset'"
970         fi
971 }
972 run_test 23d "file offset is correct after appending writes"
973
974 # rename sanity
975 test_24a() {
976         echo '-- same directory rename'
977         test_mkdir $DIR/$tdir
978         touch $DIR/$tdir/$tfile.1
979         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
980         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
981 }
982 run_test 24a "rename file to non-existent target"
983
984 test_24b() {
985         test_mkdir $DIR/$tdir
986         touch $DIR/$tdir/$tfile.{1,2}
987         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
988         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
989         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
990 }
991 run_test 24b "rename file to existing target"
992
993 test_24c() {
994         test_mkdir $DIR/$tdir
995         test_mkdir $DIR/$tdir/d$testnum.1
996         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
997         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
998         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
999 }
1000 run_test 24c "rename directory to non-existent target"
1001
1002 test_24d() {
1003         test_mkdir -c1 $DIR/$tdir
1004         test_mkdir -c1 $DIR/$tdir/d$testnum.1
1005         test_mkdir -c1 $DIR/$tdir/d$testnum.2
1006         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1007         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1008         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1009 }
1010 run_test 24d "rename directory to existing target"
1011
1012 test_24e() {
1013         echo '-- cross directory renames --'
1014         test_mkdir $DIR/R5a
1015         test_mkdir $DIR/R5b
1016         touch $DIR/R5a/f
1017         mv $DIR/R5a/f $DIR/R5b/g
1018         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1019         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1020 }
1021 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1022
1023 test_24f() {
1024         test_mkdir $DIR/R6a
1025         test_mkdir $DIR/R6b
1026         touch $DIR/R6a/f $DIR/R6b/g
1027         mv $DIR/R6a/f $DIR/R6b/g
1028         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1029         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1030 }
1031 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1032
1033 test_24g() {
1034         test_mkdir $DIR/R7a
1035         test_mkdir $DIR/R7b
1036         test_mkdir $DIR/R7a/d
1037         mv $DIR/R7a/d $DIR/R7b/e
1038         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1039         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1040 }
1041 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1042
1043 test_24h() {
1044         test_mkdir -c1 $DIR/R8a
1045         test_mkdir -c1 $DIR/R8b
1046         test_mkdir -c1 $DIR/R8a/d
1047         test_mkdir -c1 $DIR/R8b/e
1048         mrename $DIR/R8a/d $DIR/R8b/e
1049         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1050         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1051 }
1052 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1053
1054 test_24i() {
1055         echo "-- rename error cases"
1056         test_mkdir $DIR/R9
1057         test_mkdir $DIR/R9/a
1058         touch $DIR/R9/f
1059         mrename $DIR/R9/f $DIR/R9/a
1060         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1061         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1062         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1063 }
1064 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1065
1066 test_24j() {
1067         test_mkdir $DIR/R10
1068         mrename $DIR/R10/f $DIR/R10/g
1069         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1070         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1071         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1072 }
1073 run_test 24j "source does not exist ============================"
1074
1075 test_24k() {
1076         test_mkdir $DIR/R11a
1077         test_mkdir $DIR/R11a/d
1078         touch $DIR/R11a/f
1079         mv $DIR/R11a/f $DIR/R11a/d
1080         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1081         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1082 }
1083 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1084
1085 # bug 2429 - rename foo foo foo creates invalid file
1086 test_24l() {
1087         f="$DIR/f24l"
1088         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1089 }
1090 run_test 24l "Renaming a file to itself ========================"
1091
1092 test_24m() {
1093         f="$DIR/f24m"
1094         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1095         # on ext3 this does not remove either the source or target files
1096         # though the "expected" operation would be to remove the source
1097         $CHECKSTAT -t file ${f} || error "${f} missing"
1098         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1099 }
1100 run_test 24m "Renaming a file to a hard link to itself ========="
1101
1102 test_24n() {
1103     f="$DIR/f24n"
1104     # this stats the old file after it was renamed, so it should fail
1105     touch ${f}
1106     $CHECKSTAT ${f} || error "${f} missing"
1107     mv ${f} ${f}.rename
1108     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1109     $CHECKSTAT -a ${f} || error "${f} exists"
1110 }
1111 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1112
1113 test_24o() {
1114         test_mkdir $DIR/$tdir
1115         rename_many -s random -v -n 10 $DIR/$tdir
1116 }
1117 run_test 24o "rename of files during htree split"
1118
1119 test_24p() {
1120         test_mkdir $DIR/R12a
1121         test_mkdir $DIR/R12b
1122         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1123         mrename $DIR/R12a $DIR/R12b
1124         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1125         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1126         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1127         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1128 }
1129 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1130
1131 cleanup_multiop_pause() {
1132         trap 0
1133         kill -USR1 $MULTIPID
1134 }
1135
1136 test_24q() {
1137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1138
1139         test_mkdir $DIR/R13a
1140         test_mkdir $DIR/R13b
1141         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1142         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1143         MULTIPID=$!
1144
1145         trap cleanup_multiop_pause EXIT
1146         mrename $DIR/R13a $DIR/R13b
1147         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1148         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1149         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1150         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1151         cleanup_multiop_pause
1152         wait $MULTIPID || error "multiop close failed"
1153 }
1154 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1155
1156 test_24r() { #bug 3789
1157         test_mkdir $DIR/R14a
1158         test_mkdir $DIR/R14a/b
1159         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1160         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1161         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1162 }
1163 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1164
1165 test_24s() {
1166         test_mkdir $DIR/R15a
1167         test_mkdir $DIR/R15a/b
1168         test_mkdir $DIR/R15a/b/c
1169         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1170         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1171         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1172 }
1173 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1174 test_24t() {
1175         test_mkdir $DIR/R16a
1176         test_mkdir $DIR/R16a/b
1177         test_mkdir $DIR/R16a/b/c
1178         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1179         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1180         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1181 }
1182 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1183
1184 test_24u() { # bug12192
1185         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1186         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1187 }
1188 run_test 24u "create stripe file"
1189
1190 simple_cleanup_common() {
1191         local createmany=$1
1192         local rc=0
1193
1194         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1195
1196         local start=$SECONDS
1197
1198         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1199         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1200         rc=$?
1201         wait_delete_completed
1202         echo "cleanup time $((SECONDS - start))"
1203         return $rc
1204 }
1205
1206 max_pages_per_rpc() {
1207         local mdtname="$(printf "MDT%04x" ${1:-0})"
1208         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1209 }
1210
1211 test_24v() {
1212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1213
1214         local nrfiles=${COUNT:-100000}
1215         local fname="$DIR/$tdir/$tfile"
1216
1217         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1218         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1219
1220         test_mkdir "$(dirname $fname)"
1221         # assume MDT0000 has the fewest inodes
1222         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1223         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1224         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1225
1226         stack_trap "simple_cleanup_common $nrfiles"
1227
1228         createmany -m "$fname" $nrfiles
1229
1230         cancel_lru_locks mdc
1231         lctl set_param mdc.*.stats clear
1232
1233         # was previously test_24D: LU-6101
1234         # readdir() returns correct number of entries after cursor reload
1235         local num_ls=$(ls $DIR/$tdir | wc -l)
1236         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1237         local num_all=$(ls -a $DIR/$tdir | wc -l)
1238         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1239                 [ $num_all -ne $((nrfiles + 2)) ]; then
1240                         error "Expected $nrfiles files, got $num_ls " \
1241                                 "($num_uniq unique $num_all .&..)"
1242         fi
1243         # LU-5 large readdir
1244         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1245         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1246         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1247         # take into account of overhead in lu_dirpage header and end mark in
1248         # each page, plus one in rpc_num calculation.
1249         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1250         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1251         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1252         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1253         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1254         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1255         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1256         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1257                 error "large readdir doesn't take effect: " \
1258                       "$mds_readpage should be about $rpc_max"
1259 }
1260 run_test 24v "list large directory (test hash collision, b=17560)"
1261
1262 test_24w() { # bug21506
1263         SZ1=234852
1264         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1265         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1266         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1267         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1268         [[ "$SZ1" -eq "$SZ2" ]] ||
1269                 error "Error reading at the end of the file $tfile"
1270 }
1271 run_test 24w "Reading a file larger than 4Gb"
1272
1273 test_24x() {
1274         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1276         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1277                 skip "Need MDS version at least 2.7.56"
1278
1279         local MDTIDX=1
1280         local remote_dir=$DIR/$tdir/remote_dir
1281
1282         test_mkdir $DIR/$tdir
1283         $LFS mkdir -i $MDTIDX $remote_dir ||
1284                 error "create remote directory failed"
1285
1286         test_mkdir $DIR/$tdir/src_dir
1287         touch $DIR/$tdir/src_file
1288         test_mkdir $remote_dir/tgt_dir
1289         touch $remote_dir/tgt_file
1290
1291         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1292                 error "rename dir cross MDT failed!"
1293
1294         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1295                 error "rename file cross MDT failed!"
1296
1297         touch $DIR/$tdir/ln_file
1298         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1299                 error "ln file cross MDT failed"
1300
1301         rm -rf $DIR/$tdir || error "Can not delete directories"
1302 }
1303 run_test 24x "cross MDT rename/link"
1304
1305 test_24y() {
1306         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1308
1309         local remote_dir=$DIR/$tdir/remote_dir
1310         local mdtidx=1
1311
1312         test_mkdir $DIR/$tdir
1313         $LFS mkdir -i $mdtidx $remote_dir ||
1314                 error "create remote directory failed"
1315
1316         test_mkdir $remote_dir/src_dir
1317         touch $remote_dir/src_file
1318         test_mkdir $remote_dir/tgt_dir
1319         touch $remote_dir/tgt_file
1320
1321         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1322                 error "rename subdir in the same remote dir failed!"
1323
1324         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1325                 error "rename files in the same remote dir failed!"
1326
1327         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1328                 error "link files in the same remote dir failed!"
1329
1330         rm -rf $DIR/$tdir || error "Can not delete directories"
1331 }
1332 run_test 24y "rename/link on the same dir should succeed"
1333
1334 test_24z() {
1335         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1336         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1337                 skip "Need MDS version at least 2.12.51"
1338
1339         local index
1340
1341         for index in 0 1; do
1342                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1343                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1344         done
1345
1346         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1347
1348         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1349         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1350
1351         local mdts=$(comma_list $(mdts_nodes))
1352
1353         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1354         stack_trap "do_nodes $mdts $LCTL \
1355                 set_param mdt.*.enable_remote_rename=1" EXIT
1356
1357         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1358
1359         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1360         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1361 }
1362 run_test 24z "cross-MDT rename is done as cp"
1363
1364 test_24A() { # LU-3182
1365         local NFILES=5000
1366
1367         test_mkdir $DIR/$tdir
1368         stack_trap "simple_cleanup_common $NFILES"
1369         createmany -m $DIR/$tdir/$tfile $NFILES
1370         local t=$(ls $DIR/$tdir | wc -l)
1371         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1372         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1373
1374         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1375                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1376 }
1377 run_test 24A "readdir() returns correct number of entries."
1378
1379 test_24B() { # LU-4805
1380         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1381
1382         local count
1383
1384         test_mkdir $DIR/$tdir
1385         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1386                 error "create striped dir failed"
1387
1388         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1389         [ $count -eq 2 ] || error "Expected 2, got $count"
1390
1391         touch $DIR/$tdir/striped_dir/a
1392
1393         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1394         [ $count -eq 3 ] || error "Expected 3, got $count"
1395
1396         touch $DIR/$tdir/striped_dir/.f
1397
1398         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1399         [ $count -eq 4 ] || error "Expected 4, got $count"
1400
1401         rm -rf $DIR/$tdir || error "Can not delete directories"
1402 }
1403 run_test 24B "readdir for striped dir return correct number of entries"
1404
1405 test_24C() {
1406         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1407
1408         mkdir $DIR/$tdir
1409         mkdir $DIR/$tdir/d0
1410         mkdir $DIR/$tdir/d1
1411
1412         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1413                 error "create striped dir failed"
1414
1415         cd $DIR/$tdir/d0/striped_dir
1416
1417         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1418         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1419         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1420
1421         [ "$d0_ino" = "$parent_ino" ] ||
1422                 error ".. wrong, expect $d0_ino, get $parent_ino"
1423
1424         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1425                 error "mv striped dir failed"
1426
1427         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1428
1429         [ "$d1_ino" = "$parent_ino" ] ||
1430                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1431 }
1432 run_test 24C "check .. in striped dir"
1433
1434 test_24E() {
1435         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1437
1438         mkdir -p $DIR/$tdir
1439         mkdir $DIR/$tdir/src_dir
1440         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1441                 error "create remote source failed"
1442
1443         touch $DIR/$tdir/src_dir/src_child/a
1444
1445         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1446                 error "create remote target dir failed"
1447
1448         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1449                 error "create remote target child failed"
1450
1451         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1452                 error "rename dir cross MDT failed!"
1453
1454         find $DIR/$tdir
1455
1456         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1457                 error "src_child still exists after rename"
1458
1459         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1460                 error "missing file(a) after rename"
1461
1462         rm -rf $DIR/$tdir || error "Can not delete directories"
1463 }
1464 run_test 24E "cross MDT rename/link"
1465
1466 test_24F () {
1467         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1468
1469         local repeats=1000
1470         [ "$SLOW" = "no" ] && repeats=100
1471
1472         mkdir -p $DIR/$tdir
1473
1474         echo "$repeats repeats"
1475         for ((i = 0; i < repeats; i++)); do
1476                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1477                 touch $DIR/$tdir/test/a || error "touch fails"
1478                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1479                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1480         done
1481
1482         true
1483 }
1484 run_test 24F "hash order vs readdir (LU-11330)"
1485
1486 test_24G () {
1487         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1488
1489         local ino1
1490         local ino2
1491
1492         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1493         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1494         touch $DIR/$tdir-0/f1 || error "touch f1"
1495         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1496         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1497         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1498         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1499         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1500 }
1501 run_test 24G "migrate symlink in rename"
1502
1503 test_24H() {
1504         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1505         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1506                 skip "MDT1 should be on another node"
1507
1508         test_mkdir -i 1 -c 1 $DIR/$tdir
1509 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1510         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1511         touch $DIR/$tdir/$tfile || error "touch failed"
1512 }
1513 run_test 24H "repeat FLD_QUERY rpc"
1514
1515 test_25a() {
1516         echo '== symlink sanity ============================================='
1517
1518         test_mkdir $DIR/d25
1519         ln -s d25 $DIR/s25
1520         touch $DIR/s25/foo ||
1521                 error "File creation in symlinked directory failed"
1522 }
1523 run_test 25a "create file in symlinked directory ==============="
1524
1525 test_25b() {
1526         [ ! -d $DIR/d25 ] && test_25a
1527         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1528 }
1529 run_test 25b "lookup file in symlinked directory ==============="
1530
1531 test_26a() {
1532         test_mkdir $DIR/d26
1533         test_mkdir $DIR/d26/d26-2
1534         ln -s d26/d26-2 $DIR/s26
1535         touch $DIR/s26/foo || error "File creation failed"
1536 }
1537 run_test 26a "multiple component symlink ======================="
1538
1539 test_26b() {
1540         test_mkdir -p $DIR/$tdir/d26-2
1541         ln -s $tdir/d26-2/foo $DIR/s26-2
1542         touch $DIR/s26-2 || error "File creation failed"
1543 }
1544 run_test 26b "multiple component symlink at end of lookup ======"
1545
1546 test_26c() {
1547         test_mkdir $DIR/d26.2
1548         touch $DIR/d26.2/foo
1549         ln -s d26.2 $DIR/s26.2-1
1550         ln -s s26.2-1 $DIR/s26.2-2
1551         ln -s s26.2-2 $DIR/s26.2-3
1552         chmod 0666 $DIR/s26.2-3/foo
1553 }
1554 run_test 26c "chain of symlinks"
1555
1556 # recursive symlinks (bug 439)
1557 test_26d() {
1558         ln -s d26-3/foo $DIR/d26-3
1559 }
1560 run_test 26d "create multiple component recursive symlink"
1561
1562 test_26e() {
1563         [ ! -h $DIR/d26-3 ] && test_26d
1564         rm $DIR/d26-3
1565 }
1566 run_test 26e "unlink multiple component recursive symlink"
1567
1568 # recursive symlinks (bug 7022)
1569 test_26f() {
1570         test_mkdir $DIR/$tdir
1571         test_mkdir $DIR/$tdir/$tfile
1572         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1573         test_mkdir -p lndir/bar1
1574         test_mkdir $DIR/$tdir/$tfile/$tfile
1575         cd $tfile                || error "cd $tfile failed"
1576         ln -s .. dotdot          || error "ln dotdot failed"
1577         ln -s dotdot/lndir lndir || error "ln lndir failed"
1578         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1579         output=`ls $tfile/$tfile/lndir/bar1`
1580         [ "$output" = bar1 ] && error "unexpected output"
1581         rm -r $tfile             || error "rm $tfile failed"
1582         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1583 }
1584 run_test 26f "rm -r of a directory which has recursive symlink"
1585
1586 test_27a() {
1587         test_mkdir $DIR/$tdir
1588         $LFS getstripe $DIR/$tdir
1589         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1590         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1591         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1592 }
1593 run_test 27a "one stripe file"
1594
1595 test_27b() {
1596         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1597
1598         test_mkdir $DIR/$tdir
1599         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1600         $LFS getstripe -c $DIR/$tdir/$tfile
1601         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1602                 error "two-stripe file doesn't have two stripes"
1603
1604         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1605 }
1606 run_test 27b "create and write to two stripe file"
1607
1608 # 27c family tests specific striping, setstripe -o
1609 test_27ca() {
1610         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1611         test_mkdir -p $DIR/$tdir
1612         local osts="1"
1613
1614         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1615         $LFS getstripe -i $DIR/$tdir/$tfile
1616         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1617                 error "stripe not on specified OST"
1618
1619         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1620 }
1621 run_test 27ca "one stripe on specified OST"
1622
1623 test_27cb() {
1624         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1625         test_mkdir -p $DIR/$tdir
1626         local osts="1,0"
1627         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1628         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1629         echo "$getstripe"
1630
1631         # Strip getstripe output to a space separated list of OSTs
1632         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1633                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1634         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1635                 error "stripes not on specified OSTs"
1636
1637         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1638 }
1639 run_test 27cb "two stripes on specified OSTs"
1640
1641 test_27cc() {
1642         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1643         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1644                 skip "server does not support overstriping"
1645
1646         test_mkdir -p $DIR/$tdir
1647         local osts="0,0"
1648         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1649         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1650         echo "$getstripe"
1651
1652         # Strip getstripe output to a space separated list of OSTs
1653         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1654                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1655         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1656                 error "stripes not on specified OSTs"
1657
1658         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1659 }
1660 run_test 27cc "two stripes on the same OST"
1661
1662 test_27cd() {
1663         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1664         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1665                 skip "server does not support overstriping"
1666         test_mkdir -p $DIR/$tdir
1667         local osts="0,1,1,0"
1668         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1669         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1670         echo "$getstripe"
1671
1672         # Strip getstripe output to a space separated list of OSTs
1673         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1674                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1675         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1676                 error "stripes not on specified OSTs"
1677
1678         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1679 }
1680 run_test 27cd "four stripes on two OSTs"
1681
1682 test_27ce() {
1683         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1684                 skip_env "too many osts, skipping"
1685         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1686                 skip "server does not support overstriping"
1687         # We do one more stripe than we have OSTs
1688         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1689                 skip_env "ea_inode feature disabled"
1690
1691         test_mkdir -p $DIR/$tdir
1692         local osts=""
1693         for i in $(seq 0 $OSTCOUNT);
1694         do
1695                 osts=$osts"0"
1696                 if [ $i -ne $OSTCOUNT ]; then
1697                         osts=$osts","
1698                 fi
1699         done
1700         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1701         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1702         echo "$getstripe"
1703
1704         # Strip getstripe output to a space separated list of OSTs
1705         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1706                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1707         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1708                 error "stripes not on specified OSTs"
1709
1710         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1711 }
1712 run_test 27ce "more stripes than OSTs with -o"
1713
1714 test_27cf() {
1715         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1716         local pid=0
1717
1718         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1719         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1720         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1721         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1722                 error "failed to set $osp_proc=0"
1723
1724         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1725         pid=$!
1726         sleep 1
1727         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1728         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1729                 error "failed to set $osp_proc=1"
1730         wait $pid
1731         [[ $pid -ne 0 ]] ||
1732                 error "should return error due to $osp_proc=0"
1733 }
1734 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1735
1736 test_27d() {
1737         test_mkdir $DIR/$tdir
1738         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1739                 error "setstripe failed"
1740         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1741         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1742 }
1743 run_test 27d "create file with default settings"
1744
1745 test_27e() {
1746         # LU-5839 adds check for existed layout before setting it
1747         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1748                 skip "Need MDS version at least 2.7.56"
1749
1750         test_mkdir $DIR/$tdir
1751         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1752         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1753         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1754 }
1755 run_test 27e "setstripe existing file (should return error)"
1756
1757 test_27f() {
1758         test_mkdir $DIR/$tdir
1759         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1760                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1761         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1762                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1763         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1764         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1765 }
1766 run_test 27f "setstripe with bad stripe size (should return error)"
1767
1768 test_27g() {
1769         test_mkdir $DIR/$tdir
1770         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1771         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1772                 error "$DIR/$tdir/$tfile has object"
1773 }
1774 run_test 27g "$LFS getstripe with no objects"
1775
1776 test_27ga() {
1777         test_mkdir $DIR/$tdir
1778         touch $DIR/$tdir/$tfile || error "touch failed"
1779         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1780         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1781         local rc=$?
1782         (( rc == 2 )) || error "getstripe did not return ENOENT"
1783 }
1784 run_test 27ga "$LFS getstripe with missing file (should return error)"
1785
1786 test_27i() {
1787         test_mkdir $DIR/$tdir
1788         touch $DIR/$tdir/$tfile || error "touch failed"
1789         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1790                 error "missing objects"
1791 }
1792 run_test 27i "$LFS getstripe with some objects"
1793
1794 test_27j() {
1795         test_mkdir $DIR/$tdir
1796         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1797                 error "setstripe failed" || true
1798 }
1799 run_test 27j "setstripe with bad stripe offset (should return error)"
1800
1801 test_27k() { # bug 2844
1802         test_mkdir $DIR/$tdir
1803         local file=$DIR/$tdir/$tfile
1804         local ll_max_blksize=$((4 * 1024 * 1024))
1805         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1806         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1807         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1808         dd if=/dev/zero of=$file bs=4k count=1
1809         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1810         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1811 }
1812 run_test 27k "limit i_blksize for broken user apps"
1813
1814 test_27l() {
1815         mcreate $DIR/$tfile || error "creating file"
1816         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1817                 error "setstripe should have failed" || true
1818 }
1819 run_test 27l "check setstripe permissions (should return error)"
1820
1821 test_27m() {
1822         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1823
1824         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1825                 skip_env "multiple clients -- skipping"
1826
1827         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1828                    head -n1)
1829         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1830                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1831         fi
1832         stack_trap simple_cleanup_common
1833         test_mkdir $DIR/$tdir
1834         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1835         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1836                 error "dd should fill OST0"
1837         i=2
1838         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1839                 i=$((i + 1))
1840                 [ $i -gt 256 ] && break
1841         done
1842         i=$((i + 1))
1843         touch $DIR/$tdir/$tfile.$i
1844         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1845             awk '{print $1}'| grep -w "0") ] &&
1846                 error "OST0 was full but new created file still use it"
1847         i=$((i + 1))
1848         touch $DIR/$tdir/$tfile.$i
1849         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1850             awk '{print $1}'| grep -w "0") ] &&
1851                 error "OST0 was full but new created file still use it" || true
1852 }
1853 run_test 27m "create file while OST0 was full"
1854
1855 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1856 # if the OST isn't full anymore.
1857 reset_enospc() {
1858         local ostidx=${1:-""}
1859         local delay
1860         local ready
1861         local get_prealloc
1862
1863         local list=$(comma_list $(osts_nodes))
1864         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1865
1866         do_nodes $list lctl set_param fail_loc=0
1867         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1868         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1869                 awk '{print $1 * 2;exit;}')
1870         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1871                         grep -v \"^0$\""
1872         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1873 }
1874
1875 test_27n() {
1876         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1878         remote_mds_nodsh && skip "remote MDS with nodsh"
1879         remote_ost_nodsh && skip "remote OST with nodsh"
1880
1881         reset_enospc
1882         rm -f $DIR/$tdir/$tfile
1883         exhaust_precreations 0 0x80000215
1884         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1885         touch $DIR/$tdir/$tfile || error "touch failed"
1886         $LFS getstripe $DIR/$tdir/$tfile
1887         reset_enospc
1888 }
1889 run_test 27n "create file with some full OSTs"
1890
1891 test_27o() {
1892         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1894         remote_mds_nodsh && skip "remote MDS with nodsh"
1895         remote_ost_nodsh && skip "remote OST with nodsh"
1896
1897         reset_enospc
1898         rm -f $DIR/$tdir/$tfile
1899         exhaust_all_precreations 0x215
1900
1901         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1902
1903         reset_enospc
1904         rm -rf $DIR/$tdir/*
1905 }
1906 run_test 27o "create file with all full OSTs (should error)"
1907
1908 function create_and_checktime() {
1909         local fname=$1
1910         local loops=$2
1911         local i
1912
1913         for ((i=0; i < $loops; i++)); do
1914                 local start=$SECONDS
1915                 multiop $fname-$i Oc
1916                 ((SECONDS-start < TIMEOUT)) ||
1917                         error "creation took " $((SECONDS-$start)) && return 1
1918         done
1919 }
1920
1921 test_27oo() {
1922         local mdts=$(comma_list $(mdts_nodes))
1923
1924         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1925                 skip "Need MDS version at least 2.13.57"
1926
1927         local f0=$DIR/${tfile}-0
1928         local f1=$DIR/${tfile}-1
1929
1930         wait_delete_completed
1931
1932         # refill precreated objects
1933         $LFS setstripe -i0 -c1 $f0
1934
1935         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1936         # force QoS allocation policy
1937         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1938         stack_trap "do_nodes $mdts $LCTL set_param \
1939                 lov.*.qos_threshold_rr=$saved" EXIT
1940         sleep_maxage
1941
1942         # one OST is unavailable, but still have few objects preallocated
1943         stop ost1
1944         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1945                 rm -rf $f1 $DIR/$tdir*" EXIT
1946
1947         for ((i=0; i < 7; i++)); do
1948                 mkdir $DIR/$tdir$i || error "can't create dir"
1949                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1950                         error "can't set striping"
1951         done
1952         for ((i=0; i < 7; i++)); do
1953                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1954         done
1955         wait
1956 }
1957 run_test 27oo "don't let few threads to reserve too many objects"
1958
1959 test_27p() {
1960         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1962         remote_mds_nodsh && skip "remote MDS with nodsh"
1963         remote_ost_nodsh && skip "remote OST with nodsh"
1964
1965         reset_enospc
1966         rm -f $DIR/$tdir/$tfile
1967         test_mkdir $DIR/$tdir
1968
1969         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1970         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1971         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1972
1973         exhaust_precreations 0 0x80000215
1974         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1975         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1976         $LFS getstripe $DIR/$tdir/$tfile
1977
1978         reset_enospc
1979 }
1980 run_test 27p "append to a truncated file with some full OSTs"
1981
1982 test_27q() {
1983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1985         remote_mds_nodsh && skip "remote MDS with nodsh"
1986         remote_ost_nodsh && skip "remote OST with nodsh"
1987
1988         reset_enospc
1989         rm -f $DIR/$tdir/$tfile
1990
1991         mkdir_on_mdt0 $DIR/$tdir
1992         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1993         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1994                 error "truncate $DIR/$tdir/$tfile failed"
1995         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1996
1997         exhaust_all_precreations 0x215
1998
1999         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2000         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2001
2002         reset_enospc
2003 }
2004 run_test 27q "append to truncated file with all OSTs full (should error)"
2005
2006 test_27r() {
2007         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2009         remote_mds_nodsh && skip "remote MDS with nodsh"
2010         remote_ost_nodsh && skip "remote OST with nodsh"
2011
2012         reset_enospc
2013         rm -f $DIR/$tdir/$tfile
2014         exhaust_precreations 0 0x80000215
2015
2016         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2017
2018         reset_enospc
2019 }
2020 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2021
2022 test_27s() { # bug 10725
2023         test_mkdir $DIR/$tdir
2024         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2025         local stripe_count=0
2026         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2027         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2028                 error "stripe width >= 2^32 succeeded" || true
2029
2030 }
2031 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2032
2033 test_27t() { # bug 10864
2034         WDIR=$(pwd)
2035         WLFS=$(which lfs)
2036         cd $DIR
2037         touch $tfile
2038         $WLFS getstripe $tfile
2039         cd $WDIR
2040 }
2041 run_test 27t "check that utils parse path correctly"
2042
2043 test_27u() { # bug 4900
2044         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2045         remote_mds_nodsh && skip "remote MDS with nodsh"
2046
2047         local index
2048         local list=$(comma_list $(mdts_nodes))
2049
2050 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2051         do_nodes $list $LCTL set_param fail_loc=0x139
2052         test_mkdir -p $DIR/$tdir
2053         stack_trap "simple_cleanup_common 1000"
2054         createmany -o $DIR/$tdir/$tfile 1000
2055         do_nodes $list $LCTL set_param fail_loc=0
2056
2057         TLOG=$TMP/$tfile.getstripe
2058         $LFS getstripe $DIR/$tdir > $TLOG
2059         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2060         [[ $OBJS -gt 0 ]] &&
2061                 error "$OBJS objects created on OST-0. See $TLOG" ||
2062                 rm -f $TLOG
2063 }
2064 run_test 27u "skip object creation on OSC w/o objects"
2065
2066 test_27v() { # bug 4900
2067         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2069         remote_mds_nodsh && skip "remote MDS with nodsh"
2070         remote_ost_nodsh && skip "remote OST with nodsh"
2071
2072         exhaust_all_precreations 0x215
2073         reset_enospc
2074
2075         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2076
2077         touch $DIR/$tdir/$tfile
2078         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2079         # all except ost1
2080         for (( i=1; i < OSTCOUNT; i++ )); do
2081                 do_facet ost$i lctl set_param fail_loc=0x705
2082         done
2083         local START=`date +%s`
2084         createmany -o $DIR/$tdir/$tfile 32
2085
2086         local FINISH=`date +%s`
2087         local TIMEOUT=`lctl get_param -n timeout`
2088         local PROCESS=$((FINISH - START))
2089         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2090                error "$FINISH - $START >= $TIMEOUT / 2"
2091         sleep $((TIMEOUT / 2 - PROCESS))
2092         reset_enospc
2093 }
2094 run_test 27v "skip object creation on slow OST"
2095
2096 test_27w() { # bug 10997
2097         test_mkdir $DIR/$tdir
2098         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2099         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2100                 error "stripe size $size != 65536" || true
2101         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2102                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2103 }
2104 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2105
2106 test_27wa() {
2107         [[ $OSTCOUNT -lt 2 ]] &&
2108                 skip_env "skipping multiple stripe count/offset test"
2109
2110         test_mkdir $DIR/$tdir
2111         for i in $(seq 1 $OSTCOUNT); do
2112                 offset=$((i - 1))
2113                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2114                         error "setstripe -c $i -i $offset failed"
2115                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2116                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2117                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2118                 [ $index -ne $offset ] &&
2119                         error "stripe offset $index != $offset" || true
2120         done
2121 }
2122 run_test 27wa "check $LFS setstripe -c -i options"
2123
2124 test_27x() {
2125         remote_ost_nodsh && skip "remote OST with nodsh"
2126         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2128
2129         OFFSET=$(($OSTCOUNT - 1))
2130         OSTIDX=0
2131         local OST=$(ostname_from_index $OSTIDX)
2132
2133         test_mkdir $DIR/$tdir
2134         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2135         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2136         sleep_maxage
2137         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2138         for i in $(seq 0 $OFFSET); do
2139                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2140                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2141                 error "OST0 was degraded but new created file still use it"
2142         done
2143         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2144 }
2145 run_test 27x "create files while OST0 is degraded"
2146
2147 test_27y() {
2148         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2149         remote_mds_nodsh && skip "remote MDS with nodsh"
2150         remote_ost_nodsh && skip "remote OST with nodsh"
2151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2152
2153         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2154         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2155                 osp.$mdtosc.prealloc_last_id)
2156         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2157                 osp.$mdtosc.prealloc_next_id)
2158         local fcount=$((last_id - next_id))
2159         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2160         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2161
2162         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2163                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2164         local OST_DEACTIVE_IDX=-1
2165         local OSC
2166         local OSTIDX
2167         local OST
2168
2169         for OSC in $MDS_OSCS; do
2170                 OST=$(osc_to_ost $OSC)
2171                 OSTIDX=$(index_from_ostuuid $OST)
2172                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2173                         OST_DEACTIVE_IDX=$OSTIDX
2174                 fi
2175                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2176                         echo $OSC "is Deactivated:"
2177                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2178                 fi
2179         done
2180
2181         OSTIDX=$(index_from_ostuuid $OST)
2182         test_mkdir $DIR/$tdir
2183         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2184
2185         for OSC in $MDS_OSCS; do
2186                 OST=$(osc_to_ost $OSC)
2187                 OSTIDX=$(index_from_ostuuid $OST)
2188                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2189                         echo $OST "is degraded:"
2190                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2191                                                 obdfilter.$OST.degraded=1
2192                 fi
2193         done
2194
2195         sleep_maxage
2196         createmany -o $DIR/$tdir/$tfile $fcount
2197
2198         for OSC in $MDS_OSCS; do
2199                 OST=$(osc_to_ost $OSC)
2200                 OSTIDX=$(index_from_ostuuid $OST)
2201                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2202                         echo $OST "is recovered from degraded:"
2203                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2204                                                 obdfilter.$OST.degraded=0
2205                 else
2206                         do_facet $SINGLEMDS lctl --device %$OSC activate
2207                 fi
2208         done
2209
2210         # all osp devices get activated, hence -1 stripe count restored
2211         local stripe_count=0
2212
2213         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2214         # devices get activated.
2215         sleep_maxage
2216         $LFS setstripe -c -1 $DIR/$tfile
2217         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2218         rm -f $DIR/$tfile
2219         [ $stripe_count -ne $OSTCOUNT ] &&
2220                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2221         return 0
2222 }
2223 run_test 27y "create files while OST0 is degraded and the rest inactive"
2224
2225 check_seq_oid()
2226 {
2227         log "check file $1"
2228
2229         lmm_count=$($LFS getstripe -c $1)
2230         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2231         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2232
2233         local old_ifs="$IFS"
2234         IFS=$'[:]'
2235         fid=($($LFS path2fid $1))
2236         IFS="$old_ifs"
2237
2238         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2239         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2240
2241         # compare lmm_seq and lu_fid->f_seq
2242         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2243         # compare lmm_object_id and lu_fid->oid
2244         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2245
2246         # check the trusted.fid attribute of the OST objects of the file
2247         local have_obdidx=false
2248         local stripe_nr=0
2249         $LFS getstripe $1 | while read obdidx oid hex seq; do
2250                 # skip lines up to and including "obdidx"
2251                 [ -z "$obdidx" ] && break
2252                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2253                 $have_obdidx || continue
2254
2255                 local ost=$((obdidx + 1))
2256                 local dev=$(ostdevname $ost)
2257                 local oid_hex
2258
2259                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2260
2261                 seq=$(echo $seq | sed -e "s/^0x//g")
2262                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2263                         oid_hex=$(echo $oid)
2264                 else
2265                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2266                 fi
2267                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2268
2269                 local ff=""
2270                 #
2271                 # Don't unmount/remount the OSTs if we don't need to do that.
2272                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2273                 # update too, until that use mount/ll_decode_filter_fid/mount.
2274                 # Re-enable when debugfs will understand new filter_fid.
2275                 #
2276                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2277                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2278                                 $dev 2>/dev/null" | grep "parent=")
2279                 fi
2280                 if [ -z "$ff" ]; then
2281                         stop ost$ost
2282                         mount_fstype ost$ost
2283                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2284                                 $(facet_mntpt ost$ost)/$obj_file)
2285                         unmount_fstype ost$ost
2286                         start ost$ost $dev $OST_MOUNT_OPTS
2287                         clients_up
2288                 fi
2289
2290                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2291
2292                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2293
2294                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2295                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2296                 #
2297                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2298                 #       stripe_size=1048576 component_id=1 component_start=0 \
2299                 #       component_end=33554432
2300                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2301                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2302                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2303                 local ff_pstripe
2304                 if grep -q 'stripe=' <<<$ff; then
2305                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2306                 else
2307                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2308                         # into f_ver in this case.  See comment on ff_parent.
2309                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2310                 fi
2311
2312                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2313                 [ $ff_pseq = $lmm_seq ] ||
2314                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2315                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2316                 [ $ff_poid = $lmm_oid ] ||
2317                         error "FF parent OID $ff_poid != $lmm_oid"
2318                 (($ff_pstripe == $stripe_nr)) ||
2319                         error "FF stripe $ff_pstripe != $stripe_nr"
2320
2321                 stripe_nr=$((stripe_nr + 1))
2322                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2323                         continue
2324                 if grep -q 'stripe_count=' <<<$ff; then
2325                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2326                                             -e 's/ .*//' <<<$ff)
2327                         [ $lmm_count = $ff_scnt ] ||
2328                                 error "FF stripe count $lmm_count != $ff_scnt"
2329                 fi
2330         done
2331 }
2332
2333 test_27z() {
2334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2335         remote_ost_nodsh && skip "remote OST with nodsh"
2336
2337         test_mkdir $DIR/$tdir
2338         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2339                 { error "setstripe -c -1 failed"; return 1; }
2340         # We need to send a write to every object to get parent FID info set.
2341         # This _should_ also work for setattr, but does not currently.
2342         # touch $DIR/$tdir/$tfile-1 ||
2343         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2344                 { error "dd $tfile-1 failed"; return 2; }
2345         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2346                 { error "setstripe -c -1 failed"; return 3; }
2347         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2348                 { error "dd $tfile-2 failed"; return 4; }
2349
2350         # make sure write RPCs have been sent to OSTs
2351         sync; sleep 5; sync
2352
2353         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2354         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2355 }
2356 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2357
2358 test_27A() { # b=19102
2359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2360
2361         save_layout_restore_at_exit $MOUNT
2362         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2363         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2364                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2365         local default_size=$($LFS getstripe -S $MOUNT)
2366         local default_offset=$($LFS getstripe -i $MOUNT)
2367         local dsize=$(do_facet $SINGLEMDS \
2368                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2369         [ $default_size -eq $dsize ] ||
2370                 error "stripe size $default_size != $dsize"
2371         [ $default_offset -eq -1 ] ||
2372                 error "stripe offset $default_offset != -1"
2373 }
2374 run_test 27A "check filesystem-wide default LOV EA values"
2375
2376 test_27B() { # LU-2523
2377         test_mkdir $DIR/$tdir
2378         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2379         touch $DIR/$tdir/f0
2380         # open f1 with O_LOV_DELAY_CREATE
2381         # rename f0 onto f1
2382         # call setstripe ioctl on open file descriptor for f1
2383         # close
2384         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2385                 $DIR/$tdir/f0
2386
2387         rm -f $DIR/$tdir/f1
2388         # open f1 with O_LOV_DELAY_CREATE
2389         # unlink f1
2390         # call setstripe ioctl on open file descriptor for f1
2391         # close
2392         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2393
2394         # Allow multiop to fail in imitation of NFS's busted semantics.
2395         true
2396 }
2397 run_test 27B "call setstripe on open unlinked file/rename victim"
2398
2399 # 27C family tests full striping and overstriping
2400 test_27Ca() { #LU-2871
2401         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2402
2403         declare -a ost_idx
2404         local index
2405         local found
2406         local i
2407         local j
2408
2409         test_mkdir $DIR/$tdir
2410         cd $DIR/$tdir
2411         for i in $(seq 0 $((OSTCOUNT - 1))); do
2412                 # set stripe across all OSTs starting from OST$i
2413                 $LFS setstripe -i $i -c -1 $tfile$i
2414                 # get striping information
2415                 ost_idx=($($LFS getstripe $tfile$i |
2416                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2417                 echo ${ost_idx[@]}
2418
2419                 # check the layout
2420                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2421                         error "${#ost_idx[@]} != $OSTCOUNT"
2422
2423                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2424                         found=0
2425                         for j in $(echo ${ost_idx[@]}); do
2426                                 if [ $index -eq $j ]; then
2427                                         found=1
2428                                         break
2429                                 fi
2430                         done
2431                         [ $found = 1 ] ||
2432                                 error "Can not find $index in ${ost_idx[@]}"
2433                 done
2434         done
2435 }
2436 run_test 27Ca "check full striping across all OSTs"
2437
2438 test_27Cb() {
2439         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2440                 skip "server does not support overstriping"
2441         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2442                 skip_env "too many osts, skipping"
2443
2444         test_mkdir -p $DIR/$tdir
2445         local setcount=$(($OSTCOUNT * 2))
2446         [ $setcount -lt 160 ] || large_xattr_enabled ||
2447                 skip_env "ea_inode feature disabled"
2448
2449         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2450                 error "setstripe failed"
2451
2452         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2453         [ $count -eq $setcount ] ||
2454                 error "stripe count $count, should be $setcount"
2455
2456         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2457                 error "overstriped should be set in pattern"
2458
2459         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2460                 error "dd failed"
2461 }
2462 run_test 27Cb "more stripes than OSTs with -C"
2463
2464 test_27Cc() {
2465         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2466                 skip "server does not support overstriping"
2467         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2468
2469         test_mkdir -p $DIR/$tdir
2470         local setcount=$(($OSTCOUNT - 1))
2471
2472         [ $setcount -lt 160 ] || large_xattr_enabled ||
2473                 skip_env "ea_inode feature disabled"
2474
2475         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2476                 error "setstripe failed"
2477
2478         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2479         [ $count -eq $setcount ] ||
2480                 error "stripe count $count, should be $setcount"
2481
2482         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2483                 error "overstriped should not be set in pattern"
2484
2485         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2486                 error "dd failed"
2487 }
2488 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2489
2490 test_27Cd() {
2491         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2492                 skip "server does not support overstriping"
2493         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2494         large_xattr_enabled || skip_env "ea_inode feature disabled"
2495
2496         test_mkdir -p $DIR/$tdir
2497         local setcount=$LOV_MAX_STRIPE_COUNT
2498
2499         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2500                 error "setstripe failed"
2501
2502         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2503         [ $count -eq $setcount ] ||
2504                 error "stripe count $count, should be $setcount"
2505
2506         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2507                 error "overstriped should be set in pattern"
2508
2509         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2510                 error "dd failed"
2511
2512         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2513 }
2514 run_test 27Cd "test maximum stripe count"
2515
2516 test_27Ce() {
2517         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2518                 skip "server does not support overstriping"
2519         test_mkdir -p $DIR/$tdir
2520
2521         pool_add $TESTNAME || error "Pool creation failed"
2522         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2523
2524         local setcount=8
2525
2526         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2527                 error "setstripe failed"
2528
2529         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2530         [ $count -eq $setcount ] ||
2531                 error "stripe count $count, should be $setcount"
2532
2533         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2534                 error "overstriped should be set in pattern"
2535
2536         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2537                 error "dd failed"
2538
2539         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2540 }
2541 run_test 27Ce "test pool with overstriping"
2542
2543 test_27Cf() {
2544         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2545                 skip "server does not support overstriping"
2546         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2547                 skip_env "too many osts, skipping"
2548
2549         test_mkdir -p $DIR/$tdir
2550
2551         local setcount=$(($OSTCOUNT * 2))
2552         [ $setcount -lt 160 ] || large_xattr_enabled ||
2553                 skip_env "ea_inode feature disabled"
2554
2555         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2556                 error "setstripe failed"
2557
2558         echo 1 > $DIR/$tdir/$tfile
2559
2560         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2561         [ $count -eq $setcount ] ||
2562                 error "stripe count $count, should be $setcount"
2563
2564         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2565                 error "overstriped should be set in pattern"
2566
2567         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2568                 error "dd failed"
2569
2570         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2571 }
2572 run_test 27Cf "test default inheritance with overstriping"
2573
2574 test_27D() {
2575         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2576         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2577         remote_mds_nodsh && skip "remote MDS with nodsh"
2578
2579         local POOL=${POOL:-testpool}
2580         local first_ost=0
2581         local last_ost=$(($OSTCOUNT - 1))
2582         local ost_step=1
2583         local ost_list=$(seq $first_ost $ost_step $last_ost)
2584         local ost_range="$first_ost $last_ost $ost_step"
2585
2586         test_mkdir $DIR/$tdir
2587         pool_add $POOL || error "pool_add failed"
2588         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2589
2590         local skip27D
2591         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2592                 skip27D+="-s 29"
2593         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2594                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2595                         skip27D+=" -s 30,31"
2596         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2597           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2598                 skip27D+=" -s 32,33"
2599         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2600                 skip27D+=" -s 34"
2601         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2602                 error "llapi_layout_test failed"
2603
2604         destroy_test_pools || error "destroy test pools failed"
2605 }
2606 run_test 27D "validate llapi_layout API"
2607
2608 # Verify that default_easize is increased from its initial value after
2609 # accessing a widely striped file.
2610 test_27E() {
2611         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2612         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2613                 skip "client does not have LU-3338 fix"
2614
2615         # 72 bytes is the minimum space required to store striping
2616         # information for a file striped across one OST:
2617         # (sizeof(struct lov_user_md_v3) +
2618         #  sizeof(struct lov_user_ost_data_v1))
2619         local min_easize=72
2620         $LCTL set_param -n llite.*.default_easize $min_easize ||
2621                 error "lctl set_param failed"
2622         local easize=$($LCTL get_param -n llite.*.default_easize)
2623
2624         [ $easize -eq $min_easize ] ||
2625                 error "failed to set default_easize"
2626
2627         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2628                 error "setstripe failed"
2629         # In order to ensure stat() call actually talks to MDS we need to
2630         # do something drastic to this file to shake off all lock, e.g.
2631         # rename it (kills lookup lock forcing cache cleaning)
2632         mv $DIR/$tfile $DIR/${tfile}-1
2633         ls -l $DIR/${tfile}-1
2634         rm $DIR/${tfile}-1
2635
2636         easize=$($LCTL get_param -n llite.*.default_easize)
2637
2638         [ $easize -gt $min_easize ] ||
2639                 error "default_easize not updated"
2640 }
2641 run_test 27E "check that default extended attribute size properly increases"
2642
2643 test_27F() { # LU-5346/LU-7975
2644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2645         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2646         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2647                 skip "Need MDS version at least 2.8.51"
2648         remote_ost_nodsh && skip "remote OST with nodsh"
2649
2650         test_mkdir $DIR/$tdir
2651         rm -f $DIR/$tdir/f0
2652         $LFS setstripe -c 2 $DIR/$tdir
2653
2654         # stop all OSTs to reproduce situation for LU-7975 ticket
2655         for num in $(seq $OSTCOUNT); do
2656                 stop ost$num
2657         done
2658
2659         # open/create f0 with O_LOV_DELAY_CREATE
2660         # truncate f0 to a non-0 size
2661         # close
2662         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2663
2664         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2665         # open/write it again to force delayed layout creation
2666         cat /etc/hosts > $DIR/$tdir/f0 &
2667         catpid=$!
2668
2669         # restart OSTs
2670         for num in $(seq $OSTCOUNT); do
2671                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2672                         error "ost$num failed to start"
2673         done
2674
2675         wait $catpid || error "cat failed"
2676
2677         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2678         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2679                 error "wrong stripecount"
2680
2681 }
2682 run_test 27F "Client resend delayed layout creation with non-zero size"
2683
2684 test_27G() { #LU-10629
2685         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2686                 skip "Need MDS version at least 2.11.51"
2687         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2688         remote_mds_nodsh && skip "remote MDS with nodsh"
2689         local POOL=${POOL:-testpool}
2690         local ostrange="0 0 1"
2691
2692         test_mkdir $DIR/$tdir
2693         touch $DIR/$tdir/$tfile.nopool
2694         pool_add $POOL || error "pool_add failed"
2695         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2696         $LFS setstripe -p $POOL $DIR/$tdir
2697
2698         local pool=$($LFS getstripe -p $DIR/$tdir)
2699
2700         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2701         touch $DIR/$tdir/$tfile.default
2702         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2703         $LFS find $DIR/$tdir -type f --pool $POOL
2704         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2705         [[ "$found" == "2" ]] ||
2706                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2707
2708         $LFS setstripe -d $DIR/$tdir
2709
2710         pool=$($LFS getstripe -p -d $DIR/$tdir)
2711
2712         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2713 }
2714 run_test 27G "Clear OST pool from stripe"
2715
2716 test_27H() {
2717         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2718                 skip "Need MDS version newer than 2.11.54"
2719         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2720         test_mkdir $DIR/$tdir
2721         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2722         touch $DIR/$tdir/$tfile
2723         $LFS getstripe -c $DIR/$tdir/$tfile
2724         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2725                 error "two-stripe file doesn't have two stripes"
2726
2727         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2728         $LFS getstripe -y $DIR/$tdir/$tfile
2729         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2730              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2731                 error "expected l_ost_idx: [02]$ not matched"
2732
2733         # make sure ost list has been cleared
2734         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2735         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2736                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2737         touch $DIR/$tdir/f3
2738         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2739 }
2740 run_test 27H "Set specific OSTs stripe"
2741
2742 test_27I() {
2743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2744         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2745         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2746                 skip "Need MDS version newer than 2.12.52"
2747         local pool=$TESTNAME
2748         local ostrange="1 1 1"
2749
2750         save_layout_restore_at_exit $MOUNT
2751         $LFS setstripe -c 2 -i 0 $MOUNT
2752         pool_add $pool || error "pool_add failed"
2753         pool_add_targets $pool $ostrange ||
2754                 error "pool_add_targets failed"
2755         test_mkdir $DIR/$tdir
2756         $LFS setstripe -p $pool $DIR/$tdir
2757         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2758         $LFS getstripe $DIR/$tdir/$tfile
2759 }
2760 run_test 27I "check that root dir striping does not break parent dir one"
2761
2762 test_27J() {
2763         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2764                 skip "Need MDS version newer than 2.12.51"
2765
2766         test_mkdir $DIR/$tdir
2767         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2768         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2769
2770         # create foreign file (raw way)
2771         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2772                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2773
2774         ! $LFS setstripe --foreign --flags foo \
2775                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2776                         error "creating $tfile with '--flags foo' should fail"
2777
2778         ! $LFS setstripe --foreign --flags 0xffffffff \
2779                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2780                         error "creating $tfile w/ 0xffffffff flags should fail"
2781
2782         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2783                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2784
2785         # verify foreign file (raw way)
2786         parse_foreign_file -f $DIR/$tdir/$tfile |
2787                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2788                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2789         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2790                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2791         parse_foreign_file -f $DIR/$tdir/$tfile |
2792                 grep "lov_foreign_size: 73" ||
2793                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2794         parse_foreign_file -f $DIR/$tdir/$tfile |
2795                 grep "lov_foreign_type: 1" ||
2796                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2797         parse_foreign_file -f $DIR/$tdir/$tfile |
2798                 grep "lov_foreign_flags: 0x0000DA08" ||
2799                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2800         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2801                 grep "lov_foreign_value: 0x" |
2802                 sed -e 's/lov_foreign_value: 0x//')
2803         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2804         [[ $lov = ${lov2// /} ]] ||
2805                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2806
2807         # create foreign file (lfs + API)
2808         $LFS setstripe --foreign=none --flags 0xda08 \
2809                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2810                 error "$DIR/$tdir/${tfile}2: create failed"
2811
2812         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2813                 grep "lfm_magic:.*0x0BD70BD0" ||
2814                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2815         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2816         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2817                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2818         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2819                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2820         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2821                 grep "lfm_flags:.*0x0000DA08" ||
2822                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2823         $LFS getstripe $DIR/$tdir/${tfile}2 |
2824                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2825                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2826
2827         # modify striping should fail
2828         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2829                 error "$DIR/$tdir/$tfile: setstripe should fail"
2830         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2831                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2832
2833         # R/W should fail
2834         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2835         cat $DIR/$tdir/${tfile}2 &&
2836                 error "$DIR/$tdir/${tfile}2: read should fail"
2837         cat /etc/passwd > $DIR/$tdir/$tfile &&
2838                 error "$DIR/$tdir/$tfile: write should fail"
2839         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2840                 error "$DIR/$tdir/${tfile}2: write should fail"
2841
2842         # chmod should work
2843         chmod 222 $DIR/$tdir/$tfile ||
2844                 error "$DIR/$tdir/$tfile: chmod failed"
2845         chmod 222 $DIR/$tdir/${tfile}2 ||
2846                 error "$DIR/$tdir/${tfile}2: chmod failed"
2847
2848         # chown should work
2849         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2850                 error "$DIR/$tdir/$tfile: chown failed"
2851         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2852                 error "$DIR/$tdir/${tfile}2: chown failed"
2853
2854         # rename should work
2855         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2856                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2857         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2858                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2859
2860         #remove foreign file
2861         rm $DIR/$tdir/${tfile}.new ||
2862                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2863         rm $DIR/$tdir/${tfile}2.new ||
2864                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2865 }
2866 run_test 27J "basic ops on file with foreign LOV"
2867
2868 test_27K() {
2869         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2870                 skip "Need MDS version newer than 2.12.49"
2871
2872         test_mkdir $DIR/$tdir
2873         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2874         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2875
2876         # create foreign dir (raw way)
2877         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2878                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2879
2880         ! $LFS setdirstripe --foreign --flags foo \
2881                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2882                         error "creating $tdir with '--flags foo' should fail"
2883
2884         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2885                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2886                         error "creating $tdir w/ 0xffffffff flags should fail"
2887
2888         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2889                 error "create_foreign_dir FAILED"
2890
2891         # verify foreign dir (raw way)
2892         parse_foreign_dir -d $DIR/$tdir/$tdir |
2893                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2894                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2895         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2896                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2897         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2898                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2899         parse_foreign_dir -d $DIR/$tdir/$tdir |
2900                 grep "lmv_foreign_flags: 55813$" ||
2901                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2902         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2903                 grep "lmv_foreign_value: 0x" |
2904                 sed 's/lmv_foreign_value: 0x//')
2905         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2906                 sed 's/ //g')
2907         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2908
2909         # create foreign dir (lfs + API)
2910         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2911                 $DIR/$tdir/${tdir}2 ||
2912                 error "$DIR/$tdir/${tdir}2: create failed"
2913
2914         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2915                 grep "lfm_magic:.*0x0CD50CD0" ||
2916                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2917         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2918         # - sizeof(lfm_type) - sizeof(lfm_flags)
2919         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2920                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2921         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2922                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2923         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2924                 grep "lfm_flags:.*0x0000DA05" ||
2925                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2926         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2927                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2928                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2929
2930         # file create in dir should fail
2931         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2932         touch $DIR/$tdir/${tdir}2/$tfile &&
2933                 error "$DIR/${tdir}2: file create should fail"
2934
2935         # chmod should work
2936         chmod 777 $DIR/$tdir/$tdir ||
2937                 error "$DIR/$tdir: chmod failed"
2938         chmod 777 $DIR/$tdir/${tdir}2 ||
2939                 error "$DIR/${tdir}2: chmod failed"
2940
2941         # chown should work
2942         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2943                 error "$DIR/$tdir: chown failed"
2944         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2945                 error "$DIR/${tdir}2: chown failed"
2946
2947         # rename should work
2948         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2949                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2950         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2951                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2952
2953         #remove foreign dir
2954         rmdir $DIR/$tdir/${tdir}.new ||
2955                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2956         rmdir $DIR/$tdir/${tdir}2.new ||
2957                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2958 }
2959 run_test 27K "basic ops on dir with foreign LMV"
2960
2961 test_27L() {
2962         remote_mds_nodsh && skip "remote MDS with nodsh"
2963
2964         local POOL=${POOL:-$TESTNAME}
2965
2966         pool_add $POOL || error "pool_add failed"
2967
2968         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2969                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2970                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2971 }
2972 run_test 27L "lfs pool_list gives correct pool name"
2973
2974 test_27M() {
2975         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2976                 skip "Need MDS version >= than 2.12.57"
2977         remote_mds_nodsh && skip "remote MDS with nodsh"
2978         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2979
2980         test_mkdir $DIR/$tdir
2981
2982         # Set default striping on directory
2983         local setcount=4
2984         local stripe_opt
2985
2986         # if we run against a 2.12 server which lacks overstring support
2987         # then the connect_flag will not report overstriping, even if client
2988         # is 2.14+
2989         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2990                 stripe_opt="-C $setcount"
2991         elif (( $OSTCOUNT >= $setcount )); then
2992                 stripe_opt="-c $setcount"
2993         else
2994                 skip "server does not support overstriping"
2995         fi
2996         $LFS setstripe $stripe_opt $DIR/$tdir
2997
2998         echo 1 > $DIR/$tdir/${tfile}.1
2999         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3000         [ $count -eq $setcount ] ||
3001                 error "(1) stripe count $count, should be $setcount"
3002
3003         # Capture existing append_stripe_count setting for restore
3004         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3005         local mdts=$(comma_list $(mdts_nodes))
3006         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
3007
3008         local appendcount=$orig_count
3009         echo 1 >> $DIR/$tdir/${tfile}.2_append
3010         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3011         [ $count -eq $appendcount ] ||
3012                 error "(2)stripe count $count, should be $appendcount for append"
3013
3014         # Disable O_APPEND striping, verify it works
3015         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3016
3017         # Should now get the default striping, which is 4
3018         setcount=4
3019         echo 1 >> $DIR/$tdir/${tfile}.3_append
3020         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3021         [ $count -eq $setcount ] ||
3022                 error "(3) stripe count $count, should be $setcount"
3023
3024         # Try changing the stripe count for append files
3025         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3026
3027         # Append striping is now 2 (directory default is still 4)
3028         appendcount=2
3029         echo 1 >> $DIR/$tdir/${tfile}.4_append
3030         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3031         [ $count -eq $appendcount ] ||
3032                 error "(4) stripe count $count, should be $appendcount for append"
3033
3034         # Test append stripe count of -1
3035         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3036         appendcount=$OSTCOUNT
3037         echo 1 >> $DIR/$tdir/${tfile}.5
3038         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3039         [ $count -eq $appendcount ] ||
3040                 error "(5) stripe count $count, should be $appendcount for append"
3041
3042         # Set append striping back to default of 1
3043         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3044
3045         # Try a new default striping, PFL + DOM
3046         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3047
3048         # Create normal DOM file, DOM returns stripe count == 0
3049         setcount=0
3050         touch $DIR/$tdir/${tfile}.6
3051         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3052         [ $count -eq $setcount ] ||
3053                 error "(6) stripe count $count, should be $setcount"
3054
3055         # Show
3056         appendcount=1
3057         echo 1 >> $DIR/$tdir/${tfile}.7_append
3058         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3059         [ $count -eq $appendcount ] ||
3060                 error "(7) stripe count $count, should be $appendcount for append"
3061
3062         # Clean up DOM layout
3063         $LFS setstripe -d $DIR/$tdir
3064
3065         save_layout_restore_at_exit $MOUNT
3066         # Now test that append striping works when layout is from root
3067         $LFS setstripe -c 2 $MOUNT
3068         # Make a special directory for this
3069         mkdir $DIR/${tdir}/${tdir}.2
3070
3071         # Verify for normal file
3072         setcount=2
3073         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3074         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3075         [ $count -eq $setcount ] ||
3076                 error "(8) stripe count $count, should be $setcount"
3077
3078         appendcount=1
3079         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3080         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3081         [ $count -eq $appendcount ] ||
3082                 error "(9) stripe count $count, should be $appendcount for append"
3083
3084         # Now test O_APPEND striping with pools
3085         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3086         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3087
3088         # Create the pool
3089         pool_add $TESTNAME || error "pool creation failed"
3090         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3091
3092         echo 1 >> $DIR/$tdir/${tfile}.10_append
3093
3094         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3095         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3096
3097         # Check that count is still correct
3098         appendcount=1
3099         echo 1 >> $DIR/$tdir/${tfile}.11_append
3100         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3101         [ $count -eq $appendcount ] ||
3102                 error "(11) stripe count $count, should be $appendcount for append"
3103
3104         # Disable O_APPEND stripe count, verify pool works separately
3105         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3106
3107         echo 1 >> $DIR/$tdir/${tfile}.12_append
3108
3109         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3110         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3111
3112         # Remove pool setting, verify it's not applied
3113         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3114
3115         echo 1 >> $DIR/$tdir/${tfile}.13_append
3116
3117         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3118         [ "$pool" = "" ] || error "(13) pool found: $pool"
3119 }
3120 run_test 27M "test O_APPEND striping"
3121
3122 test_27N() {
3123         combined_mgs_mds && skip "needs separate MGS/MDT"
3124
3125         pool_add $TESTNAME || error "pool_add failed"
3126         do_facet mgs "$LCTL pool_list $FSNAME" |
3127                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3128                 error "lctl pool_list on MGS failed"
3129 }
3130 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3131
3132 clean_foreign_symlink() {
3133         trap 0
3134         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3135         for i in $DIR/$tdir/* ; do
3136                 $LFS unlink_foreign $i || true
3137         done
3138 }
3139
3140 test_27O() {
3141         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3142                 skip "Need MDS version newer than 2.12.51"
3143
3144         test_mkdir $DIR/$tdir
3145         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3146         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3147
3148         trap clean_foreign_symlink EXIT
3149
3150         # enable foreign_symlink behaviour
3151         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3152
3153         # foreign symlink LOV format is a partial path by default
3154
3155         # create foreign file (lfs + API)
3156         $LFS setstripe --foreign=symlink --flags 0xda05 \
3157                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3158                 error "$DIR/$tdir/${tfile}: create failed"
3159
3160         $LFS getstripe -v $DIR/$tdir/${tfile} |
3161                 grep "lfm_magic:.*0x0BD70BD0" ||
3162                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3163         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3164                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3165         $LFS getstripe -v $DIR/$tdir/${tfile} |
3166                 grep "lfm_flags:.*0x0000DA05" ||
3167                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3168         $LFS getstripe $DIR/$tdir/${tfile} |
3169                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3170                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3171
3172         # modify striping should fail
3173         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3174                 error "$DIR/$tdir/$tfile: setstripe should fail"
3175
3176         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3177         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3178         cat /etc/passwd > $DIR/$tdir/$tfile &&
3179                 error "$DIR/$tdir/$tfile: write should fail"
3180
3181         # rename should succeed
3182         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3183                 error "$DIR/$tdir/$tfile: rename has failed"
3184
3185         #remove foreign_symlink file should fail
3186         rm $DIR/$tdir/${tfile}.new &&
3187                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3188
3189         #test fake symlink
3190         mkdir /tmp/${uuid1} ||
3191                 error "/tmp/${uuid1}: mkdir has failed"
3192         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3193                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3194         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3195         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3197         #read should succeed now
3198         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3199                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3200         #write should succeed now
3201         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3202                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3203         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3204                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3205         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3206                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3207
3208         #check that getstripe still works
3209         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3210                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3211
3212         # chmod should still succeed
3213         chmod 644 $DIR/$tdir/${tfile}.new ||
3214                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3215
3216         # chown should still succeed
3217         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3218                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3219
3220         # rename should still succeed
3221         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3222                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3223
3224         #remove foreign_symlink file should still fail
3225         rm $DIR/$tdir/${tfile} &&
3226                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3227
3228         #use special ioctl() to unlink foreign_symlink file
3229         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3230                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3231
3232 }
3233 run_test 27O "basic ops on foreign file of symlink type"
3234
3235 test_27P() {
3236         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3237                 skip "Need MDS version newer than 2.12.49"
3238
3239         test_mkdir $DIR/$tdir
3240         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3241         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3242
3243         trap clean_foreign_symlink EXIT
3244
3245         # enable foreign_symlink behaviour
3246         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3247
3248         # foreign symlink LMV format is a partial path by default
3249
3250         # create foreign dir (lfs + API)
3251         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3252                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3253                 error "$DIR/$tdir/${tdir}: create failed"
3254
3255         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3256                 grep "lfm_magic:.*0x0CD50CD0" ||
3257                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3258         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3259                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3260         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3261                 grep "lfm_flags:.*0x0000DA05" ||
3262                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3263         $LFS getdirstripe $DIR/$tdir/${tdir} |
3264                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3265                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3266
3267         # file create in dir should fail
3268         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3269         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3270
3271         # rename should succeed
3272         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3273                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3274
3275         #remove foreign_symlink dir should fail
3276         rmdir $DIR/$tdir/${tdir}.new &&
3277                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3278
3279         #test fake symlink
3280         mkdir -p /tmp/${uuid1}/${uuid2} ||
3281                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3282         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3283                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3284         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3285         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3286                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3287         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3288                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3289
3290         #check that getstripe fails now that foreign_symlink enabled
3291         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3292                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3293
3294         # file create in dir should work now
3295         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3296                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3297         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3298                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3299         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3300                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3301
3302         # chmod should still succeed
3303         chmod 755 $DIR/$tdir/${tdir}.new ||
3304                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3305
3306         # chown should still succeed
3307         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3308                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3309
3310         # rename should still succeed
3311         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3312                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3313
3314         #remove foreign_symlink dir should still fail
3315         rmdir $DIR/$tdir/${tdir} &&
3316                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3317
3318         #use special ioctl() to unlink foreign_symlink file
3319         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3320                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3321
3322         #created file should still exist
3323         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3324                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3325         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3326                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3327 }
3328 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3329
3330 test_27Q() {
3331         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3332         stack_trap "rm -f $TMP/$tfile*"
3333
3334         test_mkdir $DIR/$tdir-1
3335         test_mkdir $DIR/$tdir-2
3336
3337         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3338         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3339
3340         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3341         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3342
3343         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3344         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3345
3346         # Create some bad symlinks and ensure that we don't loop
3347         # forever or something. These should return ELOOP (40) and
3348         # ENOENT (2) but I don't want to test for that because there's
3349         # always some weirdo architecture that needs to ruin
3350         # everything by defining these error numbers differently.
3351
3352         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3353         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3354
3355         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3356         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3357
3358         return 0
3359 }
3360 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3361
3362 test_27R() {
3363         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3364                 skip "need MDS 2.14.55 or later"
3365         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3366
3367         local testdir="$DIR/$tdir"
3368         test_mkdir -p $testdir
3369         stack_trap "rm -rf $testdir"
3370         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3371
3372         local f1="$testdir/f1"
3373         touch $f1 || error "failed to touch $f1"
3374         local count=$($LFS getstripe -c $f1)
3375         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3376
3377         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3378         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3379
3380         local maxcount=$(($OSTCOUNT - 1))
3381         local mdts=$(comma_list $(mdts_nodes))
3382         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3383         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3384
3385         local f2="$testdir/f2"
3386         touch $f2 || error "failed to touch $f2"
3387         local count=$($LFS getstripe -c $f2)
3388         (( $count == $maxcount )) || error "wrong stripe count"
3389 }
3390 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3391
3392 test_27S() {
3393         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
3394                 skip "Need MDS version at least 2.14.54"
3395         [[ "$(facet_host mds1)" != "$(facet_host ost1)" ]] ||
3396                 skip "needs different host for mdt1 ost1"
3397
3398         local count=$(precreated_ost_obj_count 0 0)
3399
3400         echo "precreate count $count"
3401         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
3402         $LFS setstripe -i 0 -c 1 $DIR/$tdir || error "setstripe $tdir failed"
3403         #define OBD_FAIL_OSP_GET_LAST_FID       0x2109
3404         do_facet mds1 $LCTL set_param fail_loc=0x2109
3405         #define OBD_FAIL_OST_GET_LAST_FID       0x252
3406         do_facet ost1 $LCTL set_param fail_loc=0x252
3407         createmany -o $DIR/$tdir/f $count &
3408         pid=$!
3409         echo "precreate count $(precreated_ost_obj_count 0 0)"
3410         do_facet mds1 $LCTL set_param fail_loc=0
3411         do_facet ost1 $LCTL set_param fail_loc=0
3412         wait $pid || error "createmany failed"
3413         echo "precreate count $(precreated_ost_obj_count 0 0)"
3414 }
3415 run_test 27S "don't deactivate OSP on network issue"
3416
3417 # createtest also checks that device nodes are created and
3418 # then visible correctly (#2091)
3419 test_28() { # bug 2091
3420         test_mkdir $DIR/d28
3421         $CREATETEST $DIR/d28/ct || error "createtest failed"
3422 }
3423 run_test 28 "create/mknod/mkdir with bad file types ============"
3424
3425 test_29() {
3426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3427
3428         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3429                 disable_opencache
3430                 stack_trap "restore_opencache"
3431         }
3432
3433         sync; sleep 1; sync # flush out any dirty pages from previous tests
3434         cancel_lru_locks
3435         test_mkdir $DIR/d29
3436         touch $DIR/d29/foo
3437         log 'first d29'
3438         ls -l $DIR/d29
3439
3440         declare -i LOCKCOUNTORIG=0
3441         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3442                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3443         done
3444         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3445
3446         declare -i LOCKUNUSEDCOUNTORIG=0
3447         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3448                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3449         done
3450
3451         log 'second d29'
3452         ls -l $DIR/d29
3453         log 'done'
3454
3455         declare -i LOCKCOUNTCURRENT=0
3456         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3457                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3458         done
3459
3460         declare -i LOCKUNUSEDCOUNTCURRENT=0
3461         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3462                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3463         done
3464
3465         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3466                 $LCTL set_param -n ldlm.dump_namespaces ""
3467                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3468                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3469                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3470                 return 2
3471         fi
3472         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3473                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3474                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3475                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3476                 return 3
3477         fi
3478 }
3479 run_test 29 "IT_GETATTR regression  ============================"
3480
3481 test_30a() { # was test_30
3482         cp $(which ls) $DIR || cp /bin/ls $DIR
3483         $DIR/ls / || error "Can't execute binary from lustre"
3484         rm $DIR/ls
3485 }
3486 run_test 30a "execute binary from Lustre (execve) =============="
3487
3488 test_30b() {
3489         cp `which ls` $DIR || cp /bin/ls $DIR
3490         chmod go+rx $DIR/ls
3491         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3492         rm $DIR/ls
3493 }
3494 run_test 30b "execute binary from Lustre as non-root ==========="
3495
3496 test_30c() { # b=22376
3497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3498
3499         cp $(which ls) $DIR || cp /bin/ls $DIR
3500         chmod a-rw $DIR/ls
3501         cancel_lru_locks mdc
3502         cancel_lru_locks osc
3503         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3504         rm -f $DIR/ls
3505 }
3506 run_test 30c "execute binary from Lustre without read perms ===="
3507
3508 test_30d() {
3509         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3510
3511         for i in {1..10}; do
3512                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3513                 local PID=$!
3514                 sleep 1
3515                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3516                 wait $PID || error "executing dd from Lustre failed"
3517                 rm -f $DIR/$tfile
3518         done
3519
3520         rm -f $DIR/dd
3521 }
3522 run_test 30d "execute binary from Lustre while clear locks"
3523
3524 test_31a() {
3525         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3526         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3527 }
3528 run_test 31a "open-unlink file =================================="
3529
3530 test_31b() {
3531         touch $DIR/f31 || error "touch $DIR/f31 failed"
3532         ln $DIR/f31 $DIR/f31b || error "ln failed"
3533         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3534         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3535 }
3536 run_test 31b "unlink file with multiple links while open ======="
3537
3538 test_31c() {
3539         touch $DIR/f31 || error "touch $DIR/f31 failed"
3540         ln $DIR/f31 $DIR/f31c || error "ln failed"
3541         multiop_bg_pause $DIR/f31 O_uc ||
3542                 error "multiop_bg_pause for $DIR/f31 failed"
3543         MULTIPID=$!
3544         $MULTIOP $DIR/f31c Ouc
3545         kill -USR1 $MULTIPID
3546         wait $MULTIPID
3547 }
3548 run_test 31c "open-unlink file with multiple links ============="
3549
3550 test_31d() {
3551         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3552         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3553 }
3554 run_test 31d "remove of open directory ========================="
3555
3556 test_31e() { # bug 2904
3557         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3558 }
3559 run_test 31e "remove of open non-empty directory ==============="
3560
3561 test_31f() { # bug 4554
3562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3563
3564         set -vx
3565         test_mkdir $DIR/d31f
3566         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3567         cp /etc/hosts $DIR/d31f
3568         ls -l $DIR/d31f
3569         $LFS getstripe $DIR/d31f/hosts
3570         multiop_bg_pause $DIR/d31f D_c || return 1
3571         MULTIPID=$!
3572
3573         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3574         test_mkdir $DIR/d31f
3575         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3576         cp /etc/hosts $DIR/d31f
3577         ls -l $DIR/d31f
3578         $LFS getstripe $DIR/d31f/hosts
3579         multiop_bg_pause $DIR/d31f D_c || return 1
3580         MULTIPID2=$!
3581
3582         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3583         wait $MULTIPID || error "first opendir $MULTIPID failed"
3584
3585         sleep 6
3586
3587         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3588         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3589         set +vx
3590 }
3591 run_test 31f "remove of open directory with open-unlink file ==="
3592
3593 test_31g() {
3594         echo "-- cross directory link --"
3595         test_mkdir -c1 $DIR/${tdir}ga
3596         test_mkdir -c1 $DIR/${tdir}gb
3597         touch $DIR/${tdir}ga/f
3598         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3599         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3600         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3601         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3602         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3603 }
3604 run_test 31g "cross directory link==============="
3605
3606 test_31h() {
3607         echo "-- cross directory link --"
3608         test_mkdir -c1 $DIR/${tdir}
3609         test_mkdir -c1 $DIR/${tdir}/dir
3610         touch $DIR/${tdir}/f
3611         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3612         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3613         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3614         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3615         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3616 }
3617 run_test 31h "cross directory link under child==============="
3618
3619 test_31i() {
3620         echo "-- cross directory link --"
3621         test_mkdir -c1 $DIR/$tdir
3622         test_mkdir -c1 $DIR/$tdir/dir
3623         touch $DIR/$tdir/dir/f
3624         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3625         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3626         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3627         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3628         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3629 }
3630 run_test 31i "cross directory link under parent==============="
3631
3632 test_31j() {
3633         test_mkdir -c1 -p $DIR/$tdir
3634         test_mkdir -c1 -p $DIR/$tdir/dir1
3635         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3636         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3637         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3638         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3639         return 0
3640 }
3641 run_test 31j "link for directory==============="
3642
3643 test_31k() {
3644         test_mkdir -c1 -p $DIR/$tdir
3645         touch $DIR/$tdir/s
3646         touch $DIR/$tdir/exist
3647         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3648         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3649         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3650         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3651         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3652         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3653         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3654         return 0
3655 }
3656 run_test 31k "link to file: the same, non-existing, dir==============="
3657
3658 test_31m() {
3659         mkdir $DIR/d31m
3660         touch $DIR/d31m/s
3661         mkdir $DIR/d31m2
3662         touch $DIR/d31m2/exist
3663         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3664         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3665         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3666         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3667         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3668         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3669         return 0
3670 }
3671 run_test 31m "link to file: the same, non-existing, dir==============="
3672
3673 test_31n() {
3674         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3675         nlink=$(stat --format=%h $DIR/$tfile)
3676         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3677         local fd=$(free_fd)
3678         local cmd="exec $fd<$DIR/$tfile"
3679         eval $cmd
3680         cmd="exec $fd<&-"
3681         trap "eval $cmd" EXIT
3682         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3683         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3684         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3685         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3686         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3687         eval $cmd
3688 }
3689 run_test 31n "check link count of unlinked file"
3690
3691 link_one() {
3692         local tempfile=$(mktemp $1_XXXXXX)
3693         mlink $tempfile $1 2> /dev/null &&
3694                 echo "$BASHPID: link $tempfile to $1 succeeded"
3695         munlink $tempfile
3696 }
3697
3698 test_31o() { # LU-2901
3699         test_mkdir $DIR/$tdir
3700         for LOOP in $(seq 100); do
3701                 rm -f $DIR/$tdir/$tfile*
3702                 for THREAD in $(seq 8); do
3703                         link_one $DIR/$tdir/$tfile.$LOOP &
3704                 done
3705                 wait
3706                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3707                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3708                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3709                         break || true
3710         done
3711 }
3712 run_test 31o "duplicate hard links with same filename"
3713
3714 test_31p() {
3715         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3716
3717         test_mkdir $DIR/$tdir
3718         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3719         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3720
3721         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3722                 error "open unlink test1 failed"
3723         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3724                 error "open unlink test2 failed"
3725
3726         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3727                 error "test1 still exists"
3728         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3729                 error "test2 still exists"
3730 }
3731 run_test 31p "remove of open striped directory"
3732
3733 test_31q() {
3734         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3735
3736         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3737         index=$($LFS getdirstripe -i $DIR/$tdir)
3738         [ $index -eq 3 ] || error "first stripe index $index != 3"
3739         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3740         [ $index -eq 1 ] || error "second stripe index $index != 1"
3741
3742         # when "-c <stripe_count>" is set, the number of MDTs specified after
3743         # "-i" should equal to the stripe count
3744         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3745 }
3746 run_test 31q "create striped directory on specific MDTs"
3747
3748 #LU-14949
3749 test_31r() {
3750         touch $DIR/$tfile.target
3751         touch $DIR/$tfile.source
3752
3753         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3754         $LCTL set_param fail_loc=0x1419 fail_val=3
3755         cat $DIR/$tfile.target &
3756         CATPID=$!
3757
3758         # Guarantee open is waiting before we get here
3759         sleep 1
3760         mv $DIR/$tfile.source $DIR/$tfile.target
3761
3762         wait $CATPID
3763         RC=$?
3764         if [[ $RC -ne 0 ]]; then
3765                 error "open with cat failed, rc=$RC"
3766         fi
3767 }
3768 run_test 31r "open-rename(replace) race"
3769
3770 cleanup_test32_mount() {
3771         local rc=0
3772         trap 0
3773         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3774         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3775         losetup -d $loopdev || true
3776         rm -rf $DIR/$tdir
3777         return $rc
3778 }
3779
3780 test_32a() {
3781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3782
3783         echo "== more mountpoints and symlinks ================="
3784         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3785         trap cleanup_test32_mount EXIT
3786         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3787         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3788                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3789         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3790                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3791         cleanup_test32_mount
3792 }
3793 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3794
3795 test_32b() {
3796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3797
3798         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3799         trap cleanup_test32_mount EXIT
3800         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3801         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3802                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3803         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3804                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3805         cleanup_test32_mount
3806 }
3807 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3808
3809 test_32c() {
3810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3811
3812         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3813         trap cleanup_test32_mount EXIT
3814         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3815         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3816                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3817         test_mkdir -p $DIR/$tdir/d2/test_dir
3818         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3819                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3820         cleanup_test32_mount
3821 }
3822 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3823
3824 test_32d() {
3825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3826
3827         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3828         trap cleanup_test32_mount EXIT
3829         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3830         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3831                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3832         test_mkdir -p $DIR/$tdir/d2/test_dir
3833         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3834                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3835         cleanup_test32_mount
3836 }
3837 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3838
3839 test_32e() {
3840         rm -fr $DIR/$tdir
3841         test_mkdir -p $DIR/$tdir/tmp
3842         local tmp_dir=$DIR/$tdir/tmp
3843         ln -s $DIR/$tdir $tmp_dir/symlink11
3844         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3845         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3846         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3847 }
3848 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3849
3850 test_32f() {
3851         rm -fr $DIR/$tdir
3852         test_mkdir -p $DIR/$tdir/tmp
3853         local tmp_dir=$DIR/$tdir/tmp
3854         ln -s $DIR/$tdir $tmp_dir/symlink11
3855         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3856         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3857         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3858 }
3859 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3860
3861 test_32g() {
3862         local tmp_dir=$DIR/$tdir/tmp
3863         test_mkdir -p $tmp_dir
3864         test_mkdir $DIR/${tdir}2
3865         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3866         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3867         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3868         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3869         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3870         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3871 }
3872 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3873
3874 test_32h() {
3875         rm -fr $DIR/$tdir $DIR/${tdir}2
3876         tmp_dir=$DIR/$tdir/tmp
3877         test_mkdir -p $tmp_dir
3878         test_mkdir $DIR/${tdir}2
3879         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3880         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3881         ls $tmp_dir/symlink12 || error "listing symlink12"
3882         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3883 }
3884 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3885
3886 test_32i() {
3887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3888
3889         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3890         trap cleanup_test32_mount EXIT
3891         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3892         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3893                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3894         touch $DIR/$tdir/test_file
3895         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3896                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3897         cleanup_test32_mount
3898 }
3899 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3900
3901 test_32j() {
3902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3903
3904         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3905         trap cleanup_test32_mount EXIT
3906         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3907         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3908                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3909         touch $DIR/$tdir/test_file
3910         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3911                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3912         cleanup_test32_mount
3913 }
3914 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3915
3916 test_32k() {
3917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3918
3919         rm -fr $DIR/$tdir
3920         trap cleanup_test32_mount EXIT
3921         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3922         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3923                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3924         test_mkdir -p $DIR/$tdir/d2
3925         touch $DIR/$tdir/d2/test_file || error "touch failed"
3926         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3927                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3928         cleanup_test32_mount
3929 }
3930 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3931
3932 test_32l() {
3933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3934
3935         rm -fr $DIR/$tdir
3936         trap cleanup_test32_mount EXIT
3937         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3938         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3939                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3940         test_mkdir -p $DIR/$tdir/d2
3941         touch $DIR/$tdir/d2/test_file || error "touch failed"
3942         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3943                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3944         cleanup_test32_mount
3945 }
3946 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3947
3948 test_32m() {
3949         rm -fr $DIR/d32m
3950         test_mkdir -p $DIR/d32m/tmp
3951         TMP_DIR=$DIR/d32m/tmp
3952         ln -s $DIR $TMP_DIR/symlink11
3953         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3954         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3955                 error "symlink11 not a link"
3956         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3957                 error "symlink01 not a link"
3958 }
3959 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3960
3961 test_32n() {
3962         rm -fr $DIR/d32n
3963         test_mkdir -p $DIR/d32n/tmp
3964         TMP_DIR=$DIR/d32n/tmp
3965         ln -s $DIR $TMP_DIR/symlink11
3966         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3967         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3968         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3969 }
3970 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3971
3972 test_32o() {
3973         touch $DIR/$tfile
3974         test_mkdir -p $DIR/d32o/tmp
3975         TMP_DIR=$DIR/d32o/tmp
3976         ln -s $DIR/$tfile $TMP_DIR/symlink12
3977         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3978         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3979                 error "symlink12 not a link"
3980         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3981         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3982                 error "$DIR/d32o/tmp/symlink12 not file type"
3983         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3984                 error "$DIR/d32o/symlink02 not file type"
3985 }
3986 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3987
3988 test_32p() {
3989         log 32p_1
3990         rm -fr $DIR/d32p
3991         log 32p_2
3992         rm -f $DIR/$tfile
3993         log 32p_3
3994         touch $DIR/$tfile
3995         log 32p_4
3996         test_mkdir -p $DIR/d32p/tmp
3997         log 32p_5
3998         TMP_DIR=$DIR/d32p/tmp
3999         log 32p_6
4000         ln -s $DIR/$tfile $TMP_DIR/symlink12
4001         log 32p_7
4002         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4003         log 32p_8
4004         cat $DIR/d32p/tmp/symlink12 ||
4005                 error "Can't open $DIR/d32p/tmp/symlink12"
4006         log 32p_9
4007         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4008         log 32p_10
4009 }
4010 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4011
4012 test_32q() {
4013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4014
4015         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4016         trap cleanup_test32_mount EXIT
4017         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4018         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4019         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4020                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4021         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4022         cleanup_test32_mount
4023 }
4024 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4025
4026 test_32r() {
4027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4028
4029         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4030         trap cleanup_test32_mount EXIT
4031         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4032         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4033         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4034                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4035         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4036         cleanup_test32_mount
4037 }
4038 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4039
4040 test_33aa() {
4041         rm -f $DIR/$tfile
4042         touch $DIR/$tfile
4043         chmod 444 $DIR/$tfile
4044         chown $RUNAS_ID $DIR/$tfile
4045         log 33_1
4046         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4047         log 33_2
4048 }
4049 run_test 33aa "write file with mode 444 (should return error)"
4050
4051 test_33a() {
4052         rm -fr $DIR/$tdir
4053         test_mkdir $DIR/$tdir
4054         chown $RUNAS_ID $DIR/$tdir
4055         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4056                 error "$RUNAS create $tdir/$tfile failed"
4057         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4058                 error "open RDWR" || true
4059 }
4060 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4061
4062 test_33b() {
4063         rm -fr $DIR/$tdir
4064         test_mkdir $DIR/$tdir
4065         chown $RUNAS_ID $DIR/$tdir
4066         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4067 }
4068 run_test 33b "test open file with malformed flags (No panic)"
4069
4070 test_33c() {
4071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4072         remote_ost_nodsh && skip "remote OST with nodsh"
4073
4074         local ostnum
4075         local ostname
4076         local write_bytes
4077         local all_zeros
4078
4079         all_zeros=true
4080         test_mkdir $DIR/$tdir
4081         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4082
4083         sync
4084         for ostnum in $(seq $OSTCOUNT); do
4085                 # test-framework's OST numbering is one-based, while Lustre's
4086                 # is zero-based
4087                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4088                 # check if at least some write_bytes stats are counted
4089                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4090                               obdfilter.$ostname.stats |
4091                               awk '/^write_bytes/ {print $7}' )
4092                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4093                 if (( ${write_bytes:-0} > 0 )); then
4094                         all_zeros=false
4095                         break
4096                 fi
4097         done
4098
4099         $all_zeros || return 0
4100
4101         # Write four bytes
4102         echo foo > $DIR/$tdir/bar
4103         # Really write them
4104         sync
4105
4106         # Total up write_bytes after writing.  We'd better find non-zeros.
4107         for ostnum in $(seq $OSTCOUNT); do
4108                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4109                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4110                               obdfilter/$ostname/stats |
4111                               awk '/^write_bytes/ {print $7}' )
4112                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4113                 if (( ${write_bytes:-0} > 0 )); then
4114                         all_zeros=false
4115                         break
4116                 fi
4117         done
4118
4119         if $all_zeros; then
4120                 for ostnum in $(seq $OSTCOUNT); do
4121                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4122                         echo "Check write_bytes is in obdfilter.*.stats:"
4123                         do_facet ost$ostnum lctl get_param -n \
4124                                 obdfilter.$ostname.stats
4125                 done
4126                 error "OST not keeping write_bytes stats (b=22312)"
4127         fi
4128 }
4129 run_test 33c "test write_bytes stats"
4130
4131 test_33d() {
4132         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4134
4135         local MDTIDX=1
4136         local remote_dir=$DIR/$tdir/remote_dir
4137
4138         test_mkdir $DIR/$tdir
4139         $LFS mkdir -i $MDTIDX $remote_dir ||
4140                 error "create remote directory failed"
4141
4142         touch $remote_dir/$tfile
4143         chmod 444 $remote_dir/$tfile
4144         chown $RUNAS_ID $remote_dir/$tfile
4145
4146         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4147
4148         chown $RUNAS_ID $remote_dir
4149         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4150                                         error "create" || true
4151         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4152                                     error "open RDWR" || true
4153         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4154 }
4155 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4156
4157 test_33e() {
4158         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4159
4160         mkdir $DIR/$tdir
4161
4162         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4163         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4164         mkdir $DIR/$tdir/local_dir
4165
4166         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4167         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4168         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4169
4170         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4171                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4172
4173         rmdir $DIR/$tdir/* || error "rmdir failed"
4174
4175         umask 777
4176         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4177         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4178         mkdir $DIR/$tdir/local_dir
4179
4180         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4181         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4182         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4183
4184         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4185                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4186
4187         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4188
4189         umask 000
4190         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4191         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4192         mkdir $DIR/$tdir/local_dir
4193
4194         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4195         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4196         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4197
4198         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4199                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4200 }
4201 run_test 33e "mkdir and striped directory should have same mode"
4202
4203 cleanup_33f() {
4204         trap 0
4205         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4206 }
4207
4208 test_33f() {
4209         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4210         remote_mds_nodsh && skip "remote MDS with nodsh"
4211
4212         mkdir $DIR/$tdir
4213         chmod go+rwx $DIR/$tdir
4214         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4215         trap cleanup_33f EXIT
4216
4217         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4218                 error "cannot create striped directory"
4219
4220         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4221                 error "cannot create files in striped directory"
4222
4223         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4224                 error "cannot remove files in striped directory"
4225
4226         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4227                 error "cannot remove striped directory"
4228
4229         cleanup_33f
4230 }
4231 run_test 33f "nonroot user can create, access, and remove a striped directory"
4232
4233 test_33g() {
4234         mkdir -p $DIR/$tdir/dir2
4235
4236         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4237         echo $err
4238         [[ $err =~ "exists" ]] || error "Not exists error"
4239 }
4240 run_test 33g "nonroot user create already existing root created file"
4241
4242 test_33h() {
4243         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4244         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4245                 skip "Need MDS version at least 2.13.50"
4246
4247         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4248                 error "mkdir $tdir failed"
4249         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4250
4251         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4252         local index2
4253
4254         for fname in $DIR/$tdir/$tfile.bak \
4255                      $DIR/$tdir/$tfile.SAV \
4256                      $DIR/$tdir/$tfile.orig \
4257                      $DIR/$tdir/$tfile~; do
4258                 touch $fname  || error "touch $fname failed"
4259                 index2=$($LFS getstripe -m $fname)
4260                 [ $index -eq $index2 ] ||
4261                         error "$fname MDT index mismatch $index != $index2"
4262         done
4263
4264         local failed=0
4265         for i in {1..250}; do
4266                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4267                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4268                         touch $fname  || error "touch $fname failed"
4269                         index2=$($LFS getstripe -m $fname)
4270                         if [[ $index != $index2 ]]; then
4271                                 failed=$((failed + 1))
4272                                 echo "$fname MDT index mismatch $index != $index2"
4273                         fi
4274                 done
4275         done
4276         echo "$failed MDT index mismatches"
4277         (( failed < 20 )) || error "MDT index mismatch $failed times"
4278
4279 }
4280 run_test 33h "temp file is located on the same MDT as target"
4281
4282 test_33i()
4283 {
4284         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4285
4286         local FNAME=$(str_repeat 'f' 250)
4287
4288         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4289         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4290
4291         local count
4292         local total
4293
4294         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4295
4296         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4297
4298         lctl --device %$MDC deactivate
4299         stack_trap "lctl --device %$MDC activate"
4300         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4301         total=$(\ls -l $DIR/$tdir | wc -l)
4302         # "ls -l" will list total in the first line
4303         total=$((total - 1))
4304         (( total + count == 1000 )) ||
4305                 error "ls list $total files, $count files on MDT1"
4306 }
4307 run_test 33i "striped directory can be accessed when one MDT is down"
4308
4309 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4310 test_34a() {
4311         rm -f $DIR/f34
4312         $MCREATE $DIR/f34 || error "mcreate failed"
4313         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4314                 error "getstripe failed"
4315         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4316         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4317                 error "getstripe failed"
4318         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4319                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4320 }
4321 run_test 34a "truncate file that has not been opened ==========="
4322
4323 test_34b() {
4324         [ ! -f $DIR/f34 ] && test_34a
4325         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4326                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4327         $OPENFILE -f O_RDONLY $DIR/f34
4328         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4329                 error "getstripe failed"
4330         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4331                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4332 }
4333 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4334
4335 test_34c() {
4336         [ ! -f $DIR/f34 ] && test_34a
4337         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4338                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4339         $OPENFILE -f O_RDWR $DIR/f34
4340         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4341                 error "$LFS getstripe failed"
4342         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4343                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4344 }
4345 run_test 34c "O_RDWR opening file-with-size works =============="
4346
4347 test_34d() {
4348         [ ! -f $DIR/f34 ] && test_34a
4349         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4350                 error "dd failed"
4351         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4352                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4353         rm $DIR/f34
4354 }
4355 run_test 34d "write to sparse file ============================="
4356
4357 test_34e() {
4358         rm -f $DIR/f34e
4359         $MCREATE $DIR/f34e || error "mcreate failed"
4360         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4361         $CHECKSTAT -s 1000 $DIR/f34e ||
4362                 error "Size of $DIR/f34e not equal to 1000 bytes"
4363         $OPENFILE -f O_RDWR $DIR/f34e
4364         $CHECKSTAT -s 1000 $DIR/f34e ||
4365                 error "Size of $DIR/f34e not equal to 1000 bytes"
4366 }
4367 run_test 34e "create objects, some with size and some without =="
4368
4369 test_34f() { # bug 6242, 6243
4370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4371
4372         SIZE34F=48000
4373         rm -f $DIR/f34f
4374         $MCREATE $DIR/f34f || error "mcreate failed"
4375         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4376         dd if=$DIR/f34f of=$TMP/f34f
4377         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4378         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4379         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4380         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4381         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4382 }
4383 run_test 34f "read from a file with no objects until EOF ======="
4384
4385 test_34g() {
4386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4387
4388         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4389                 error "dd failed"
4390         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4391         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4392                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4393         cancel_lru_locks osc
4394         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4395                 error "wrong size after lock cancel"
4396
4397         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4398         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4399                 error "expanding truncate failed"
4400         cancel_lru_locks osc
4401         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4402                 error "wrong expanded size after lock cancel"
4403 }
4404 run_test 34g "truncate long file ==============================="
4405
4406 test_34h() {
4407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4408
4409         local gid=10
4410         local sz=1000
4411
4412         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4413         sync # Flush the cache so that multiop below does not block on cache
4414              # flush when getting the group lock
4415         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4416         MULTIPID=$!
4417
4418         # Since just timed wait is not good enough, let's do a sync write
4419         # that way we are sure enough time for a roundtrip + processing
4420         # passed + 2 seconds of extra margin.
4421         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4422         rm $DIR/${tfile}-1
4423         sleep 2
4424
4425         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4426                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4427                 kill -9 $MULTIPID
4428         fi
4429         wait $MULTIPID
4430         local nsz=`stat -c %s $DIR/$tfile`
4431         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4432 }
4433 run_test 34h "ftruncate file under grouplock should not block"
4434
4435 test_35a() {
4436         cp /bin/sh $DIR/f35a
4437         chmod 444 $DIR/f35a
4438         chown $RUNAS_ID $DIR/f35a
4439         $RUNAS $DIR/f35a && error || true
4440         rm $DIR/f35a
4441 }
4442 run_test 35a "exec file with mode 444 (should return and not leak)"
4443
4444 test_36a() {
4445         rm -f $DIR/f36
4446         utime $DIR/f36 || error "utime failed for MDS"
4447 }
4448 run_test 36a "MDS utime check (mknod, utime)"
4449
4450 test_36b() {
4451         echo "" > $DIR/f36
4452         utime $DIR/f36 || error "utime failed for OST"
4453 }
4454 run_test 36b "OST utime check (open, utime)"
4455
4456 test_36c() {
4457         rm -f $DIR/d36/f36
4458         test_mkdir $DIR/d36
4459         chown $RUNAS_ID $DIR/d36
4460         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4461 }
4462 run_test 36c "non-root MDS utime check (mknod, utime)"
4463
4464 test_36d() {
4465         [ ! -d $DIR/d36 ] && test_36c
4466         echo "" > $DIR/d36/f36
4467         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4468 }
4469 run_test 36d "non-root OST utime check (open, utime)"
4470
4471 test_36e() {
4472         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4473
4474         test_mkdir $DIR/$tdir
4475         touch $DIR/$tdir/$tfile
4476         $RUNAS utime $DIR/$tdir/$tfile &&
4477                 error "utime worked, expected failure" || true
4478 }
4479 run_test 36e "utime on non-owned file (should return error)"
4480
4481 subr_36fh() {
4482         local fl="$1"
4483         local LANG_SAVE=$LANG
4484         local LC_LANG_SAVE=$LC_LANG
4485         export LANG=C LC_LANG=C # for date language
4486
4487         DATESTR="Dec 20  2000"
4488         test_mkdir $DIR/$tdir
4489         lctl set_param fail_loc=$fl
4490         date; date +%s
4491         cp /etc/hosts $DIR/$tdir/$tfile
4492         sync & # write RPC generated with "current" inode timestamp, but delayed
4493         sleep 1
4494         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4495         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4496         cancel_lru_locks $OSC
4497         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4498         date; date +%s
4499         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4500                 echo "BEFORE: $LS_BEFORE" && \
4501                 echo "AFTER : $LS_AFTER" && \
4502                 echo "WANT  : $DATESTR" && \
4503                 error "$DIR/$tdir/$tfile timestamps changed" || true
4504
4505         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4506 }
4507
4508 test_36f() {
4509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4510
4511         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4512         subr_36fh "0x80000214"
4513 }
4514 run_test 36f "utime on file racing with OST BRW write =========="
4515
4516 test_36g() {
4517         remote_ost_nodsh && skip "remote OST with nodsh"
4518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4519         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4520                 skip "Need MDS version at least 2.12.51"
4521
4522         local fmd_max_age
4523         local fmd
4524         local facet="ost1"
4525         local tgt="obdfilter"
4526
4527         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4528
4529         test_mkdir $DIR/$tdir
4530         fmd_max_age=$(do_facet $facet \
4531                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4532                 head -n 1")
4533
4534         echo "FMD max age: ${fmd_max_age}s"
4535         touch $DIR/$tdir/$tfile
4536         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4537                 gawk '{cnt=cnt+$1}  END{print cnt}')
4538         echo "FMD before: $fmd"
4539         [[ $fmd == 0 ]] &&
4540                 error "FMD wasn't create by touch"
4541         sleep $((fmd_max_age + 12))
4542         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4543                 gawk '{cnt=cnt+$1}  END{print cnt}')
4544         echo "FMD after: $fmd"
4545         [[ $fmd == 0 ]] ||
4546                 error "FMD wasn't expired by ping"
4547 }
4548 run_test 36g "FMD cache expiry ====================="
4549
4550 test_36h() {
4551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4552
4553         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4554         subr_36fh "0x80000227"
4555 }
4556 run_test 36h "utime on file racing with OST BRW write =========="
4557
4558 test_36i() {
4559         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4560
4561         test_mkdir $DIR/$tdir
4562         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4563
4564         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4565         local new_mtime=$((mtime + 200))
4566
4567         #change Modify time of striped dir
4568         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4569                         error "change mtime failed"
4570
4571         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4572
4573         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4574 }
4575 run_test 36i "change mtime on striped directory"
4576
4577 # test_37 - duplicate with tests 32q 32r
4578
4579 test_38() {
4580         local file=$DIR/$tfile
4581         touch $file
4582         openfile -f O_DIRECTORY $file
4583         local RC=$?
4584         local ENOTDIR=20
4585         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4586         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4587 }
4588 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4589
4590 test_39a() { # was test_39
4591         touch $DIR/$tfile
4592         touch $DIR/${tfile}2
4593 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4594 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4595 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4596         sleep 2
4597         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4598         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4599                 echo "mtime"
4600                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4601                 echo "atime"
4602                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4603                 echo "ctime"
4604                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4605                 error "O_TRUNC didn't change timestamps"
4606         fi
4607 }
4608 run_test 39a "mtime changed on create"
4609
4610 test_39b() {
4611         test_mkdir -c1 $DIR/$tdir
4612         cp -p /etc/passwd $DIR/$tdir/fopen
4613         cp -p /etc/passwd $DIR/$tdir/flink
4614         cp -p /etc/passwd $DIR/$tdir/funlink
4615         cp -p /etc/passwd $DIR/$tdir/frename
4616         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4617
4618         sleep 1
4619         echo "aaaaaa" >> $DIR/$tdir/fopen
4620         echo "aaaaaa" >> $DIR/$tdir/flink
4621         echo "aaaaaa" >> $DIR/$tdir/funlink
4622         echo "aaaaaa" >> $DIR/$tdir/frename
4623
4624         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4625         local link_new=`stat -c %Y $DIR/$tdir/flink`
4626         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4627         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4628
4629         cat $DIR/$tdir/fopen > /dev/null
4630         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4631         rm -f $DIR/$tdir/funlink2
4632         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4633
4634         for (( i=0; i < 2; i++ )) ; do
4635                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4636                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4637                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4638                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4639
4640                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4641                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4642                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4643                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4644
4645                 cancel_lru_locks $OSC
4646                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4647         done
4648 }
4649 run_test 39b "mtime change on open, link, unlink, rename  ======"
4650
4651 # this should be set to past
4652 TEST_39_MTIME=`date -d "1 year ago" +%s`
4653
4654 # bug 11063
4655 test_39c() {
4656         touch $DIR1/$tfile
4657         sleep 2
4658         local mtime0=`stat -c %Y $DIR1/$tfile`
4659
4660         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4661         local mtime1=`stat -c %Y $DIR1/$tfile`
4662         [ "$mtime1" = $TEST_39_MTIME ] || \
4663                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4664
4665         local d1=`date +%s`
4666         echo hello >> $DIR1/$tfile
4667         local d2=`date +%s`
4668         local mtime2=`stat -c %Y $DIR1/$tfile`
4669         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4670                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4671
4672         mv $DIR1/$tfile $DIR1/$tfile-1
4673
4674         for (( i=0; i < 2; i++ )) ; do
4675                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4676                 [ "$mtime2" = "$mtime3" ] || \
4677                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4678
4679                 cancel_lru_locks $OSC
4680                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4681         done
4682 }
4683 run_test 39c "mtime change on rename ==========================="
4684
4685 # bug 21114
4686 test_39d() {
4687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4688
4689         touch $DIR1/$tfile
4690         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4691
4692         for (( i=0; i < 2; i++ )) ; do
4693                 local mtime=`stat -c %Y $DIR1/$tfile`
4694                 [ $mtime = $TEST_39_MTIME ] || \
4695                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4696
4697                 cancel_lru_locks $OSC
4698                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4699         done
4700 }
4701 run_test 39d "create, utime, stat =============================="
4702
4703 # bug 21114
4704 test_39e() {
4705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4706
4707         touch $DIR1/$tfile
4708         local mtime1=`stat -c %Y $DIR1/$tfile`
4709
4710         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4711
4712         for (( i=0; i < 2; i++ )) ; do
4713                 local mtime2=`stat -c %Y $DIR1/$tfile`
4714                 [ $mtime2 = $TEST_39_MTIME ] || \
4715                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4716
4717                 cancel_lru_locks $OSC
4718                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4719         done
4720 }
4721 run_test 39e "create, stat, utime, stat ========================"
4722
4723 # bug 21114
4724 test_39f() {
4725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4726
4727         touch $DIR1/$tfile
4728         mtime1=`stat -c %Y $DIR1/$tfile`
4729
4730         sleep 2
4731         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4732
4733         for (( i=0; i < 2; i++ )) ; do
4734                 local mtime2=`stat -c %Y $DIR1/$tfile`
4735                 [ $mtime2 = $TEST_39_MTIME ] || \
4736                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4737
4738                 cancel_lru_locks $OSC
4739                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4740         done
4741 }
4742 run_test 39f "create, stat, sleep, utime, stat ================="
4743
4744 # bug 11063
4745 test_39g() {
4746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4747
4748         echo hello >> $DIR1/$tfile
4749         local mtime1=`stat -c %Y $DIR1/$tfile`
4750
4751         sleep 2
4752         chmod o+r $DIR1/$tfile
4753
4754         for (( i=0; i < 2; i++ )) ; do
4755                 local mtime2=`stat -c %Y $DIR1/$tfile`
4756                 [ "$mtime1" = "$mtime2" ] || \
4757                         error "lost mtime: $mtime2, should be $mtime1"
4758
4759                 cancel_lru_locks $OSC
4760                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4761         done
4762 }
4763 run_test 39g "write, chmod, stat ==============================="
4764
4765 # bug 11063
4766 test_39h() {
4767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4768
4769         touch $DIR1/$tfile
4770         sleep 1
4771
4772         local d1=`date`
4773         echo hello >> $DIR1/$tfile
4774         local mtime1=`stat -c %Y $DIR1/$tfile`
4775
4776         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4777         local d2=`date`
4778         if [ "$d1" != "$d2" ]; then
4779                 echo "write and touch not within one second"
4780         else
4781                 for (( i=0; i < 2; i++ )) ; do
4782                         local mtime2=`stat -c %Y $DIR1/$tfile`
4783                         [ "$mtime2" = $TEST_39_MTIME ] || \
4784                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4785
4786                         cancel_lru_locks $OSC
4787                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4788                 done
4789         fi
4790 }
4791 run_test 39h "write, utime within one second, stat ============="
4792
4793 test_39i() {
4794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4795
4796         touch $DIR1/$tfile
4797         sleep 1
4798
4799         echo hello >> $DIR1/$tfile
4800         local mtime1=`stat -c %Y $DIR1/$tfile`
4801
4802         mv $DIR1/$tfile $DIR1/$tfile-1
4803
4804         for (( i=0; i < 2; i++ )) ; do
4805                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4806
4807                 [ "$mtime1" = "$mtime2" ] || \
4808                         error "lost mtime: $mtime2, should be $mtime1"
4809
4810                 cancel_lru_locks $OSC
4811                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4812         done
4813 }
4814 run_test 39i "write, rename, stat =============================="
4815
4816 test_39j() {
4817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4818
4819         start_full_debug_logging
4820         touch $DIR1/$tfile
4821         sleep 1
4822
4823         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4824         lctl set_param fail_loc=0x80000412
4825         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4826                 error "multiop failed"
4827         local multipid=$!
4828         local mtime1=`stat -c %Y $DIR1/$tfile`
4829
4830         mv $DIR1/$tfile $DIR1/$tfile-1
4831
4832         kill -USR1 $multipid
4833         wait $multipid || error "multiop close failed"
4834
4835         for (( i=0; i < 2; i++ )) ; do
4836                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4837                 [ "$mtime1" = "$mtime2" ] ||
4838                         error "mtime is lost on close: $mtime2, " \
4839                               "should be $mtime1"
4840
4841                 cancel_lru_locks
4842                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4843         done
4844         lctl set_param fail_loc=0
4845         stop_full_debug_logging
4846 }
4847 run_test 39j "write, rename, close, stat ======================="
4848
4849 test_39k() {
4850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4851
4852         touch $DIR1/$tfile
4853         sleep 1
4854
4855         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4856         local multipid=$!
4857         local mtime1=`stat -c %Y $DIR1/$tfile`
4858
4859         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4860
4861         kill -USR1 $multipid
4862         wait $multipid || error "multiop close failed"
4863
4864         for (( i=0; i < 2; i++ )) ; do
4865                 local mtime2=`stat -c %Y $DIR1/$tfile`
4866
4867                 [ "$mtime2" = $TEST_39_MTIME ] || \
4868                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4869
4870                 cancel_lru_locks
4871                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4872         done
4873 }
4874 run_test 39k "write, utime, close, stat ========================"
4875
4876 # this should be set to future
4877 TEST_39_ATIME=`date -d "1 year" +%s`
4878
4879 test_39l() {
4880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4881         remote_mds_nodsh && skip "remote MDS with nodsh"
4882
4883         local atime_diff=$(do_facet $SINGLEMDS \
4884                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4885         rm -rf $DIR/$tdir
4886         mkdir_on_mdt0 $DIR/$tdir
4887
4888         # test setting directory atime to future
4889         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4890         local atime=$(stat -c %X $DIR/$tdir)
4891         [ "$atime" = $TEST_39_ATIME ] ||
4892                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4893
4894         # test setting directory atime from future to now
4895         local now=$(date +%s)
4896         touch -a -d @$now $DIR/$tdir
4897
4898         atime=$(stat -c %X $DIR/$tdir)
4899         [ "$atime" -eq "$now"  ] ||
4900                 error "atime is not updated from future: $atime, $now"
4901
4902         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4903         sleep 3
4904
4905         # test setting directory atime when now > dir atime + atime_diff
4906         local d1=$(date +%s)
4907         ls $DIR/$tdir
4908         local d2=$(date +%s)
4909         cancel_lru_locks mdc
4910         atime=$(stat -c %X $DIR/$tdir)
4911         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4912                 error "atime is not updated  : $atime, should be $d2"
4913
4914         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4915         sleep 3
4916
4917         # test not setting directory atime when now < dir atime + atime_diff
4918         ls $DIR/$tdir
4919         cancel_lru_locks mdc
4920         atime=$(stat -c %X $DIR/$tdir)
4921         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4922                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4923
4924         do_facet $SINGLEMDS \
4925                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4926 }
4927 run_test 39l "directory atime update ==========================="
4928
4929 test_39m() {
4930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4931
4932         touch $DIR1/$tfile
4933         sleep 2
4934         local far_past_mtime=$(date -d "May 29 1953" +%s)
4935         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4936
4937         touch -m -d @$far_past_mtime $DIR1/$tfile
4938         touch -a -d @$far_past_atime $DIR1/$tfile
4939
4940         for (( i=0; i < 2; i++ )) ; do
4941                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4942                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4943                         error "atime or mtime set incorrectly"
4944
4945                 cancel_lru_locks $OSC
4946                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4947         done
4948 }
4949 run_test 39m "test atime and mtime before 1970"
4950
4951 test_39n() { # LU-3832
4952         remote_mds_nodsh && skip "remote MDS with nodsh"
4953
4954         local atime_diff=$(do_facet $SINGLEMDS \
4955                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4956         local atime0
4957         local atime1
4958         local atime2
4959
4960         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4961
4962         rm -rf $DIR/$tfile
4963         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4964         atime0=$(stat -c %X $DIR/$tfile)
4965
4966         sleep 5
4967         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4968         atime1=$(stat -c %X $DIR/$tfile)
4969
4970         sleep 5
4971         cancel_lru_locks mdc
4972         cancel_lru_locks osc
4973         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4974         atime2=$(stat -c %X $DIR/$tfile)
4975
4976         do_facet $SINGLEMDS \
4977                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4978
4979         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4980         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4981 }
4982 run_test 39n "check that O_NOATIME is honored"
4983
4984 test_39o() {
4985         TESTDIR=$DIR/$tdir/$tfile
4986         [ -e $TESTDIR ] && rm -rf $TESTDIR
4987         mkdir -p $TESTDIR
4988         cd $TESTDIR
4989         links1=2
4990         ls
4991         mkdir a b
4992         ls
4993         links2=$(stat -c %h .)
4994         [ $(($links1 + 2)) != $links2 ] &&
4995                 error "wrong links count $(($links1 + 2)) != $links2"
4996         rmdir b
4997         links3=$(stat -c %h .)
4998         [ $(($links1 + 1)) != $links3 ] &&
4999                 error "wrong links count $links1 != $links3"
5000         return 0
5001 }
5002 run_test 39o "directory cached attributes updated after create"
5003
5004 test_39p() {
5005         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5006
5007         local MDTIDX=1
5008         TESTDIR=$DIR/$tdir/$tdir
5009         [ -e $TESTDIR ] && rm -rf $TESTDIR
5010         test_mkdir -p $TESTDIR
5011         cd $TESTDIR
5012         links1=2
5013         ls
5014         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5015         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5016         ls
5017         links2=$(stat -c %h .)
5018         [ $(($links1 + 2)) != $links2 ] &&
5019                 error "wrong links count $(($links1 + 2)) != $links2"
5020         rmdir remote_dir2
5021         links3=$(stat -c %h .)
5022         [ $(($links1 + 1)) != $links3 ] &&
5023                 error "wrong links count $links1 != $links3"
5024         return 0
5025 }
5026 run_test 39p "remote directory cached attributes updated after create ========"
5027
5028 test_39r() {
5029         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5030                 skip "no atime update on old OST"
5031         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5032                 skip_env "ldiskfs only test"
5033         fi
5034
5035         local saved_adiff
5036         saved_adiff=$(do_facet ost1 \
5037                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5038         stack_trap "do_facet ost1 \
5039                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5040
5041         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5042
5043         $LFS setstripe -i 0 $DIR/$tfile
5044         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5045                 error "can't write initial file"
5046         cancel_lru_locks osc
5047
5048         # exceed atime_diff and access file
5049         sleep 6
5050         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5051                 error "can't udpate atime"
5052
5053         local atime_cli=$(stat -c %X $DIR/$tfile)
5054         echo "client atime: $atime_cli"
5055         # allow atime update to be written to device
5056         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5057         sleep 5
5058
5059         local ostdev=$(ostdevname 1)
5060         local fid=($(lfs getstripe -y $DIR/$tfile |
5061                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5062         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5063         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5064
5065         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5066         local atime_ost=$(do_facet ost1 "$cmd" |&
5067                           awk -F'[: ]' '/atime:/ { print $4 }')
5068         (( atime_cli == atime_ost )) ||
5069                 error "atime on client $atime_cli != ost $atime_ost"
5070 }
5071 run_test 39r "lazy atime update on OST"
5072
5073 test_39q() { # LU-8041
5074         local testdir=$DIR/$tdir
5075         mkdir -p $testdir
5076         multiop_bg_pause $testdir D_c || error "multiop failed"
5077         local multipid=$!
5078         cancel_lru_locks mdc
5079         kill -USR1 $multipid
5080         local atime=$(stat -c %X $testdir)
5081         [ "$atime" -ne 0 ] || error "atime is zero"
5082 }
5083 run_test 39q "close won't zero out atime"
5084
5085 test_40() {
5086         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5087         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5088                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5089         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5090                 error "$tfile is not 4096 bytes in size"
5091 }
5092 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5093
5094 test_41() {
5095         # bug 1553
5096         small_write $DIR/f41 18
5097 }
5098 run_test 41 "test small file write + fstat ====================="
5099
5100 count_ost_writes() {
5101         lctl get_param -n ${OSC}.*.stats |
5102                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5103                         END { printf("%0.0f", writes) }'
5104 }
5105
5106 # decent default
5107 WRITEBACK_SAVE=500
5108 DIRTY_RATIO_SAVE=40
5109 MAX_DIRTY_RATIO=50
5110 BG_DIRTY_RATIO_SAVE=10
5111 MAX_BG_DIRTY_RATIO=25
5112
5113 start_writeback() {
5114         trap 0
5115         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5116         # dirty_ratio, dirty_background_ratio
5117         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5118                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5119                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5120                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5121         else
5122                 # if file not here, we are a 2.4 kernel
5123                 kill -CONT `pidof kupdated`
5124         fi
5125 }
5126
5127 stop_writeback() {
5128         # setup the trap first, so someone cannot exit the test at the
5129         # exact wrong time and mess up a machine
5130         trap start_writeback EXIT
5131         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5132         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5133                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5134                 sysctl -w vm.dirty_writeback_centisecs=0
5135                 sysctl -w vm.dirty_writeback_centisecs=0
5136                 # save and increase /proc/sys/vm/dirty_ratio
5137                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5138                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5139                 # save and increase /proc/sys/vm/dirty_background_ratio
5140                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5141                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5142         else
5143                 # if file not here, we are a 2.4 kernel
5144                 kill -STOP `pidof kupdated`
5145         fi
5146 }
5147
5148 # ensure that all stripes have some grant before we test client-side cache
5149 setup_test42() {
5150         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5151                 dd if=/dev/zero of=$i bs=4k count=1
5152                 rm $i
5153         done
5154 }
5155
5156 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5157 # file truncation, and file removal.
5158 test_42a() {
5159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5160
5161         setup_test42
5162         cancel_lru_locks $OSC
5163         stop_writeback
5164         sync; sleep 1; sync # just to be safe
5165         BEFOREWRITES=`count_ost_writes`
5166         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5167         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5168         AFTERWRITES=`count_ost_writes`
5169         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5170                 error "$BEFOREWRITES < $AFTERWRITES"
5171         start_writeback
5172 }
5173 run_test 42a "ensure that we don't flush on close"
5174
5175 test_42b() {
5176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5177
5178         setup_test42
5179         cancel_lru_locks $OSC
5180         stop_writeback
5181         sync
5182         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5183         BEFOREWRITES=$(count_ost_writes)
5184         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5185         AFTERWRITES=$(count_ost_writes)
5186         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5187                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5188         fi
5189         BEFOREWRITES=$(count_ost_writes)
5190         sync || error "sync: $?"
5191         AFTERWRITES=$(count_ost_writes)
5192         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5193                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5194         fi
5195         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5196         start_writeback
5197         return 0
5198 }
5199 run_test 42b "test destroy of file with cached dirty data ======"
5200
5201 # if these tests just want to test the effect of truncation,
5202 # they have to be very careful.  consider:
5203 # - the first open gets a {0,EOF}PR lock
5204 # - the first write conflicts and gets a {0, count-1}PW
5205 # - the rest of the writes are under {count,EOF}PW
5206 # - the open for truncate tries to match a {0,EOF}PR
5207 #   for the filesize and cancels the PWs.
5208 # any number of fixes (don't get {0,EOF} on open, match
5209 # composite locks, do smarter file size management) fix
5210 # this, but for now we want these tests to verify that
5211 # the cancellation with truncate intent works, so we
5212 # start the file with a full-file pw lock to match against
5213 # until the truncate.
5214 trunc_test() {
5215         test=$1
5216         file=$DIR/$test
5217         offset=$2
5218         cancel_lru_locks $OSC
5219         stop_writeback
5220         # prime the file with 0,EOF PW to match
5221         touch $file
5222         $TRUNCATE $file 0
5223         sync; sync
5224         # now the real test..
5225         dd if=/dev/zero of=$file bs=1024 count=100
5226         BEFOREWRITES=`count_ost_writes`
5227         $TRUNCATE $file $offset
5228         cancel_lru_locks $OSC
5229         AFTERWRITES=`count_ost_writes`
5230         start_writeback
5231 }
5232
5233 test_42c() {
5234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5235
5236         trunc_test 42c 1024
5237         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5238                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5239         rm $file
5240 }
5241 run_test 42c "test partial truncate of file with cached dirty data"
5242
5243 test_42d() {
5244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5245
5246         trunc_test 42d 0
5247         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5248                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5249         rm $file
5250 }
5251 run_test 42d "test complete truncate of file with cached dirty data"
5252
5253 test_42e() { # bug22074
5254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5255
5256         local TDIR=$DIR/${tdir}e
5257         local pages=16 # hardcoded 16 pages, don't change it.
5258         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5259         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5260         local max_dirty_mb
5261         local warmup_files
5262
5263         test_mkdir $DIR/${tdir}e
5264         $LFS setstripe -c 1 $TDIR
5265         createmany -o $TDIR/f $files
5266
5267         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5268
5269         # we assume that with $OSTCOUNT files, at least one of them will
5270         # be allocated on OST0.
5271         warmup_files=$((OSTCOUNT * max_dirty_mb))
5272         createmany -o $TDIR/w $warmup_files
5273
5274         # write a large amount of data into one file and sync, to get good
5275         # avail_grant number from OST.
5276         for ((i=0; i<$warmup_files; i++)); do
5277                 idx=$($LFS getstripe -i $TDIR/w$i)
5278                 [ $idx -ne 0 ] && continue
5279                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5280                 break
5281         done
5282         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5283         sync
5284         $LCTL get_param $proc_osc0/cur_dirty_bytes
5285         $LCTL get_param $proc_osc0/cur_grant_bytes
5286
5287         # create as much dirty pages as we can while not to trigger the actual
5288         # RPCs directly. but depends on the env, VFS may trigger flush during this
5289         # period, hopefully we are good.
5290         for ((i=0; i<$warmup_files; i++)); do
5291                 idx=$($LFS getstripe -i $TDIR/w$i)
5292                 [ $idx -ne 0 ] && continue
5293                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5294         done
5295         $LCTL get_param $proc_osc0/cur_dirty_bytes
5296         $LCTL get_param $proc_osc0/cur_grant_bytes
5297
5298         # perform the real test
5299         $LCTL set_param $proc_osc0/rpc_stats 0
5300         for ((;i<$files; i++)); do
5301                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5302                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5303         done
5304         sync
5305         $LCTL get_param $proc_osc0/rpc_stats
5306
5307         local percent=0
5308         local have_ppr=false
5309         $LCTL get_param $proc_osc0/rpc_stats |
5310                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5311                         # skip lines until we are at the RPC histogram data
5312                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5313                         $have_ppr || continue
5314
5315                         # we only want the percent stat for < 16 pages
5316                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5317
5318                         percent=$((percent + WPCT))
5319                         if [[ $percent -gt 15 ]]; then
5320                                 error "less than 16-pages write RPCs" \
5321                                       "$percent% > 15%"
5322                                 break
5323                         fi
5324                 done
5325         rm -rf $TDIR
5326 }
5327 run_test 42e "verify sub-RPC writes are not done synchronously"
5328
5329 test_43A() { # was test_43
5330         test_mkdir $DIR/$tdir
5331         cp -p /bin/ls $DIR/$tdir/$tfile
5332         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5333         pid=$!
5334         # give multiop a chance to open
5335         sleep 1
5336
5337         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5338         kill -USR1 $pid
5339         # Wait for multiop to exit
5340         wait $pid
5341 }
5342 run_test 43A "execution of file opened for write should return -ETXTBSY"
5343
5344 test_43a() {
5345         test_mkdir $DIR/$tdir
5346         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5347         $DIR/$tdir/sleep 60 &
5348         SLEEP_PID=$!
5349         # Make sure exec of $tdir/sleep wins race with truncate
5350         sleep 1
5351         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5352         kill $SLEEP_PID
5353 }
5354 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5355
5356 test_43b() {
5357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5358
5359         test_mkdir $DIR/$tdir
5360         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5361         $DIR/$tdir/sleep 60 &
5362         SLEEP_PID=$!
5363         # Make sure exec of $tdir/sleep wins race with truncate
5364         sleep 1
5365         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5366         kill $SLEEP_PID
5367 }
5368 run_test 43b "truncate of file being executed should return -ETXTBSY"
5369
5370 test_43c() {
5371         local testdir="$DIR/$tdir"
5372         test_mkdir $testdir
5373         cp $SHELL $testdir/
5374         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5375                 ( cd $testdir && md5sum -c )
5376 }
5377 run_test 43c "md5sum of copy into lustre"
5378
5379 test_44A() { # was test_44
5380         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5381
5382         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5383         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5384 }
5385 run_test 44A "zero length read from a sparse stripe"
5386
5387 test_44a() {
5388         local nstripe=$($LFS getstripe -c -d $DIR)
5389         [ -z "$nstripe" ] && skip "can't get stripe info"
5390         [[ $nstripe -gt $OSTCOUNT ]] &&
5391                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5392
5393         local stride=$($LFS getstripe -S -d $DIR)
5394         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5395                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5396         fi
5397
5398         OFFSETS="0 $((stride/2)) $((stride-1))"
5399         for offset in $OFFSETS; do
5400                 for i in $(seq 0 $((nstripe-1))); do
5401                         local GLOBALOFFSETS=""
5402                         # size in Bytes
5403                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5404                         local myfn=$DIR/d44a-$size
5405                         echo "--------writing $myfn at $size"
5406                         ll_sparseness_write $myfn $size ||
5407                                 error "ll_sparseness_write"
5408                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5409                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5410                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5411
5412                         for j in $(seq 0 $((nstripe-1))); do
5413                                 # size in Bytes
5414                                 size=$((((j + $nstripe )*$stride + $offset)))
5415                                 ll_sparseness_write $myfn $size ||
5416                                         error "ll_sparseness_write"
5417                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5418                         done
5419                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5420                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5421                         rm -f $myfn
5422                 done
5423         done
5424 }
5425 run_test 44a "test sparse pwrite ==============================="
5426
5427 dirty_osc_total() {
5428         tot=0
5429         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5430                 tot=$(($tot + $d))
5431         done
5432         echo $tot
5433 }
5434 do_dirty_record() {
5435         before=`dirty_osc_total`
5436         echo executing "\"$*\""
5437         eval $*
5438         after=`dirty_osc_total`
5439         echo before $before, after $after
5440 }
5441 test_45() {
5442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5443
5444         f="$DIR/f45"
5445         # Obtain grants from OST if it supports it
5446         echo blah > ${f}_grant
5447         stop_writeback
5448         sync
5449         do_dirty_record "echo blah > $f"
5450         [[ $before -eq $after ]] && error "write wasn't cached"
5451         do_dirty_record "> $f"
5452         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5453         do_dirty_record "echo blah > $f"
5454         [[ $before -eq $after ]] && error "write wasn't cached"
5455         do_dirty_record "sync"
5456         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5457         do_dirty_record "echo blah > $f"
5458         [[ $before -eq $after ]] && error "write wasn't cached"
5459         do_dirty_record "cancel_lru_locks osc"
5460         [[ $before -gt $after ]] ||
5461                 error "lock cancellation didn't lower dirty count"
5462         start_writeback
5463 }
5464 run_test 45 "osc io page accounting ============================"
5465
5466 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5467 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5468 # objects offset and an assert hit when an rpc was built with 1023's mapped
5469 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5470 test_46() {
5471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5472
5473         f="$DIR/f46"
5474         stop_writeback
5475         sync
5476         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5477         sync
5478         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5479         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5480         sync
5481         start_writeback
5482 }
5483 run_test 46 "dirtying a previously written page ================"
5484
5485 # test_47 is removed "Device nodes check" is moved to test_28
5486
5487 test_48a() { # bug 2399
5488         [ "$mds1_FSTYPE" = "zfs" ] &&
5489         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5490                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5491
5492         test_mkdir $DIR/$tdir
5493         cd $DIR/$tdir
5494         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5495         test_mkdir $DIR/$tdir
5496         touch foo || error "'touch foo' failed after recreating cwd"
5497         test_mkdir bar
5498         touch .foo || error "'touch .foo' failed after recreating cwd"
5499         test_mkdir .bar
5500         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5501         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5502         cd . || error "'cd .' failed after recreating cwd"
5503         mkdir . && error "'mkdir .' worked after recreating cwd"
5504         rmdir . && error "'rmdir .' worked after recreating cwd"
5505         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5506         cd .. || error "'cd ..' failed after recreating cwd"
5507 }
5508 run_test 48a "Access renamed working dir (should return errors)="
5509
5510 test_48b() { # bug 2399
5511         rm -rf $DIR/$tdir
5512         test_mkdir $DIR/$tdir
5513         cd $DIR/$tdir
5514         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5515         touch foo && error "'touch foo' worked after removing cwd"
5516         mkdir foo && error "'mkdir foo' worked after removing cwd"
5517         touch .foo && error "'touch .foo' worked after removing cwd"
5518         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5519         ls . > /dev/null && error "'ls .' worked after removing cwd"
5520         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5521         mkdir . && error "'mkdir .' worked after removing cwd"
5522         rmdir . && error "'rmdir .' worked after removing cwd"
5523         ln -s . foo && error "'ln -s .' worked after removing cwd"
5524         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5525 }
5526 run_test 48b "Access removed working dir (should return errors)="
5527
5528 test_48c() { # bug 2350
5529         #lctl set_param debug=-1
5530         #set -vx
5531         rm -rf $DIR/$tdir
5532         test_mkdir -p $DIR/$tdir/dir
5533         cd $DIR/$tdir/dir
5534         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5535         $TRACE touch foo && error "touch foo worked after removing cwd"
5536         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5537         touch .foo && error "touch .foo worked after removing cwd"
5538         mkdir .foo && error "mkdir .foo worked after removing cwd"
5539         $TRACE ls . && error "'ls .' worked after removing cwd"
5540         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5541         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5542         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5543         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5544         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5545 }
5546 run_test 48c "Access removed working subdir (should return errors)"
5547
5548 test_48d() { # bug 2350
5549         #lctl set_param debug=-1
5550         #set -vx
5551         rm -rf $DIR/$tdir
5552         test_mkdir -p $DIR/$tdir/dir
5553         cd $DIR/$tdir/dir
5554         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5555         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5556         $TRACE touch foo && error "'touch foo' worked after removing parent"
5557         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5558         touch .foo && error "'touch .foo' worked after removing parent"
5559         mkdir .foo && error "mkdir .foo worked after removing parent"
5560         $TRACE ls . && error "'ls .' worked after removing parent"
5561         $TRACE ls .. && error "'ls ..' worked after removing parent"
5562         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5563         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5564         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5565         true
5566 }
5567 run_test 48d "Access removed parent subdir (should return errors)"
5568
5569 test_48e() { # bug 4134
5570         #lctl set_param debug=-1
5571         #set -vx
5572         rm -rf $DIR/$tdir
5573         test_mkdir -p $DIR/$tdir/dir
5574         cd $DIR/$tdir/dir
5575         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5576         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5577         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5578         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5579         # On a buggy kernel addition of "touch foo" after cd .. will
5580         # produce kernel oops in lookup_hash_it
5581         touch ../foo && error "'cd ..' worked after recreate parent"
5582         cd $DIR
5583         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5584 }
5585 run_test 48e "Access to recreated parent subdir (should return errors)"
5586
5587 test_48f() {
5588         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5589                 skip "need MDS >= 2.13.55"
5590         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5591         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5592                 skip "needs different host for mdt1 mdt2"
5593         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5594
5595         $LFS mkdir -i0 $DIR/$tdir
5596         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5597
5598         for d in sub1 sub2 sub3; do
5599                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5600                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5601                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5602         done
5603
5604         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5605 }
5606 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5607
5608 test_49() { # LU-1030
5609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5610         remote_ost_nodsh && skip "remote OST with nodsh"
5611
5612         # get ost1 size - $FSNAME-OST0000
5613         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5614                 awk '{ print $4 }')
5615         # write 800M at maximum
5616         [[ $ost1_size -lt 2 ]] && ost1_size=2
5617         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5618
5619         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5620         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5621         local dd_pid=$!
5622
5623         # change max_pages_per_rpc while writing the file
5624         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5625         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5626         # loop until dd process exits
5627         while ps ax -opid | grep -wq $dd_pid; do
5628                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5629                 sleep $((RANDOM % 5 + 1))
5630         done
5631         # restore original max_pages_per_rpc
5632         $LCTL set_param $osc1_mppc=$orig_mppc
5633         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5634 }
5635 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5636
5637 test_50() {
5638         # bug 1485
5639         test_mkdir $DIR/$tdir
5640         cd $DIR/$tdir
5641         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5642 }
5643 run_test 50 "special situations: /proc symlinks  ==============="
5644
5645 test_51a() {    # was test_51
5646         # bug 1516 - create an empty entry right after ".." then split dir
5647         test_mkdir -c1 $DIR/$tdir
5648         touch $DIR/$tdir/foo
5649         $MCREATE $DIR/$tdir/bar
5650         rm $DIR/$tdir/foo
5651         createmany -m $DIR/$tdir/longfile 201
5652         FNUM=202
5653         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5654                 $MCREATE $DIR/$tdir/longfile$FNUM
5655                 FNUM=$(($FNUM + 1))
5656                 echo -n "+"
5657         done
5658         echo
5659         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5660 }
5661 run_test 51a "special situations: split htree with empty entry =="
5662
5663 cleanup_print_lfs_df () {
5664         trap 0
5665         $LFS df
5666         $LFS df -i
5667 }
5668
5669 test_51b() {
5670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5671
5672         local dir=$DIR/$tdir
5673         local nrdirs=$((65536 + 100))
5674
5675         # cleanup the directory
5676         rm -fr $dir
5677
5678         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5679
5680         $LFS df
5681         $LFS df -i
5682         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5683         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5684         [[ $numfree -lt $nrdirs ]] &&
5685                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5686
5687         # need to check free space for the directories as well
5688         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5689         numfree=$(( blkfree / $(fs_inode_ksize) ))
5690         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5691
5692         trap cleanup_print_lfs_df EXIT
5693
5694         # create files
5695         createmany -d $dir/d $nrdirs || {
5696                 unlinkmany $dir/d $nrdirs
5697                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5698         }
5699
5700         # really created :
5701         nrdirs=$(ls -U $dir | wc -l)
5702
5703         # unlink all but 100 subdirectories, then check it still works
5704         local left=100
5705         local delete=$((nrdirs - left))
5706
5707         $LFS df
5708         $LFS df -i
5709
5710         # for ldiskfs the nlink count should be 1, but this is OSD specific
5711         # and so this is listed for informational purposes only
5712         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5713         unlinkmany -d $dir/d $delete ||
5714                 error "unlink of first $delete subdirs failed"
5715
5716         echo "nlink between: $(stat -c %h $dir)"
5717         local found=$(ls -U $dir | wc -l)
5718         [ $found -ne $left ] &&
5719                 error "can't find subdirs: found only $found, expected $left"
5720
5721         unlinkmany -d $dir/d $delete $left ||
5722                 error "unlink of second $left subdirs failed"
5723         # regardless of whether the backing filesystem tracks nlink accurately
5724         # or not, the nlink count shouldn't be more than "." and ".." here
5725         local after=$(stat -c %h $dir)
5726         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5727                 echo "nlink after: $after"
5728
5729         cleanup_print_lfs_df
5730 }
5731 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5732
5733 test_51d() {
5734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5735         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5736         local qos_old
5737
5738         test_mkdir $DIR/$tdir
5739         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5740
5741         qos_old=$(do_facet mds1 \
5742                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5743         do_nodes $(comma_list $(mdts_nodes)) \
5744                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5745         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5746                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5747
5748         createmany -o $DIR/$tdir/t- 1000
5749         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5750         for ((n = 0; n < $OSTCOUNT; n++)); do
5751                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5752                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5753                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5754                             '($1 == '$n') { objs += 1 } \
5755                             END { printf("%0.0f", objs) }')
5756                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5757         done
5758         unlinkmany $DIR/$tdir/t- 1000
5759
5760         nlast=0
5761         for ((n = 0; n < $OSTCOUNT; n++)); do
5762                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5763                         { $LFS df && $LFS df -i &&
5764                         error "OST $n has fewer objects vs. OST $nlast" \
5765                               " (${objs[$n]} < ${objs[$nlast]}"; }
5766                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5767                         { $LFS df && $LFS df -i &&
5768                         error "OST $n has fewer objects vs. OST $nlast" \
5769                               " (${objs[$n]} < ${objs[$nlast]}"; }
5770
5771                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5772                         { $LFS df && $LFS df -i &&
5773                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5774                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5775                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5776                         { $LFS df && $LFS df -i &&
5777                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5778                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5779                 nlast=$n
5780         done
5781 }
5782 run_test 51d "check object distribution"
5783
5784 test_51e() {
5785         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5786                 skip_env "ldiskfs only test"
5787         fi
5788
5789         test_mkdir -c1 $DIR/$tdir
5790         test_mkdir -c1 $DIR/$tdir/d0
5791
5792         touch $DIR/$tdir/d0/foo
5793         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5794                 error "file exceed 65000 nlink limit!"
5795         unlinkmany $DIR/$tdir/d0/f- 65001
5796         return 0
5797 }
5798 run_test 51e "check file nlink limit"
5799
5800 test_51f() {
5801         test_mkdir $DIR/$tdir
5802
5803         local max=100000
5804         local ulimit_old=$(ulimit -n)
5805         local spare=20 # number of spare fd's for scripts/libraries, etc.
5806         local mdt=$($LFS getstripe -m $DIR/$tdir)
5807         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5808
5809         echo "MDT$mdt numfree=$numfree, max=$max"
5810         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5811         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5812                 while ! ulimit -n $((numfree + spare)); do
5813                         numfree=$((numfree * 3 / 4))
5814                 done
5815                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5816         else
5817                 echo "left ulimit at $ulimit_old"
5818         fi
5819
5820         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5821                 unlinkmany $DIR/$tdir/f $numfree
5822                 error "create+open $numfree files in $DIR/$tdir failed"
5823         }
5824         ulimit -n $ulimit_old
5825
5826         # if createmany exits at 120s there will be fewer than $numfree files
5827         unlinkmany $DIR/$tdir/f $numfree || true
5828 }
5829 run_test 51f "check many open files limit"
5830
5831 test_52a() {
5832         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5833         test_mkdir $DIR/$tdir
5834         touch $DIR/$tdir/foo
5835         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5836         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5837         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5838         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5839         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5840                                         error "link worked"
5841         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5842         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5843         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5844                                                      error "lsattr"
5845         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5846         cp -r $DIR/$tdir $TMP/
5847         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5848 }
5849 run_test 52a "append-only flag test (should return errors)"
5850
5851 test_52b() {
5852         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5853         test_mkdir $DIR/$tdir
5854         touch $DIR/$tdir/foo
5855         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5856         cat test > $DIR/$tdir/foo && error "cat test worked"
5857         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5858         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5859         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5860                                         error "link worked"
5861         echo foo >> $DIR/$tdir/foo && error "echo worked"
5862         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5863         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5864         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5865         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5866                                                         error "lsattr"
5867         chattr -i $DIR/$tdir/foo || error "chattr failed"
5868
5869         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5870 }
5871 run_test 52b "immutable flag test (should return errors) ======="
5872
5873 test_53() {
5874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5875         remote_mds_nodsh && skip "remote MDS with nodsh"
5876         remote_ost_nodsh && skip "remote OST with nodsh"
5877
5878         local param
5879         local param_seq
5880         local ostname
5881         local mds_last
5882         local mds_last_seq
5883         local ost_last
5884         local ost_last_seq
5885         local ost_last_id
5886         local ostnum
5887         local node
5888         local found=false
5889         local support_last_seq=true
5890
5891         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5892                 support_last_seq=false
5893
5894         # only test MDT0000
5895         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5896         local value
5897         for value in $(do_facet $SINGLEMDS \
5898                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5899                 param=$(echo ${value[0]} | cut -d "=" -f1)
5900                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5901
5902                 if $support_last_seq; then
5903                         param_seq=$(echo $param |
5904                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5905                         mds_last_seq=$(do_facet $SINGLEMDS \
5906                                        $LCTL get_param -n $param_seq)
5907                 fi
5908                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5909
5910                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5911                 node=$(facet_active_host ost$((ostnum+1)))
5912                 param="obdfilter.$ostname.last_id"
5913                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5914                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5915                         ost_last_id=$ost_last
5916
5917                         if $support_last_seq; then
5918                                 ost_last_id=$(echo $ost_last |
5919                                               awk -F':' '{print $2}' |
5920                                               sed -e "s/^0x//g")
5921                                 ost_last_seq=$(echo $ost_last |
5922                                                awk -F':' '{print $1}')
5923                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5924                         fi
5925
5926                         if [[ $ost_last_id != $mds_last ]]; then
5927                                 error "$ost_last_id != $mds_last"
5928                         else
5929                                 found=true
5930                                 break
5931                         fi
5932                 done
5933         done
5934         $found || error "can not match last_seq/last_id for $mdtosc"
5935         return 0
5936 }
5937 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5938
5939 test_54a() {
5940         perl -MSocket -e ';' || skip "no Socket perl module installed"
5941
5942         $SOCKETSERVER $DIR/socket ||
5943                 error "$SOCKETSERVER $DIR/socket failed: $?"
5944         $SOCKETCLIENT $DIR/socket ||
5945                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5946         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5947 }
5948 run_test 54a "unix domain socket test =========================="
5949
5950 test_54b() {
5951         f="$DIR/f54b"
5952         mknod $f c 1 3
5953         chmod 0666 $f
5954         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5955 }
5956 run_test 54b "char device works in lustre ======================"
5957
5958 find_loop_dev() {
5959         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5960         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5961         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5962
5963         for i in $(seq 3 7); do
5964                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5965                 LOOPDEV=$LOOPBASE$i
5966                 LOOPNUM=$i
5967                 break
5968         done
5969 }
5970
5971 cleanup_54c() {
5972         local rc=0
5973         loopdev="$DIR/loop54c"
5974
5975         trap 0
5976         $UMOUNT $DIR/$tdir || rc=$?
5977         losetup -d $loopdev || true
5978         losetup -d $LOOPDEV || true
5979         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5980         return $rc
5981 }
5982
5983 test_54c() {
5984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5985
5986         loopdev="$DIR/loop54c"
5987
5988         find_loop_dev
5989         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5990         trap cleanup_54c EXIT
5991         mknod $loopdev b 7 $LOOPNUM
5992         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5993         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5994         losetup $loopdev $DIR/$tfile ||
5995                 error "can't set up $loopdev for $DIR/$tfile"
5996         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5997         test_mkdir $DIR/$tdir
5998         mount -t ext2 $loopdev $DIR/$tdir ||
5999                 error "error mounting $loopdev on $DIR/$tdir"
6000         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6001                 error "dd write"
6002         df $DIR/$tdir
6003         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6004                 error "dd read"
6005         cleanup_54c
6006 }
6007 run_test 54c "block device works in lustre ====================="
6008
6009 test_54d() {
6010         f="$DIR/f54d"
6011         string="aaaaaa"
6012         mknod $f p
6013         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
6014 }
6015 run_test 54d "fifo device works in lustre ======================"
6016
6017 test_54e() {
6018         f="$DIR/f54e"
6019         string="aaaaaa"
6020         cp -aL /dev/console $f
6021         echo $string > $f || error "echo $string to $f failed"
6022 }
6023 run_test 54e "console/tty device works in lustre ======================"
6024
6025 test_56a() {
6026         local numfiles=3
6027         local numdirs=2
6028         local dir=$DIR/$tdir
6029
6030         rm -rf $dir
6031         test_mkdir -p $dir/dir
6032         for i in $(seq $numfiles); do
6033                 touch $dir/file$i
6034                 touch $dir/dir/file$i
6035         done
6036
6037         local numcomp=$($LFS getstripe --component-count $dir)
6038
6039         [[ $numcomp == 0 ]] && numcomp=1
6040
6041         # test lfs getstripe with --recursive
6042         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6043
6044         [[ $filenum -eq $((numfiles * 2)) ]] ||
6045                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6046         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6047         [[ $filenum -eq $numfiles ]] ||
6048                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6049         echo "$LFS getstripe showed obdidx or l_ost_idx"
6050
6051         # test lfs getstripe with file instead of dir
6052         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6053         [[ $filenum -eq 1 ]] ||
6054                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6055         echo "$LFS getstripe file1 passed"
6056
6057         #test lfs getstripe with --verbose
6058         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6059         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6060                 error "$LFS getstripe --verbose $dir: "\
6061                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6062         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6063                 error "$LFS getstripe $dir: showed lmm_magic"
6064
6065         #test lfs getstripe with -v prints lmm_fid
6066         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6067         local countfids=$((numdirs + numfiles * numcomp))
6068         [[ $filenum -eq $countfids ]] ||
6069                 error "$LFS getstripe -v $dir: "\
6070                       "got $filenum want $countfids lmm_fid"
6071         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6072                 error "$LFS getstripe $dir: showed lmm_fid by default"
6073         echo "$LFS getstripe --verbose passed"
6074
6075         #check for FID information
6076         local fid1=$($LFS getstripe --fid $dir/file1)
6077         local fid2=$($LFS getstripe --verbose $dir/file1 |
6078                      awk '/lmm_fid: / { print $2; exit; }')
6079         local fid3=$($LFS path2fid $dir/file1)
6080
6081         [ "$fid1" != "$fid2" ] &&
6082                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6083         [ "$fid1" != "$fid3" ] &&
6084                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6085         echo "$LFS getstripe --fid passed"
6086
6087         #test lfs getstripe with --obd
6088         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6089                 error "$LFS getstripe --obd wrong_uuid: should return error"
6090
6091         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6092
6093         local ostidx=1
6094         local obduuid=$(ostuuid_from_index $ostidx)
6095         local found=$($LFS getstripe -r --obd $obduuid $dir |
6096                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6097
6098         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6099         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6100                 ((filenum--))
6101         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6102                 ((filenum--))
6103
6104         [[ $found -eq $filenum ]] ||
6105                 error "$LFS getstripe --obd: found $found expect $filenum"
6106         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6107                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6108                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6109                 error "$LFS getstripe --obd: should not show file on other obd"
6110         echo "$LFS getstripe --obd passed"
6111 }
6112 run_test 56a "check $LFS getstripe"
6113
6114 test_56b() {
6115         local dir=$DIR/$tdir
6116         local numdirs=3
6117
6118         test_mkdir $dir
6119         for i in $(seq $numdirs); do
6120                 test_mkdir $dir/dir$i
6121         done
6122
6123         # test lfs getdirstripe default mode is non-recursion, which is
6124         # different from lfs getstripe
6125         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6126
6127         [[ $dircnt -eq 1 ]] ||
6128                 error "$LFS getdirstripe: found $dircnt, not 1"
6129         dircnt=$($LFS getdirstripe --recursive $dir |
6130                 grep -c lmv_stripe_count)
6131         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6132                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6133 }
6134 run_test 56b "check $LFS getdirstripe"
6135
6136 test_56c() {
6137         remote_ost_nodsh && skip "remote OST with nodsh"
6138
6139         local ost_idx=0
6140         local ost_name=$(ostname_from_index $ost_idx)
6141         local old_status=$(ost_dev_status $ost_idx)
6142         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6143
6144         [[ -z "$old_status" ]] ||
6145                 skip_env "OST $ost_name is in $old_status status"
6146
6147         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6148         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6149                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6150         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6151                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6152                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6153         fi
6154
6155         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6156                 error "$LFS df -v showing inactive devices"
6157         sleep_maxage
6158
6159         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6160
6161         [[ "$new_status" =~ "D" ]] ||
6162                 error "$ost_name status is '$new_status', missing 'D'"
6163         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6164                 [[ "$new_status" =~ "N" ]] ||
6165                         error "$ost_name status is '$new_status', missing 'N'"
6166         fi
6167         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6168                 [[ "$new_status" =~ "f" ]] ||
6169                         error "$ost_name status is '$new_status', missing 'f'"
6170         fi
6171
6172         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6173         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6174                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6175         [[ -z "$p" ]] && restore_lustre_params < $p || true
6176         sleep_maxage
6177
6178         new_status=$(ost_dev_status $ost_idx)
6179         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6180                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6181         # can't check 'f' as devices may actually be on flash
6182 }
6183 run_test 56c "check 'lfs df' showing device status"
6184
6185 test_56d() {
6186         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6187         local osts=$($LFS df -v $MOUNT | grep -c OST)
6188
6189         $LFS df $MOUNT
6190
6191         (( mdts == MDSCOUNT )) ||
6192                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6193         (( osts == OSTCOUNT )) ||
6194                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6195 }
6196 run_test 56d "'lfs df -v' prints only configured devices"
6197
6198 test_56e() {
6199         err_enoent=2 # No such file or directory
6200         err_eopnotsupp=95 # Operation not supported
6201
6202         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6203         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6204
6205         # Check for handling of path not exists
6206         output=$($LFS df $enoent_mnt 2>&1)
6207         ret=$?
6208
6209         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6210         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6211                 error "expect failure $err_enoent, not $ret"
6212
6213         # Check for handling of non-Lustre FS
6214         output=$($LFS df $notsup_mnt)
6215         ret=$?
6216
6217         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6218         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6219                 error "expect success $err_eopnotsupp, not $ret"
6220
6221         # Check for multiple LustreFS argument
6222         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6223         ret=$?
6224
6225         [[ $output -eq 3 && $ret -eq 0 ]] ||
6226                 error "expect success 3, not $output, rc = $ret"
6227
6228         # Check for correct non-Lustre FS handling among multiple
6229         # LustreFS argument
6230         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6231                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6232         ret=$?
6233
6234         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6235                 error "expect success 2, not $output, rc = $ret"
6236 }
6237 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6238
6239 NUMFILES=3
6240 NUMDIRS=3
6241 setup_56() {
6242         local local_tdir="$1"
6243         local local_numfiles="$2"
6244         local local_numdirs="$3"
6245         local dir_params="$4"
6246         local dir_stripe_params="$5"
6247
6248         if [ ! -d "$local_tdir" ] ; then
6249                 test_mkdir -p $dir_stripe_params $local_tdir
6250                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6251                 for i in $(seq $local_numfiles) ; do
6252                         touch $local_tdir/file$i
6253                 done
6254                 for i in $(seq $local_numdirs) ; do
6255                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6256                         for j in $(seq $local_numfiles) ; do
6257                                 touch $local_tdir/dir$i/file$j
6258                         done
6259                 done
6260         fi
6261 }
6262
6263 setup_56_special() {
6264         local local_tdir=$1
6265         local local_numfiles=$2
6266         local local_numdirs=$3
6267
6268         setup_56 $local_tdir $local_numfiles $local_numdirs
6269
6270         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6271                 for i in $(seq $local_numfiles) ; do
6272                         mknod $local_tdir/loop${i}b b 7 $i
6273                         mknod $local_tdir/null${i}c c 1 3
6274                         ln -s $local_tdir/file1 $local_tdir/link${i}
6275                 done
6276                 for i in $(seq $local_numdirs) ; do
6277                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6278                         mknod $local_tdir/dir$i/null${i}c c 1 3
6279                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6280                 done
6281         fi
6282 }
6283
6284 test_56g() {
6285         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6286         local expected=$(($NUMDIRS + 2))
6287
6288         setup_56 $dir $NUMFILES $NUMDIRS
6289
6290         # test lfs find with -name
6291         for i in $(seq $NUMFILES) ; do
6292                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6293
6294                 [ $nums -eq $expected ] ||
6295                         error "lfs find -name '*$i' $dir wrong: "\
6296                               "found $nums, expected $expected"
6297         done
6298 }
6299 run_test 56g "check lfs find -name"
6300
6301 test_56h() {
6302         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6303         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6304
6305         setup_56 $dir $NUMFILES $NUMDIRS
6306
6307         # test lfs find with ! -name
6308         for i in $(seq $NUMFILES) ; do
6309                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6310
6311                 [ $nums -eq $expected ] ||
6312                         error "lfs find ! -name '*$i' $dir wrong: "\
6313                               "found $nums, expected $expected"
6314         done
6315 }
6316 run_test 56h "check lfs find ! -name"
6317
6318 test_56i() {
6319         local dir=$DIR/$tdir
6320
6321         test_mkdir $dir
6322
6323         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6324         local out=$($cmd)
6325
6326         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6327 }
6328 run_test 56i "check 'lfs find -ost UUID' skips directories"
6329
6330 test_56j() {
6331         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6332
6333         setup_56_special $dir $NUMFILES $NUMDIRS
6334
6335         local expected=$((NUMDIRS + 1))
6336         local cmd="$LFS find -type d $dir"
6337         local nums=$($cmd | wc -l)
6338
6339         [ $nums -eq $expected ] ||
6340                 error "'$cmd' wrong: found $nums, expected $expected"
6341 }
6342 run_test 56j "check lfs find -type d"
6343
6344 test_56k() {
6345         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6346
6347         setup_56_special $dir $NUMFILES $NUMDIRS
6348
6349         local expected=$(((NUMDIRS + 1) * NUMFILES))
6350         local cmd="$LFS find -type f $dir"
6351         local nums=$($cmd | wc -l)
6352
6353         [ $nums -eq $expected ] ||
6354                 error "'$cmd' wrong: found $nums, expected $expected"
6355 }
6356 run_test 56k "check lfs find -type f"
6357
6358 test_56l() {
6359         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6360
6361         setup_56_special $dir $NUMFILES $NUMDIRS
6362
6363         local expected=$((NUMDIRS + NUMFILES))
6364         local cmd="$LFS find -type b $dir"
6365         local nums=$($cmd | wc -l)
6366
6367         [ $nums -eq $expected ] ||
6368                 error "'$cmd' wrong: found $nums, expected $expected"
6369 }
6370 run_test 56l "check lfs find -type b"
6371
6372 test_56m() {
6373         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6374
6375         setup_56_special $dir $NUMFILES $NUMDIRS
6376
6377         local expected=$((NUMDIRS + NUMFILES))
6378         local cmd="$LFS find -type c $dir"
6379         local nums=$($cmd | wc -l)
6380         [ $nums -eq $expected ] ||
6381                 error "'$cmd' wrong: found $nums, expected $expected"
6382 }
6383 run_test 56m "check lfs find -type c"
6384
6385 test_56n() {
6386         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6387         setup_56_special $dir $NUMFILES $NUMDIRS
6388
6389         local expected=$((NUMDIRS + NUMFILES))
6390         local cmd="$LFS find -type l $dir"
6391         local nums=$($cmd | wc -l)
6392
6393         [ $nums -eq $expected ] ||
6394                 error "'$cmd' wrong: found $nums, expected $expected"
6395 }
6396 run_test 56n "check lfs find -type l"
6397
6398 test_56o() {
6399         local dir=$DIR/$tdir
6400
6401         setup_56 $dir $NUMFILES $NUMDIRS
6402         utime $dir/file1 > /dev/null || error "utime (1)"
6403         utime $dir/file2 > /dev/null || error "utime (2)"
6404         utime $dir/dir1 > /dev/null || error "utime (3)"
6405         utime $dir/dir2 > /dev/null || error "utime (4)"
6406         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6407         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6408
6409         local expected=4
6410         local nums=$($LFS find -mtime +0 $dir | wc -l)
6411
6412         [ $nums -eq $expected ] ||
6413                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6414
6415         expected=12
6416         cmd="$LFS find -mtime 0 $dir"
6417         nums=$($cmd | wc -l)
6418         [ $nums -eq $expected ] ||
6419                 error "'$cmd' wrong: found $nums, expected $expected"
6420 }
6421 run_test 56o "check lfs find -mtime for old files"
6422
6423 test_56ob() {
6424         local dir=$DIR/$tdir
6425         local expected=1
6426         local count=0
6427
6428         # just to make sure there is something that won't be found
6429         test_mkdir $dir
6430         touch $dir/$tfile.now
6431
6432         for age in year week day hour min; do
6433                 count=$((count + 1))
6434
6435                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6436                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6437                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6438
6439                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6440                 local nums=$($cmd | wc -l)
6441                 [ $nums -eq $expected ] ||
6442                         error "'$cmd' wrong: found $nums, expected $expected"
6443
6444                 cmd="$LFS find $dir -atime $count${age:0:1}"
6445                 nums=$($cmd | wc -l)
6446                 [ $nums -eq $expected ] ||
6447                         error "'$cmd' wrong: found $nums, expected $expected"
6448         done
6449
6450         sleep 2
6451         cmd="$LFS find $dir -ctime +1s -type f"
6452         nums=$($cmd | wc -l)
6453         (( $nums == $count * 2 + 1)) ||
6454                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6455 }
6456 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6457
6458 test_newerXY_base() {
6459         local x=$1
6460         local y=$2
6461         local dir=$DIR/$tdir
6462         local ref
6463         local negref
6464
6465         if [ $y == "t" ]; then
6466                 if [ $x == "b" ]; then
6467                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6468                 else
6469                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6470                 fi
6471         else
6472                 ref=$DIR/$tfile.newer.$x$y
6473                 touch $ref || error "touch $ref failed"
6474         fi
6475
6476         echo "before = $ref"
6477         sleep 2
6478         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6479         sleep 2
6480         if [ $y == "t" ]; then
6481                 if [ $x == "b" ]; then
6482                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6483                 else
6484                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6485                 fi
6486         else
6487                 negref=$DIR/$tfile.negnewer.$x$y
6488                 touch $negref || error "touch $negref failed"
6489         fi
6490
6491         echo "after = $negref"
6492         local cmd="$LFS find $dir -newer$x$y $ref"
6493         local nums=$(eval $cmd | wc -l)
6494         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6495
6496         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6497                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6498
6499         cmd="$LFS find $dir ! -newer$x$y $negref"
6500         nums=$(eval $cmd | wc -l)
6501         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6502                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6503
6504         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6505         nums=$(eval $cmd | wc -l)
6506         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6507                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6508
6509         rm -rf $DIR/*
6510 }
6511
6512 test_56oc() {
6513         test_newerXY_base "a" "a"
6514         test_newerXY_base "a" "m"
6515         test_newerXY_base "a" "c"
6516         test_newerXY_base "m" "a"
6517         test_newerXY_base "m" "m"
6518         test_newerXY_base "m" "c"
6519         test_newerXY_base "c" "a"
6520         test_newerXY_base "c" "m"
6521         test_newerXY_base "c" "c"
6522
6523         [[ -n "$sles_version" ]] &&
6524                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6525
6526         test_newerXY_base "a" "t"
6527         test_newerXY_base "m" "t"
6528         test_newerXY_base "c" "t"
6529
6530         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6531            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6532                 ! btime_supported && echo "btime unsupported" && return 0
6533
6534         test_newerXY_base "b" "b"
6535         test_newerXY_base "b" "t"
6536 }
6537 run_test 56oc "check lfs find -newerXY work"
6538
6539 btime_supported() {
6540         local dir=$DIR/$tdir
6541         local rc
6542
6543         mkdir -p $dir
6544         touch $dir/$tfile
6545         $LFS find $dir -btime -1d -type f
6546         rc=$?
6547         rm -rf $dir
6548         return $rc
6549 }
6550
6551 test_56od() {
6552         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6553                 ! btime_supported && skip "btime unsupported on MDS"
6554
6555         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6556                 ! btime_supported && skip "btime unsupported on clients"
6557
6558         local dir=$DIR/$tdir
6559         local ref=$DIR/$tfile.ref
6560         local negref=$DIR/$tfile.negref
6561
6562         mkdir $dir || error "mkdir $dir failed"
6563         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6564         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6565         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6566         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6567         touch $ref || error "touch $ref failed"
6568         # sleep 3 seconds at least
6569         sleep 3
6570
6571         local before=$(do_facet mds1 date +%s)
6572         local skew=$(($(date +%s) - before + 1))
6573
6574         if (( skew < 0 && skew > -5 )); then
6575                 sleep $((0 - skew + 1))
6576                 skew=0
6577         fi
6578
6579         # Set the dir stripe params to limit files all on MDT0,
6580         # otherwise we need to calc the max clock skew between
6581         # the client and MDTs.
6582         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6583         sleep 2
6584         touch $negref || error "touch $negref failed"
6585
6586         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6587         local nums=$($cmd | wc -l)
6588         local expected=$(((NUMFILES + 1) * NUMDIRS))
6589
6590         [ $nums -eq $expected ] ||
6591                 error "'$cmd' wrong: found $nums, expected $expected"
6592
6593         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6594         nums=$($cmd | wc -l)
6595         expected=$((NUMFILES + 1))
6596         [ $nums -eq $expected ] ||
6597                 error "'$cmd' wrong: found $nums, expected $expected"
6598
6599         [ $skew -lt 0 ] && return
6600
6601         local after=$(do_facet mds1 date +%s)
6602         local age=$((after - before + 1 + skew))
6603
6604         cmd="$LFS find $dir -btime -${age}s -type f"
6605         nums=$($cmd | wc -l)
6606         expected=$(((NUMFILES + 1) * NUMDIRS))
6607
6608         echo "Clock skew between client and server: $skew, age:$age"
6609         [ $nums -eq $expected ] ||
6610                 error "'$cmd' wrong: found $nums, expected $expected"
6611
6612         expected=$(($NUMDIRS + 1))
6613         cmd="$LFS find $dir -btime -${age}s -type d"
6614         nums=$($cmd | wc -l)
6615         [ $nums -eq $expected ] ||
6616                 error "'$cmd' wrong: found $nums, expected $expected"
6617         rm -f $ref $negref || error "Failed to remove $ref $negref"
6618 }
6619 run_test 56od "check lfs find -btime with units"
6620
6621 test_56p() {
6622         [ $RUNAS_ID -eq $UID ] &&
6623                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6624
6625         local dir=$DIR/$tdir
6626
6627         setup_56 $dir $NUMFILES $NUMDIRS
6628         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6629
6630         local expected=$NUMFILES
6631         local cmd="$LFS find -uid $RUNAS_ID $dir"
6632         local nums=$($cmd | wc -l)
6633
6634         [ $nums -eq $expected ] ||
6635                 error "'$cmd' wrong: found $nums, expected $expected"
6636
6637         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6638         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6639         nums=$($cmd | wc -l)
6640         [ $nums -eq $expected ] ||
6641                 error "'$cmd' wrong: found $nums, expected $expected"
6642 }
6643 run_test 56p "check lfs find -uid and ! -uid"
6644
6645 test_56q() {
6646         [ $RUNAS_ID -eq $UID ] &&
6647                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6648
6649         local dir=$DIR/$tdir
6650
6651         setup_56 $dir $NUMFILES $NUMDIRS
6652         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6653
6654         local expected=$NUMFILES
6655         local cmd="$LFS find -gid $RUNAS_GID $dir"
6656         local nums=$($cmd | wc -l)
6657
6658         [ $nums -eq $expected ] ||
6659                 error "'$cmd' wrong: found $nums, expected $expected"
6660
6661         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6662         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6663         nums=$($cmd | wc -l)
6664         [ $nums -eq $expected ] ||
6665                 error "'$cmd' wrong: found $nums, expected $expected"
6666 }
6667 run_test 56q "check lfs find -gid and ! -gid"
6668
6669 test_56r() {
6670         local dir=$DIR/$tdir
6671
6672         setup_56 $dir $NUMFILES $NUMDIRS
6673
6674         local expected=12
6675         local cmd="$LFS find -size 0 -type f -lazy $dir"
6676         local nums=$($cmd | wc -l)
6677
6678         [ $nums -eq $expected ] ||
6679                 error "'$cmd' wrong: found $nums, expected $expected"
6680         cmd="$LFS find -size 0 -type f $dir"
6681         nums=$($cmd | wc -l)
6682         [ $nums -eq $expected ] ||
6683                 error "'$cmd' wrong: found $nums, expected $expected"
6684
6685         expected=0
6686         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6687         nums=$($cmd | wc -l)
6688         [ $nums -eq $expected ] ||
6689                 error "'$cmd' wrong: found $nums, expected $expected"
6690         cmd="$LFS find ! -size 0 -type f $dir"
6691         nums=$($cmd | wc -l)
6692         [ $nums -eq $expected ] ||
6693                 error "'$cmd' wrong: found $nums, expected $expected"
6694
6695         echo "test" > $dir/$tfile
6696         echo "test2" > $dir/$tfile.2 && sync
6697         expected=1
6698         cmd="$LFS find -size 5 -type f -lazy $dir"
6699         nums=$($cmd | wc -l)
6700         [ $nums -eq $expected ] ||
6701                 error "'$cmd' wrong: found $nums, expected $expected"
6702         cmd="$LFS find -size 5 -type f $dir"
6703         nums=$($cmd | wc -l)
6704         [ $nums -eq $expected ] ||
6705                 error "'$cmd' wrong: found $nums, expected $expected"
6706
6707         expected=1
6708         cmd="$LFS find -size +5 -type f -lazy $dir"
6709         nums=$($cmd | wc -l)
6710         [ $nums -eq $expected ] ||
6711                 error "'$cmd' wrong: found $nums, expected $expected"
6712         cmd="$LFS find -size +5 -type f $dir"
6713         nums=$($cmd | wc -l)
6714         [ $nums -eq $expected ] ||
6715                 error "'$cmd' wrong: found $nums, expected $expected"
6716
6717         expected=2
6718         cmd="$LFS find -size +0 -type f -lazy $dir"
6719         nums=$($cmd | wc -l)
6720         [ $nums -eq $expected ] ||
6721                 error "'$cmd' wrong: found $nums, expected $expected"
6722         cmd="$LFS find -size +0 -type f $dir"
6723         nums=$($cmd | wc -l)
6724         [ $nums -eq $expected ] ||
6725                 error "'$cmd' wrong: found $nums, expected $expected"
6726
6727         expected=2
6728         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6729         nums=$($cmd | wc -l)
6730         [ $nums -eq $expected ] ||
6731                 error "'$cmd' wrong: found $nums, expected $expected"
6732         cmd="$LFS find ! -size -5 -type f $dir"
6733         nums=$($cmd | wc -l)
6734         [ $nums -eq $expected ] ||
6735                 error "'$cmd' wrong: found $nums, expected $expected"
6736
6737         expected=12
6738         cmd="$LFS find -size -5 -type f -lazy $dir"
6739         nums=$($cmd | wc -l)
6740         [ $nums -eq $expected ] ||
6741                 error "'$cmd' wrong: found $nums, expected $expected"
6742         cmd="$LFS find -size -5 -type f $dir"
6743         nums=$($cmd | wc -l)
6744         [ $nums -eq $expected ] ||
6745                 error "'$cmd' wrong: found $nums, expected $expected"
6746 }
6747 run_test 56r "check lfs find -size works"
6748
6749 test_56ra_sub() {
6750         local expected=$1
6751         local glimpses=$2
6752         local cmd="$3"
6753
6754         cancel_lru_locks $OSC
6755
6756         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6757         local nums=$($cmd | wc -l)
6758
6759         [ $nums -eq $expected ] ||
6760                 error "'$cmd' wrong: found $nums, expected $expected"
6761
6762         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6763
6764         if (( rpcs_before + glimpses != rpcs_after )); then
6765                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6766                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6767
6768                 if [[ $glimpses == 0 ]]; then
6769                         error "'$cmd' should not send glimpse RPCs to OST"
6770                 else
6771                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6772                 fi
6773         fi
6774 }
6775
6776 test_56ra() {
6777         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6778                 skip "MDS < 2.12.58 doesn't return LSOM data"
6779         local dir=$DIR/$tdir
6780         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6781
6782         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6783
6784         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6785         $LCTL set_param -n llite.*.statahead_agl=0
6786         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6787
6788         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6789         # open and close all files to ensure LSOM is updated
6790         cancel_lru_locks $OSC
6791         find $dir -type f | xargs cat > /dev/null
6792
6793         #   expect_found  glimpse_rpcs  command_to_run
6794         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6795         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6796         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6797         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6798
6799         echo "test" > $dir/$tfile
6800         echo "test2" > $dir/$tfile.2 && sync
6801         cancel_lru_locks $OSC
6802         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6803
6804         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6805         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6806         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6807         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6808
6809         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6810         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6811         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6812         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6813         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6814         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6815 }
6816 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6817
6818 test_56rb() {
6819         local dir=$DIR/$tdir
6820         local tmp=$TMP/$tfile.log
6821         local mdt_idx;
6822
6823         test_mkdir -p $dir || error "failed to mkdir $dir"
6824         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6825                 error "failed to setstripe $dir/$tfile"
6826         mdt_idx=$($LFS getdirstripe -i $dir)
6827         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6828
6829         stack_trap "rm -f $tmp" EXIT
6830         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6831         ! grep -q obd_uuid $tmp ||
6832                 error "failed to find --size +100K --ost 0 $dir"
6833         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6834         ! grep -q obd_uuid $tmp ||
6835                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6836 }
6837 run_test 56rb "check lfs find --size --ost/--mdt works"
6838
6839 test_56rc() {
6840         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6841         local dir=$DIR/$tdir
6842         local found
6843
6844         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6845         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6846         (( $MDSCOUNT > 2 )) &&
6847                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6848         mkdir $dir/$tdir-{1..10}
6849         touch $dir/$tfile-{1..10}
6850
6851         found=$($LFS find $dir --mdt-count 2 | wc -l)
6852         expect=11
6853         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6854
6855         found=$($LFS find $dir -T +1 | wc -l)
6856         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6857         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6858
6859         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6860         expect=11
6861         (( $found == $expect )) || error "found $found all_char, expect $expect"
6862
6863         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6864         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6865         (( $found == $expect )) || error "found $found all_char, expect $expect"
6866 }
6867 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6868
6869 test_56s() { # LU-611 #LU-9369
6870         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6871
6872         local dir=$DIR/$tdir
6873         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6874
6875         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6876         for i in $(seq $NUMDIRS); do
6877                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6878         done
6879
6880         local expected=$NUMDIRS
6881         local cmd="$LFS find -c $OSTCOUNT $dir"
6882         local nums=$($cmd | wc -l)
6883
6884         [ $nums -eq $expected ] || {
6885                 $LFS getstripe -R $dir
6886                 error "'$cmd' wrong: found $nums, expected $expected"
6887         }
6888
6889         expected=$((NUMDIRS + onestripe))
6890         cmd="$LFS find -stripe-count +0 -type f $dir"
6891         nums=$($cmd | wc -l)
6892         [ $nums -eq $expected ] || {
6893                 $LFS getstripe -R $dir
6894                 error "'$cmd' wrong: found $nums, expected $expected"
6895         }
6896
6897         expected=$onestripe
6898         cmd="$LFS find -stripe-count 1 -type f $dir"
6899         nums=$($cmd | wc -l)
6900         [ $nums -eq $expected ] || {
6901                 $LFS getstripe -R $dir
6902                 error "'$cmd' wrong: found $nums, expected $expected"
6903         }
6904
6905         cmd="$LFS find -stripe-count -2 -type f $dir"
6906         nums=$($cmd | wc -l)
6907         [ $nums -eq $expected ] || {
6908                 $LFS getstripe -R $dir
6909                 error "'$cmd' wrong: found $nums, expected $expected"
6910         }
6911
6912         expected=0
6913         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6914         nums=$($cmd | wc -l)
6915         [ $nums -eq $expected ] || {
6916                 $LFS getstripe -R $dir
6917                 error "'$cmd' wrong: found $nums, expected $expected"
6918         }
6919 }
6920 run_test 56s "check lfs find -stripe-count works"
6921
6922 test_56t() { # LU-611 #LU-9369
6923         local dir=$DIR/$tdir
6924
6925         setup_56 $dir 0 $NUMDIRS
6926         for i in $(seq $NUMDIRS); do
6927                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6928         done
6929
6930         local expected=$NUMDIRS
6931         local cmd="$LFS find -S 8M $dir"
6932         local nums=$($cmd | wc -l)
6933
6934         [ $nums -eq $expected ] || {
6935                 $LFS getstripe -R $dir
6936                 error "'$cmd' wrong: found $nums, expected $expected"
6937         }
6938         rm -rf $dir
6939
6940         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6941
6942         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6943
6944         expected=$(((NUMDIRS + 1) * NUMFILES))
6945         cmd="$LFS find -stripe-size 512k -type f $dir"
6946         nums=$($cmd | wc -l)
6947         [ $nums -eq $expected ] ||
6948                 error "'$cmd' wrong: found $nums, expected $expected"
6949
6950         cmd="$LFS find -stripe-size +320k -type f $dir"
6951         nums=$($cmd | wc -l)
6952         [ $nums -eq $expected ] ||
6953                 error "'$cmd' wrong: found $nums, expected $expected"
6954
6955         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6956         cmd="$LFS find -stripe-size +200k -type f $dir"
6957         nums=$($cmd | wc -l)
6958         [ $nums -eq $expected ] ||
6959                 error "'$cmd' wrong: found $nums, expected $expected"
6960
6961         cmd="$LFS find -stripe-size -640k -type f $dir"
6962         nums=$($cmd | wc -l)
6963         [ $nums -eq $expected ] ||
6964                 error "'$cmd' wrong: found $nums, expected $expected"
6965
6966         expected=4
6967         cmd="$LFS find -stripe-size 256k -type f $dir"
6968         nums=$($cmd | wc -l)
6969         [ $nums -eq $expected ] ||
6970                 error "'$cmd' wrong: found $nums, expected $expected"
6971
6972         cmd="$LFS find -stripe-size -320k -type f $dir"
6973         nums=$($cmd | wc -l)
6974         [ $nums -eq $expected ] ||
6975                 error "'$cmd' wrong: found $nums, expected $expected"
6976
6977         expected=0
6978         cmd="$LFS find -stripe-size 1024k -type f $dir"
6979         nums=$($cmd | wc -l)
6980         [ $nums -eq $expected ] ||
6981                 error "'$cmd' wrong: found $nums, expected $expected"
6982 }
6983 run_test 56t "check lfs find -stripe-size works"
6984
6985 test_56u() { # LU-611
6986         local dir=$DIR/$tdir
6987
6988         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6989
6990         if [[ $OSTCOUNT -gt 1 ]]; then
6991                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6992                 onestripe=4
6993         else
6994                 onestripe=0
6995         fi
6996
6997         local expected=$(((NUMDIRS + 1) * NUMFILES))
6998         local cmd="$LFS find -stripe-index 0 -type f $dir"
6999         local nums=$($cmd | wc -l)
7000
7001         [ $nums -eq $expected ] ||
7002                 error "'$cmd' wrong: found $nums, expected $expected"
7003
7004         expected=$onestripe
7005         cmd="$LFS find -stripe-index 1 -type f $dir"
7006         nums=$($cmd | wc -l)
7007         [ $nums -eq $expected ] ||
7008                 error "'$cmd' wrong: found $nums, expected $expected"
7009
7010         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7011         nums=$($cmd | wc -l)
7012         [ $nums -eq $expected ] ||
7013                 error "'$cmd' wrong: found $nums, expected $expected"
7014
7015         expected=0
7016         # This should produce an error and not return any files
7017         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7018         nums=$($cmd 2>/dev/null | wc -l)
7019         [ $nums -eq $expected ] ||
7020                 error "'$cmd' wrong: found $nums, expected $expected"
7021
7022         if [[ $OSTCOUNT -gt 1 ]]; then
7023                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7024                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7025                 nums=$($cmd | wc -l)
7026                 [ $nums -eq $expected ] ||
7027                         error "'$cmd' wrong: found $nums, expected $expected"
7028         fi
7029 }
7030 run_test 56u "check lfs find -stripe-index works"
7031
7032 test_56v() {
7033         local mdt_idx=0
7034         local dir=$DIR/$tdir
7035
7036         setup_56 $dir $NUMFILES $NUMDIRS
7037
7038         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7039         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7040
7041         for file in $($LFS find -m $UUID $dir); do
7042                 file_midx=$($LFS getstripe -m $file)
7043                 [ $file_midx -eq $mdt_idx ] ||
7044                         error "lfs find -m $UUID != getstripe -m $file_midx"
7045         done
7046 }
7047 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7048
7049 test_56w() {
7050         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7052
7053         local dir=$DIR/$tdir
7054
7055         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7056
7057         local stripe_size=$($LFS getstripe -S -d $dir) ||
7058                 error "$LFS getstripe -S -d $dir failed"
7059         stripe_size=${stripe_size%% *}
7060
7061         local file_size=$((stripe_size * OSTCOUNT))
7062         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7063         local required_space=$((file_num * file_size))
7064         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7065                            head -n1)
7066         [[ $free_space -le $((required_space / 1024)) ]] &&
7067                 skip_env "need $required_space, have $free_space kbytes"
7068
7069         local dd_bs=65536
7070         local dd_count=$((file_size / dd_bs))
7071
7072         # write data into the files
7073         local i
7074         local j
7075         local file
7076
7077         for i in $(seq $NUMFILES); do
7078                 file=$dir/file$i
7079                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7080                         error "write data into $file failed"
7081         done
7082         for i in $(seq $NUMDIRS); do
7083                 for j in $(seq $NUMFILES); do
7084                         file=$dir/dir$i/file$j
7085                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7086                                 error "write data into $file failed"
7087                 done
7088         done
7089
7090         # $LFS_MIGRATE will fail if hard link migration is unsupported
7091         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7092                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7093                         error "creating links to $dir/dir1/file1 failed"
7094         fi
7095
7096         local expected=-1
7097
7098         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7099
7100         # lfs_migrate file
7101         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7102
7103         echo "$cmd"
7104         eval $cmd || error "$cmd failed"
7105
7106         check_stripe_count $dir/file1 $expected
7107
7108         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7109         then
7110                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7111                 # OST 1 if it is on OST 0. This file is small enough to
7112                 # be on only one stripe.
7113                 file=$dir/migr_1_ost
7114                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7115                         error "write data into $file failed"
7116                 local obdidx=$($LFS getstripe -i $file)
7117                 local oldmd5=$(md5sum $file)
7118                 local newobdidx=0
7119
7120                 [[ $obdidx -eq 0 ]] && newobdidx=1
7121                 cmd="$LFS migrate -i $newobdidx $file"
7122                 echo $cmd
7123                 eval $cmd || error "$cmd failed"
7124
7125                 local realobdix=$($LFS getstripe -i $file)
7126                 local newmd5=$(md5sum $file)
7127
7128                 [[ $newobdidx -ne $realobdix ]] &&
7129                         error "new OST is different (was=$obdidx, "\
7130                               "wanted=$newobdidx, got=$realobdix)"
7131                 [[ "$oldmd5" != "$newmd5" ]] &&
7132                         error "md5sum differ: $oldmd5, $newmd5"
7133         fi
7134
7135         # lfs_migrate dir
7136         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7137         echo "$cmd"
7138         eval $cmd || error "$cmd failed"
7139
7140         for j in $(seq $NUMFILES); do
7141                 check_stripe_count $dir/dir1/file$j $expected
7142         done
7143
7144         # lfs_migrate works with lfs find
7145         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7146              $LFS_MIGRATE -y -c $expected"
7147         echo "$cmd"
7148         eval $cmd || error "$cmd failed"
7149
7150         for i in $(seq 2 $NUMFILES); do
7151                 check_stripe_count $dir/file$i $expected
7152         done
7153         for i in $(seq 2 $NUMDIRS); do
7154                 for j in $(seq $NUMFILES); do
7155                 check_stripe_count $dir/dir$i/file$j $expected
7156                 done
7157         done
7158 }
7159 run_test 56w "check lfs_migrate -c stripe_count works"
7160
7161 test_56wb() {
7162         local file1=$DIR/$tdir/file1
7163         local create_pool=false
7164         local initial_pool=$($LFS getstripe -p $DIR)
7165         local pool_list=()
7166         local pool=""
7167
7168         echo -n "Creating test dir..."
7169         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7170         echo "done."
7171
7172         echo -n "Creating test file..."
7173         touch $file1 || error "cannot create file"
7174         echo "done."
7175
7176         echo -n "Detecting existing pools..."
7177         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7178
7179         if [ ${#pool_list[@]} -gt 0 ]; then
7180                 echo "${pool_list[@]}"
7181                 for thispool in "${pool_list[@]}"; do
7182                         if [[ -z "$initial_pool" ||
7183                               "$initial_pool" != "$thispool" ]]; then
7184                                 pool="$thispool"
7185                                 echo "Using existing pool '$pool'"
7186                                 break
7187                         fi
7188                 done
7189         else
7190                 echo "none detected."
7191         fi
7192         if [ -z "$pool" ]; then
7193                 pool=${POOL:-testpool}
7194                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7195                 echo -n "Creating pool '$pool'..."
7196                 create_pool=true
7197                 pool_add $pool &> /dev/null ||
7198                         error "pool_add failed"
7199                 echo "done."
7200
7201                 echo -n "Adding target to pool..."
7202                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7203                         error "pool_add_targets failed"
7204                 echo "done."
7205         fi
7206
7207         echo -n "Setting pool using -p option..."
7208         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7209                 error "migrate failed rc = $?"
7210         echo "done."
7211
7212         echo -n "Verifying test file is in pool after migrating..."
7213         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7214                 error "file was not migrated to pool $pool"
7215         echo "done."
7216
7217         echo -n "Removing test file from pool '$pool'..."
7218         # "lfs migrate $file" won't remove the file from the pool
7219         # until some striping information is changed.
7220         $LFS migrate -c 1 $file1 &> /dev/null ||
7221                 error "cannot remove from pool"
7222         [ "$($LFS getstripe -p $file1)" ] &&
7223                 error "pool still set"
7224         echo "done."
7225
7226         echo -n "Setting pool using --pool option..."
7227         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7228                 error "migrate failed rc = $?"
7229         echo "done."
7230
7231         # Clean up
7232         rm -f $file1
7233         if $create_pool; then
7234                 destroy_test_pools 2> /dev/null ||
7235                         error "destroy test pools failed"
7236         fi
7237 }
7238 run_test 56wb "check lfs_migrate pool support"
7239
7240 test_56wc() {
7241         local file1="$DIR/$tdir/file1"
7242         local parent_ssize
7243         local parent_scount
7244         local cur_ssize
7245         local cur_scount
7246         local orig_ssize
7247
7248         echo -n "Creating test dir..."
7249         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7250         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7251                 error "cannot set stripe by '-S 1M -c 1'"
7252         echo "done"
7253
7254         echo -n "Setting initial stripe for test file..."
7255         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7256                 error "cannot set stripe"
7257         cur_ssize=$($LFS getstripe -S "$file1")
7258         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7259         echo "done."
7260
7261         # File currently set to -S 512K -c 1
7262
7263         # Ensure -c and -S options are rejected when -R is set
7264         echo -n "Verifying incompatible options are detected..."
7265         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7266                 error "incompatible -c and -R options not detected"
7267         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7268                 error "incompatible -S and -R options not detected"
7269         echo "done."
7270
7271         # Ensure unrecognized options are passed through to 'lfs migrate'
7272         echo -n "Verifying -S option is passed through to lfs migrate..."
7273         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7274                 error "migration failed"
7275         cur_ssize=$($LFS getstripe -S "$file1")
7276         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7277         echo "done."
7278
7279         # File currently set to -S 1M -c 1
7280
7281         # Ensure long options are supported
7282         echo -n "Verifying long options supported..."
7283         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7284                 error "long option without argument not supported"
7285         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7286                 error "long option with argument not supported"
7287         cur_ssize=$($LFS getstripe -S "$file1")
7288         [ $cur_ssize -eq 524288 ] ||
7289                 error "migrate --stripe-size $cur_ssize != 524288"
7290         echo "done."
7291
7292         # File currently set to -S 512K -c 1
7293
7294         if [ "$OSTCOUNT" -gt 1 ]; then
7295                 echo -n "Verifying explicit stripe count can be set..."
7296                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7297                         error "migrate failed"
7298                 cur_scount=$($LFS getstripe -c "$file1")
7299                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7300                 echo "done."
7301         fi
7302
7303         # File currently set to -S 512K -c 1 or -S 512K -c 2
7304
7305         # Ensure parent striping is used if -R is set, and no stripe
7306         # count or size is specified
7307         echo -n "Setting stripe for parent directory..."
7308         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7309                 error "cannot set stripe '-S 2M -c 1'"
7310         echo "done."
7311
7312         echo -n "Verifying restripe option uses parent stripe settings..."
7313         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7314         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7315         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7316                 error "migrate failed"
7317         cur_ssize=$($LFS getstripe -S "$file1")
7318         [ $cur_ssize -eq $parent_ssize ] ||
7319                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7320         cur_scount=$($LFS getstripe -c "$file1")
7321         [ $cur_scount -eq $parent_scount ] ||
7322                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7323         echo "done."
7324
7325         # File currently set to -S 1M -c 1
7326
7327         # Ensure striping is preserved if -R is not set, and no stripe
7328         # count or size is specified
7329         echo -n "Verifying striping size preserved when not specified..."
7330         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7331         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7332                 error "cannot set stripe on parent directory"
7333         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7334                 error "migrate failed"
7335         cur_ssize=$($LFS getstripe -S "$file1")
7336         [ $cur_ssize -eq $orig_ssize ] ||
7337                 error "migrate by default $cur_ssize != $orig_ssize"
7338         echo "done."
7339
7340         # Ensure file name properly detected when final option has no argument
7341         echo -n "Verifying file name properly detected..."
7342         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7343                 error "file name interpreted as option argument"
7344         echo "done."
7345
7346         # Clean up
7347         rm -f "$file1"
7348 }
7349 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7350
7351 test_56wd() {
7352         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7353
7354         local file1=$DIR/$tdir/file1
7355
7356         echo -n "Creating test dir..."
7357         test_mkdir $DIR/$tdir || error "cannot create dir"
7358         echo "done."
7359
7360         echo -n "Creating test file..."
7361         touch $file1
7362         echo "done."
7363
7364         # Ensure 'lfs migrate' will fail by using a non-existent option,
7365         # and make sure rsync is not called to recover
7366         echo -n "Make sure --no-rsync option works..."
7367         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7368                 grep -q 'refusing to fall back to rsync' ||
7369                 error "rsync was called with --no-rsync set"
7370         echo "done."
7371
7372         # Ensure rsync is called without trying 'lfs migrate' first
7373         echo -n "Make sure --rsync option works..."
7374         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7375                 grep -q 'falling back to rsync' &&
7376                 error "lfs migrate was called with --rsync set"
7377         echo "done."
7378
7379         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7380         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7381                 grep -q 'at the same time' ||
7382                 error "--rsync and --no-rsync accepted concurrently"
7383         echo "done."
7384
7385         # Clean up
7386         rm -f $file1
7387 }
7388 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7389
7390 test_56we() {
7391         local td=$DIR/$tdir
7392         local tf=$td/$tfile
7393
7394         test_mkdir $td || error "cannot create $td"
7395         touch $tf || error "cannot touch $tf"
7396
7397         echo -n "Make sure --non-direct|-D works..."
7398         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7399                 grep -q "lfs migrate --non-direct" ||
7400                 error "--non-direct option cannot work correctly"
7401         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7402                 grep -q "lfs migrate -D" ||
7403                 error "-D option cannot work correctly"
7404         echo "done."
7405 }
7406 run_test 56we "check lfs_migrate --non-direct|-D support"
7407
7408 test_56x() {
7409         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7410         check_swap_layouts_support
7411
7412         local dir=$DIR/$tdir
7413         local ref1=/etc/passwd
7414         local file1=$dir/file1
7415
7416         test_mkdir $dir || error "creating dir $dir"
7417         $LFS setstripe -c 2 $file1
7418         cp $ref1 $file1
7419         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7420         stripe=$($LFS getstripe -c $file1)
7421         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7422         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7423
7424         # clean up
7425         rm -f $file1
7426 }
7427 run_test 56x "lfs migration support"
7428
7429 test_56xa() {
7430         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7431         check_swap_layouts_support
7432
7433         local dir=$DIR/$tdir/$testnum
7434
7435         test_mkdir -p $dir
7436
7437         local ref1=/etc/passwd
7438         local file1=$dir/file1
7439
7440         $LFS setstripe -c 2 $file1
7441         cp $ref1 $file1
7442         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7443
7444         local stripe=$($LFS getstripe -c $file1)
7445
7446         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7447         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7448
7449         # clean up
7450         rm -f $file1
7451 }
7452 run_test 56xa "lfs migration --block support"
7453
7454 check_migrate_links() {
7455         local dir="$1"
7456         local file1="$dir/file1"
7457         local begin="$2"
7458         local count="$3"
7459         local runas="$4"
7460         local total_count=$(($begin + $count - 1))
7461         local symlink_count=10
7462         local uniq_count=10
7463
7464         if [ ! -f "$file1" ]; then
7465                 echo -n "creating initial file..."
7466                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7467                         error "cannot setstripe initial file"
7468                 echo "done"
7469
7470                 echo -n "creating symlinks..."
7471                 for s in $(seq 1 $symlink_count); do
7472                         ln -s "$file1" "$dir/slink$s" ||
7473                                 error "cannot create symlinks"
7474                 done
7475                 echo "done"
7476
7477                 echo -n "creating nonlinked files..."
7478                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7479                         error "cannot create nonlinked files"
7480                 echo "done"
7481         fi
7482
7483         # create hard links
7484         if [ ! -f "$dir/file$total_count" ]; then
7485                 echo -n "creating hard links $begin:$total_count..."
7486                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7487                         /dev/null || error "cannot create hard links"
7488                 echo "done"
7489         fi
7490
7491         echo -n "checking number of hard links listed in xattrs..."
7492         local fid=$($LFS getstripe -F "$file1")
7493         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7494
7495         echo "${#paths[*]}"
7496         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7497                         skip "hard link list has unexpected size, skipping test"
7498         fi
7499         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7500                         error "link names should exceed xattrs size"
7501         fi
7502
7503         echo -n "migrating files..."
7504         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7505         local rc=$?
7506         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7507         echo "done"
7508
7509         # make sure all links have been properly migrated
7510         echo -n "verifying files..."
7511         fid=$($LFS getstripe -F "$file1") ||
7512                 error "cannot get fid for file $file1"
7513         for i in $(seq 2 $total_count); do
7514                 local fid2=$($LFS getstripe -F $dir/file$i)
7515
7516                 [ "$fid2" == "$fid" ] ||
7517                         error "migrated hard link has mismatched FID"
7518         done
7519
7520         # make sure hard links were properly detected, and migration was
7521         # performed only once for the entire link set; nonlinked files should
7522         # also be migrated
7523         local actual=$(grep -c 'done' <<< "$migrate_out")
7524         local expected=$(($uniq_count + 1))
7525
7526         [ "$actual" -eq  "$expected" ] ||
7527                 error "hard links individually migrated ($actual != $expected)"
7528
7529         # make sure the correct number of hard links are present
7530         local hardlinks=$(stat -c '%h' "$file1")
7531
7532         [ $hardlinks -eq $total_count ] ||
7533                 error "num hard links $hardlinks != $total_count"
7534         echo "done"
7535
7536         return 0
7537 }
7538
7539 test_56xb() {
7540         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7541                 skip "Need MDS version at least 2.10.55"
7542
7543         local dir="$DIR/$tdir"
7544
7545         test_mkdir "$dir" || error "cannot create dir $dir"
7546
7547         echo "testing lfs migrate mode when all links fit within xattrs"
7548         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7549
7550         echo "testing rsync mode when all links fit within xattrs"
7551         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7552
7553         echo "testing lfs migrate mode when all links do not fit within xattrs"
7554         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7555
7556         echo "testing rsync mode when all links do not fit within xattrs"
7557         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7558
7559         chown -R $RUNAS_ID $dir
7560         echo "testing non-root lfs migrate mode when not all links are in xattr"
7561         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7562
7563         # clean up
7564         rm -rf $dir
7565 }
7566 run_test 56xb "lfs migration hard link support"
7567
7568 test_56xc() {
7569         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7570
7571         local dir="$DIR/$tdir"
7572
7573         test_mkdir "$dir" || error "cannot create dir $dir"
7574
7575         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7576         echo -n "Setting initial stripe for 20MB test file..."
7577         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7578                 error "cannot setstripe 20MB file"
7579         echo "done"
7580         echo -n "Sizing 20MB test file..."
7581         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7582         echo "done"
7583         echo -n "Verifying small file autostripe count is 1..."
7584         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7585                 error "cannot migrate 20MB file"
7586         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7587                 error "cannot get stripe for $dir/20mb"
7588         [ $stripe_count -eq 1 ] ||
7589                 error "unexpected stripe count $stripe_count for 20MB file"
7590         rm -f "$dir/20mb"
7591         echo "done"
7592
7593         # Test 2: File is small enough to fit within the available space on
7594         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7595         # have at least an additional 1KB for each desired stripe for test 3
7596         echo -n "Setting stripe for 1GB test file..."
7597         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7598         echo "done"
7599         echo -n "Sizing 1GB test file..."
7600         # File size is 1GB + 3KB
7601         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7602         echo "done"
7603
7604         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7605         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7606         if (( avail > 524288 * OSTCOUNT )); then
7607                 echo -n "Migrating 1GB file..."
7608                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7609                         error "cannot migrate 1GB file"
7610                 echo "done"
7611                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7612                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7613                         error "cannot getstripe for 1GB file"
7614                 [ $stripe_count -eq 2 ] ||
7615                         error "unexpected stripe count $stripe_count != 2"
7616                 echo "done"
7617         fi
7618
7619         # Test 3: File is too large to fit within the available space on
7620         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7621         if [ $OSTCOUNT -ge 3 ]; then
7622                 # The required available space is calculated as
7623                 # file size (1GB + 3KB) / OST count (3).
7624                 local kb_per_ost=349526
7625
7626                 echo -n "Migrating 1GB file with limit..."
7627                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7628                         error "cannot migrate 1GB file with limit"
7629                 echo "done"
7630
7631                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7632                 echo -n "Verifying 1GB autostripe count with limited space..."
7633                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7634                         error "unexpected stripe count $stripe_count (min 3)"
7635                 echo "done"
7636         fi
7637
7638         # clean up
7639         rm -rf $dir
7640 }
7641 run_test 56xc "lfs migration autostripe"
7642
7643 test_56xd() {
7644         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7645
7646         local dir=$DIR/$tdir
7647         local f_mgrt=$dir/$tfile.mgrt
7648         local f_yaml=$dir/$tfile.yaml
7649         local f_copy=$dir/$tfile.copy
7650         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7651         local layout_copy="-c 2 -S 2M -i 1"
7652         local yamlfile=$dir/yamlfile
7653         local layout_before;
7654         local layout_after;
7655
7656         test_mkdir "$dir" || error "cannot create dir $dir"
7657         $LFS setstripe $layout_yaml $f_yaml ||
7658                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7659         $LFS getstripe --yaml $f_yaml > $yamlfile
7660         $LFS setstripe $layout_copy $f_copy ||
7661                 error "cannot setstripe $f_copy with layout $layout_copy"
7662         touch $f_mgrt
7663         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7664
7665         # 1. test option --yaml
7666         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7667                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7668         layout_before=$(get_layout_param $f_yaml)
7669         layout_after=$(get_layout_param $f_mgrt)
7670         [ "$layout_after" == "$layout_before" ] ||
7671                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7672
7673         # 2. test option --copy
7674         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7675                 error "cannot migrate $f_mgrt with --copy $f_copy"
7676         layout_before=$(get_layout_param $f_copy)
7677         layout_after=$(get_layout_param $f_mgrt)
7678         [ "$layout_after" == "$layout_before" ] ||
7679                 error "lfs_migrate --copy: $layout_after != $layout_before"
7680 }
7681 run_test 56xd "check lfs_migrate --yaml and --copy support"
7682
7683 test_56xe() {
7684         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7685
7686         local dir=$DIR/$tdir
7687         local f_comp=$dir/$tfile
7688         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7689         local layout_before=""
7690         local layout_after=""
7691
7692         test_mkdir "$dir" || error "cannot create dir $dir"
7693         $LFS setstripe $layout $f_comp ||
7694                 error "cannot setstripe $f_comp with layout $layout"
7695         layout_before=$(get_layout_param $f_comp)
7696         dd if=/dev/zero of=$f_comp bs=1M count=4
7697
7698         # 1. migrate a comp layout file by lfs_migrate
7699         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7700         layout_after=$(get_layout_param $f_comp)
7701         [ "$layout_before" == "$layout_after" ] ||
7702                 error "lfs_migrate: $layout_before != $layout_after"
7703
7704         # 2. migrate a comp layout file by lfs migrate
7705         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7706         layout_after=$(get_layout_param $f_comp)
7707         [ "$layout_before" == "$layout_after" ] ||
7708                 error "lfs migrate: $layout_before != $layout_after"
7709 }
7710 run_test 56xe "migrate a composite layout file"
7711
7712 test_56xf() {
7713         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7714
7715         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7716                 skip "Need server version at least 2.13.53"
7717
7718         local dir=$DIR/$tdir
7719         local f_comp=$dir/$tfile
7720         local layout="-E 1M -c1 -E -1 -c2"
7721         local fid_before=""
7722         local fid_after=""
7723
7724         test_mkdir "$dir" || error "cannot create dir $dir"
7725         $LFS setstripe $layout $f_comp ||
7726                 error "cannot setstripe $f_comp with layout $layout"
7727         fid_before=$($LFS getstripe --fid $f_comp)
7728         dd if=/dev/zero of=$f_comp bs=1M count=4
7729
7730         # 1. migrate a comp layout file to a comp layout
7731         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7732         fid_after=$($LFS getstripe --fid $f_comp)
7733         [ "$fid_before" == "$fid_after" ] ||
7734                 error "comp-to-comp migrate: $fid_before != $fid_after"
7735
7736         # 2. migrate a comp layout file to a plain layout
7737         $LFS migrate -c2 $f_comp ||
7738                 error "cannot migrate $f_comp by lfs migrate"
7739         fid_after=$($LFS getstripe --fid $f_comp)
7740         [ "$fid_before" == "$fid_after" ] ||
7741                 error "comp-to-plain migrate: $fid_before != $fid_after"
7742
7743         # 3. migrate a plain layout file to a comp layout
7744         $LFS migrate $layout $f_comp ||
7745                 error "cannot migrate $f_comp by lfs migrate"
7746         fid_after=$($LFS getstripe --fid $f_comp)
7747         [ "$fid_before" == "$fid_after" ] ||
7748                 error "plain-to-comp migrate: $fid_before != $fid_after"
7749 }
7750 run_test 56xf "FID is not lost during migration of a composite layout file"
7751
7752 check_file_ost_range() {
7753         local file="$1"
7754         shift
7755         local range="$*"
7756         local -a file_range
7757         local idx
7758
7759         file_range=($($LFS getstripe -y "$file" |
7760                 awk '/l_ost_idx:/ { print $NF }'))
7761
7762         if [[ "${#file_range[@]}" = 0 ]]; then
7763                 echo "No osts found for $file"
7764                 return 1
7765         fi
7766
7767         for idx in "${file_range[@]}"; do
7768                 [[ " $range " =~ " $idx " ]] ||
7769                         return 1
7770         done
7771
7772         return 0
7773 }
7774
7775 sub_test_56xg() {
7776         local stripe_opt="$1"
7777         local pool="$2"
7778         shift 2
7779         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7780
7781         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7782                 error "Fail to migrate $tfile on $pool"
7783         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7784                 error "$tfile is not in pool $pool"
7785         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7786                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7787 }
7788
7789 test_56xg() {
7790         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7791         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7792         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7793                 skip "Need MDS version newer than 2.14.52"
7794
7795         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7796         local -a pool_ranges=("0 0" "1 1" "0 1")
7797
7798         # init pools
7799         for i in "${!pool_names[@]}"; do
7800                 pool_add ${pool_names[$i]} ||
7801                         error "pool_add failed (pool: ${pool_names[$i]})"
7802                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7803                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7804         done
7805
7806         # init the file to migrate
7807         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7808                 error "Unable to create $tfile on OST1"
7809         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7810                 error "Unable to write on $tfile"
7811
7812         echo "1. migrate $tfile on pool ${pool_names[0]}"
7813         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7814
7815         echo "2. migrate $tfile on pool ${pool_names[2]}"
7816         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7817
7818         echo "3. migrate $tfile on pool ${pool_names[1]}"
7819         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7820
7821         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7822         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7823         echo
7824
7825         # Clean pools
7826         destroy_test_pools ||
7827                 error "pool_destroy failed"
7828 }
7829 run_test 56xg "lfs migrate pool support"
7830
7831 test_56y() {
7832         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7833                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7834
7835         local res=""
7836         local dir=$DIR/$tdir
7837         local f1=$dir/file1
7838         local f2=$dir/file2
7839
7840         test_mkdir -p $dir || error "creating dir $dir"
7841         touch $f1 || error "creating std file $f1"
7842         $MULTIOP $f2 H2c || error "creating released file $f2"
7843
7844         # a directory can be raid0, so ask only for files
7845         res=$($LFS find $dir -L raid0 -type f | wc -l)
7846         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7847
7848         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7849         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7850
7851         # only files can be released, so no need to force file search
7852         res=$($LFS find $dir -L released)
7853         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7854
7855         res=$($LFS find $dir -type f \! -L released)
7856         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7857 }
7858 run_test 56y "lfs find -L raid0|released"
7859
7860 test_56z() { # LU-4824
7861         # This checks to make sure 'lfs find' continues after errors
7862         # There are two classes of errors that should be caught:
7863         # - If multiple paths are provided, all should be searched even if one
7864         #   errors out
7865         # - If errors are encountered during the search, it should not terminate
7866         #   early
7867         local dir=$DIR/$tdir
7868         local i
7869
7870         test_mkdir $dir
7871         for i in d{0..9}; do
7872                 test_mkdir $dir/$i
7873                 touch $dir/$i/$tfile
7874         done
7875         $LFS find $DIR/non_existent_dir $dir &&
7876                 error "$LFS find did not return an error"
7877         # Make a directory unsearchable. This should NOT be the last entry in
7878         # directory order.  Arbitrarily pick the 6th entry
7879         chmod 700 $($LFS find $dir -type d | sed '6!d')
7880
7881         $RUNAS $LFS find $DIR/non_existent $dir
7882         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7883
7884         # The user should be able to see 10 directories and 9 files
7885         (( count == 19 )) ||
7886                 error "$LFS find found $count != 19 entries after error"
7887 }
7888 run_test 56z "lfs find should continue after an error"
7889
7890 test_56aa() { # LU-5937
7891         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7892
7893         local dir=$DIR/$tdir
7894
7895         mkdir $dir
7896         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7897
7898         createmany -o $dir/striped_dir/${tfile}- 1024
7899         local dirs=$($LFS find --size +8k $dir/)
7900
7901         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7902 }
7903 run_test 56aa "lfs find --size under striped dir"
7904
7905 test_56ab() { # LU-10705
7906         test_mkdir $DIR/$tdir
7907         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7908         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7909         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7910         # Flush writes to ensure valid blocks.  Need to be more thorough for
7911         # ZFS, since blocks are not allocated/returned to client immediately.
7912         sync_all_data
7913         wait_zfs_commit ost1 2
7914         cancel_lru_locks osc
7915         ls -ls $DIR/$tdir
7916
7917         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7918
7919         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7920
7921         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7922         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7923
7924         rm -f $DIR/$tdir/$tfile.[123]
7925 }
7926 run_test 56ab "lfs find --blocks"
7927
7928 # LU-11188
7929 test_56aca() {
7930         local dir="$DIR/$tdir"
7931         local perms=(001 002 003 004 005 006 007
7932                      010 020 030 040 050 060 070
7933                      100 200 300 400 500 600 700
7934                      111 222 333 444 555 666 777)
7935         local perm_minus=(8 8 4 8 4 4 2
7936                           8 8 4 8 4 4 2
7937                           8 8 4 8 4 4 2
7938                           4 4 2 4 2 2 1)
7939         local perm_slash=(8  8 12  8 12 12 14
7940                           8  8 12  8 12 12 14
7941                           8  8 12  8 12 12 14
7942                          16 16 24 16 24 24 28)
7943
7944         test_mkdir "$dir"
7945         for perm in ${perms[*]}; do
7946                 touch "$dir/$tfile.$perm"
7947                 chmod $perm "$dir/$tfile.$perm"
7948         done
7949
7950         for ((i = 0; i < ${#perms[*]}; i++)); do
7951                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7952                 (( $num == 1 )) ||
7953                         error "lfs find -perm ${perms[i]}:"\
7954                               "$num != 1"
7955
7956                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7957                 (( $num == ${perm_minus[i]} )) ||
7958                         error "lfs find -perm -${perms[i]}:"\
7959                               "$num != ${perm_minus[i]}"
7960
7961                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7962                 (( $num == ${perm_slash[i]} )) ||
7963                         error "lfs find -perm /${perms[i]}:"\
7964                               "$num != ${perm_slash[i]}"
7965         done
7966 }
7967 run_test 56aca "check lfs find -perm with octal representation"
7968
7969 test_56acb() {
7970         local dir=$DIR/$tdir
7971         # p is the permission of write and execute for user, group and other
7972         # without the umask. It is used to test +wx.
7973         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7974         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7975         local symbolic=(+t  a+t u+t g+t o+t
7976                         g+s u+s o+s +s o+sr
7977                         o=r,ug+o,u+w
7978                         u+ g+ o+ a+ ugo+
7979                         u- g- o- a- ugo-
7980                         u= g= o= a= ugo=
7981                         o=r,ug+o,u+w u=r,a+u,u+w
7982                         g=r,ugo=g,u+w u+x,+X +X
7983                         u+x,u+X u+X u+x,g+X o+r,+X
7984                         u+x,go+X +wx +rwx)
7985
7986         test_mkdir $dir
7987         for perm in ${perms[*]}; do
7988                 touch "$dir/$tfile.$perm"
7989                 chmod $perm "$dir/$tfile.$perm"
7990         done
7991
7992         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7993                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7994
7995                 (( $num == 1 )) ||
7996                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7997         done
7998 }
7999 run_test 56acb "check lfs find -perm with symbolic representation"
8000
8001 test_56acc() {
8002         local dir=$DIR/$tdir
8003         local tests="17777 787 789 abcd
8004                 ug=uu ug=a ug=gu uo=ou urw
8005                 u+xg+x a=r,u+x,"
8006
8007         test_mkdir $dir
8008         for err in $tests; do
8009                 if $LFS find $dir -perm $err 2>/dev/null; then
8010                         error "lfs find -perm $err: parsing should have failed"
8011                 fi
8012         done
8013 }
8014 run_test 56acc "check parsing error for lfs find -perm"
8015
8016 test_56ba() {
8017         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8018                 skip "Need MDS version at least 2.10.50"
8019
8020         # Create composite files with one component
8021         local dir=$DIR/$tdir
8022
8023         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8024         # Create composite files with three components
8025         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8026         # Create non-composite files
8027         createmany -o $dir/${tfile}- 10
8028
8029         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8030
8031         [[ $nfiles == 10 ]] ||
8032                 error "lfs find -E 1M found $nfiles != 10 files"
8033
8034         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8035         [[ $nfiles == 25 ]] ||
8036                 error "lfs find ! -E 1M found $nfiles != 25 files"
8037
8038         # All files have a component that starts at 0
8039         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8040         [[ $nfiles == 35 ]] ||
8041                 error "lfs find --component-start 0 - $nfiles != 35 files"
8042
8043         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8044         [[ $nfiles == 15 ]] ||
8045                 error "lfs find --component-start 2M - $nfiles != 15 files"
8046
8047         # All files created here have a componenet that does not starts at 2M
8048         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8049         [[ $nfiles == 35 ]] ||
8050                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8051
8052         # Find files with a specified number of components
8053         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8054         [[ $nfiles == 15 ]] ||
8055                 error "lfs find --component-count 3 - $nfiles != 15 files"
8056
8057         # Remember non-composite files have a component count of zero
8058         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8059         [[ $nfiles == 10 ]] ||
8060                 error "lfs find --component-count 0 - $nfiles != 10 files"
8061
8062         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8063         [[ $nfiles == 20 ]] ||
8064                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8065
8066         # All files have a flag called "init"
8067         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8068         [[ $nfiles == 35 ]] ||
8069                 error "lfs find --component-flags init - $nfiles != 35 files"
8070
8071         # Multi-component files will have a component not initialized
8072         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8073         [[ $nfiles == 15 ]] ||
8074                 error "lfs find !--component-flags init - $nfiles != 15 files"
8075
8076         rm -rf $dir
8077
8078 }
8079 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8080
8081 test_56ca() {
8082         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8083                 skip "Need MDS version at least 2.10.57"
8084
8085         local td=$DIR/$tdir
8086         local tf=$td/$tfile
8087         local dir
8088         local nfiles
8089         local cmd
8090         local i
8091         local j
8092
8093         # create mirrored directories and mirrored files
8094         mkdir $td || error "mkdir $td failed"
8095         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8096         createmany -o $tf- 10 || error "create $tf- failed"
8097
8098         for i in $(seq 2); do
8099                 dir=$td/dir$i
8100                 mkdir $dir || error "mkdir $dir failed"
8101                 $LFS mirror create -N$((3 + i)) $dir ||
8102                         error "create mirrored dir $dir failed"
8103                 createmany -o $dir/$tfile- 10 ||
8104                         error "create $dir/$tfile- failed"
8105         done
8106
8107         # change the states of some mirrored files
8108         echo foo > $tf-6
8109         for i in $(seq 2); do
8110                 dir=$td/dir$i
8111                 for j in $(seq 4 9); do
8112                         echo foo > $dir/$tfile-$j
8113                 done
8114         done
8115
8116         # find mirrored files with specific mirror count
8117         cmd="$LFS find --mirror-count 3 --type f $td"
8118         nfiles=$($cmd | wc -l)
8119         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8120
8121         cmd="$LFS find ! --mirror-count 3 --type f $td"
8122         nfiles=$($cmd | wc -l)
8123         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8124
8125         cmd="$LFS find --mirror-count +2 --type f $td"
8126         nfiles=$($cmd | wc -l)
8127         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8128
8129         cmd="$LFS find --mirror-count -6 --type f $td"
8130         nfiles=$($cmd | wc -l)
8131         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8132
8133         # find mirrored files with specific file state
8134         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8135         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8136
8137         cmd="$LFS find --mirror-state=ro --type f $td"
8138         nfiles=$($cmd | wc -l)
8139         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8140
8141         cmd="$LFS find ! --mirror-state=ro --type f $td"
8142         nfiles=$($cmd | wc -l)
8143         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8144
8145         cmd="$LFS find --mirror-state=wp --type f $td"
8146         nfiles=$($cmd | wc -l)
8147         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8148
8149         cmd="$LFS find ! --mirror-state=sp --type f $td"
8150         nfiles=$($cmd | wc -l)
8151         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8152 }
8153 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8154
8155 test_56da() { # LU-14179
8156         local path=$DIR/$tdir
8157
8158         test_mkdir $path
8159         cd $path
8160
8161         local longdir=$(str_repeat 'a' 255)
8162
8163         for i in {1..15}; do
8164                 path=$path/$longdir
8165                 test_mkdir $longdir
8166                 cd $longdir
8167         done
8168
8169         local len=${#path}
8170         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8171
8172         test_mkdir $lastdir
8173         cd $lastdir
8174         # PATH_MAX-1
8175         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8176
8177         # NAME_MAX
8178         touch $(str_repeat 'f' 255)
8179
8180         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8181                 error "lfs find reported an error"
8182
8183         rm -rf $DIR/$tdir
8184 }
8185 run_test 56da "test lfs find with long paths"
8186
8187 test_56ea() { #LU-10378
8188         local path=$DIR/$tdir
8189         local pool=$TESTNAME
8190
8191         # Create ost pool
8192         pool_add $pool || error "pool_add $pool failed"
8193         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8194                 error "adding targets to $pool failed"
8195
8196         # Set default pool on directory before creating file
8197         mkdir $path || error "mkdir $path failed"
8198         $LFS setstripe -p $pool $path ||
8199                 error "set OST pool on $pool failed"
8200         touch $path/$tfile || error "touch $path/$tfile failed"
8201
8202         # Compare basic file attributes from -printf and stat
8203         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8204         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8205
8206         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8207                 error "Attrs from lfs find and stat don't match"
8208
8209         # Compare Lustre attributes from lfs find and lfs getstripe
8210         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8211         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8212         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8213         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8214         local fpool=$($LFS getstripe --pool $path/$tfile)
8215         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8216
8217         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8218                 error "Attrs from lfs find and lfs getstripe don't match"
8219
8220         # Verify behavior for unknown escape/format sequences
8221         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8222
8223         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8224                 error "Escape/format codes don't match"
8225 }
8226 run_test 56ea "test lfs find -printf option"
8227
8228 test_57a() {
8229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8230         # note test will not do anything if MDS is not local
8231         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8232                 skip_env "ldiskfs only test"
8233         fi
8234         remote_mds_nodsh && skip "remote MDS with nodsh"
8235
8236         local MNTDEV="osd*.*MDT*.mntdev"
8237         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8238         [ -z "$DEV" ] && error "can't access $MNTDEV"
8239         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8240                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8241                         error "can't access $DEV"
8242                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8243                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8244                 rm $TMP/t57a.dump
8245         done
8246 }
8247 run_test 57a "verify MDS filesystem created with large inodes =="
8248
8249 test_57b() {
8250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8251         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8252                 skip_env "ldiskfs only test"
8253         fi
8254         remote_mds_nodsh && skip "remote MDS with nodsh"
8255
8256         local dir=$DIR/$tdir
8257         local filecount=100
8258         local file1=$dir/f1
8259         local fileN=$dir/f$filecount
8260
8261         rm -rf $dir || error "removing $dir"
8262         test_mkdir -c1 $dir
8263         local mdtidx=$($LFS getstripe -m $dir)
8264         local mdtname=MDT$(printf %04x $mdtidx)
8265         local facet=mds$((mdtidx + 1))
8266
8267         echo "mcreating $filecount files"
8268         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8269
8270         # verify that files do not have EAs yet
8271         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8272                 error "$file1 has an EA"
8273         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8274                 error "$fileN has an EA"
8275
8276         sync
8277         sleep 1
8278         df $dir  #make sure we get new statfs data
8279         local mdsfree=$(do_facet $facet \
8280                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8281         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8282         local file
8283
8284         echo "opening files to create objects/EAs"
8285         for file in $(seq -f $dir/f%g 1 $filecount); do
8286                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8287                         error "opening $file"
8288         done
8289
8290         # verify that files have EAs now
8291         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8292         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8293
8294         sleep 1  #make sure we get new statfs data
8295         df $dir
8296         local mdsfree2=$(do_facet $facet \
8297                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8298         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8299
8300         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8301                 if [ "$mdsfree" != "$mdsfree2" ]; then
8302                         error "MDC before $mdcfree != after $mdcfree2"
8303                 else
8304                         echo "MDC before $mdcfree != after $mdcfree2"
8305                         echo "unable to confirm if MDS has large inodes"
8306                 fi
8307         fi
8308         rm -rf $dir
8309 }
8310 run_test 57b "default LOV EAs are stored inside large inodes ==="
8311
8312 test_58() {
8313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8314         [ -z "$(which wiretest 2>/dev/null)" ] &&
8315                         skip_env "could not find wiretest"
8316
8317         wiretest
8318 }
8319 run_test 58 "verify cross-platform wire constants =============="
8320
8321 test_59() {
8322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8323
8324         echo "touch 130 files"
8325         createmany -o $DIR/f59- 130
8326         echo "rm 130 files"
8327         unlinkmany $DIR/f59- 130
8328         sync
8329         # wait for commitment of removal
8330         wait_delete_completed
8331 }
8332 run_test 59 "verify cancellation of llog records async ========="
8333
8334 TEST60_HEAD="test_60 run $RANDOM"
8335 test_60a() {
8336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8337         remote_mgs_nodsh && skip "remote MGS with nodsh"
8338         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8339                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8340                         skip_env "missing subtest run-llog.sh"
8341
8342         log "$TEST60_HEAD - from kernel mode"
8343         do_facet mgs "$LCTL dk > /dev/null"
8344         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8345         do_facet mgs $LCTL dk > $TMP/$tfile
8346
8347         # LU-6388: test llog_reader
8348         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8349         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8350         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8351                         skip_env "missing llog_reader"
8352         local fstype=$(facet_fstype mgs)
8353         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8354                 skip_env "Only for ldiskfs or zfs type mgs"
8355
8356         local mntpt=$(facet_mntpt mgs)
8357         local mgsdev=$(mgsdevname 1)
8358         local fid_list
8359         local fid
8360         local rec_list
8361         local rec
8362         local rec_type
8363         local obj_file
8364         local path
8365         local seq
8366         local oid
8367         local pass=true
8368
8369         #get fid and record list
8370         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8371                 tail -n 4))
8372         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8373                 tail -n 4))
8374         #remount mgs as ldiskfs or zfs type
8375         stop mgs || error "stop mgs failed"
8376         mount_fstype mgs || error "remount mgs failed"
8377         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8378                 fid=${fid_list[i]}
8379                 rec=${rec_list[i]}
8380                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8381                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8382                 oid=$((16#$oid))
8383
8384                 case $fstype in
8385                         ldiskfs )
8386                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8387                         zfs )
8388                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8389                 esac
8390                 echo "obj_file is $obj_file"
8391                 do_facet mgs $llog_reader $obj_file
8392
8393                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8394                         awk '{ print $3 }' | sed -e "s/^type=//g")
8395                 if [ $rec_type != $rec ]; then
8396                         echo "FAILED test_60a wrong record type $rec_type," \
8397                               "should be $rec"
8398                         pass=false
8399                         break
8400                 fi
8401
8402                 #check obj path if record type is LLOG_LOGID_MAGIC
8403                 if [ "$rec" == "1064553b" ]; then
8404                         path=$(do_facet mgs $llog_reader $obj_file |
8405                                 grep "path=" | awk '{ print $NF }' |
8406                                 sed -e "s/^path=//g")
8407                         if [ $obj_file != $mntpt/$path ]; then
8408                                 echo "FAILED test_60a wrong obj path" \
8409                                       "$montpt/$path, should be $obj_file"
8410                                 pass=false
8411                                 break
8412                         fi
8413                 fi
8414         done
8415         rm -f $TMP/$tfile
8416         #restart mgs before "error", otherwise it will block the next test
8417         stop mgs || error "stop mgs failed"
8418         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8419         $pass || error "test failed, see FAILED test_60a messages for specifics"
8420 }
8421 run_test 60a "llog_test run from kernel module and test llog_reader"
8422
8423 test_60b() { # bug 6411
8424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8425
8426         dmesg > $DIR/$tfile
8427         LLOG_COUNT=$(do_facet mgs dmesg |
8428                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8429                           /llog_[a-z]*.c:[0-9]/ {
8430                                 if (marker)
8431                                         from_marker++
8432                                 from_begin++
8433                           }
8434                           END {
8435                                 if (marker)
8436                                         print from_marker
8437                                 else
8438                                         print from_begin
8439                           }")
8440
8441         [[ $LLOG_COUNT -gt 120 ]] &&
8442                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8443 }
8444 run_test 60b "limit repeated messages from CERROR/CWARN"
8445
8446 test_60c() {
8447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8448
8449         echo "create 5000 files"
8450         createmany -o $DIR/f60c- 5000
8451 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8452         lctl set_param fail_loc=0x80000137
8453         unlinkmany $DIR/f60c- 5000
8454         lctl set_param fail_loc=0
8455 }
8456 run_test 60c "unlink file when mds full"
8457
8458 test_60d() {
8459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8460
8461         SAVEPRINTK=$(lctl get_param -n printk)
8462         # verify "lctl mark" is even working"
8463         MESSAGE="test message ID $RANDOM $$"
8464         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8465         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8466
8467         lctl set_param printk=0 || error "set lnet.printk failed"
8468         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8469         MESSAGE="new test message ID $RANDOM $$"
8470         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8471         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8472         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8473
8474         lctl set_param -n printk="$SAVEPRINTK"
8475 }
8476 run_test 60d "test printk console message masking"
8477
8478 test_60e() {
8479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8480         remote_mds_nodsh && skip "remote MDS with nodsh"
8481
8482         touch $DIR/$tfile
8483 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8484         do_facet mds1 lctl set_param fail_loc=0x15b
8485         rm $DIR/$tfile
8486 }
8487 run_test 60e "no space while new llog is being created"
8488
8489 test_60f() {
8490         local old_path=$($LCTL get_param -n debug_path)
8491
8492         stack_trap "$LCTL set_param debug_path=$old_path"
8493         stack_trap "rm -f $TMP/$tfile*"
8494         rm -f $TMP/$tfile* 2> /dev/null
8495         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8496         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8497         test_mkdir $DIR/$tdir
8498         # retry in case the open is cached and not released
8499         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8500                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8501                 sleep 0.1
8502         done
8503         ls $TMP/$tfile*
8504         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8505 }
8506 run_test 60f "change debug_path works"
8507
8508 test_60g() {
8509         local pid
8510         local i
8511
8512         test_mkdir -c $MDSCOUNT $DIR/$tdir
8513
8514         (
8515                 local index=0
8516                 while true; do
8517                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8518                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8519                                 2>/dev/null
8520                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8521                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8522                         index=$((index + 1))
8523                 done
8524         ) &
8525
8526         pid=$!
8527
8528         for i in {0..100}; do
8529                 # define OBD_FAIL_OSD_TXN_START    0x19a
8530                 local index=$((i % MDSCOUNT + 1))
8531
8532                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8533                         > /dev/null
8534                 sleep 0.01
8535         done
8536
8537         kill -9 $pid
8538
8539         for i in $(seq $MDSCOUNT); do
8540                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8541         done
8542
8543         mkdir $DIR/$tdir/new || error "mkdir failed"
8544         rmdir $DIR/$tdir/new || error "rmdir failed"
8545
8546         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8547                 -t namespace
8548         for i in $(seq $MDSCOUNT); do
8549                 wait_update_facet mds$i "$LCTL get_param -n \
8550                         mdd.$(facet_svc mds$i).lfsck_namespace |
8551                         awk '/^status/ { print \\\$2 }'" "completed"
8552         done
8553
8554         ls -R $DIR/$tdir
8555         rm -rf $DIR/$tdir || error "rmdir failed"
8556 }
8557 run_test 60g "transaction abort won't cause MDT hung"
8558
8559 test_60h() {
8560         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8561                 skip "Need MDS version at least 2.12.52"
8562         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8563
8564         local f
8565
8566         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8567         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8568         for fail_loc in 0x80000188 0x80000189; do
8569                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8570                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8571                         error "mkdir $dir-$fail_loc failed"
8572                 for i in {0..10}; do
8573                         # create may fail on missing stripe
8574                         echo $i > $DIR/$tdir-$fail_loc/$i
8575                 done
8576                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8577                         error "getdirstripe $tdir-$fail_loc failed"
8578                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8579                         error "migrate $tdir-$fail_loc failed"
8580                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8581                         error "getdirstripe $tdir-$fail_loc failed"
8582                 pushd $DIR/$tdir-$fail_loc
8583                 for f in *; do
8584                         echo $f | cmp $f - || error "$f data mismatch"
8585                 done
8586                 popd
8587                 rm -rf $DIR/$tdir-$fail_loc
8588         done
8589 }
8590 run_test 60h "striped directory with missing stripes can be accessed"
8591
8592 function t60i_load() {
8593         mkdir $DIR/$tdir
8594         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8595         $LCTL set_param fail_loc=0x131c fail_val=1
8596         for ((i=0; i<5000; i++)); do
8597                 touch $DIR/$tdir/f$i
8598         done
8599 }
8600
8601 test_60i() {
8602         changelog_register || error "changelog_register failed"
8603         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8604         changelog_users $SINGLEMDS | grep -q $cl_user ||
8605                 error "User $cl_user not found in changelog_users"
8606         changelog_chmask "ALL"
8607         t60i_load &
8608         local PID=$!
8609         for((i=0; i<100; i++)); do
8610                 changelog_dump >/dev/null ||
8611                         error "can't read changelog"
8612         done
8613         kill $PID
8614         wait $PID
8615         changelog_deregister || error "changelog_deregister failed"
8616         $LCTL set_param fail_loc=0
8617 }
8618 run_test 60i "llog: new record vs reader race"
8619
8620 test_61a() {
8621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8622
8623         f="$DIR/f61"
8624         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8625         cancel_lru_locks osc
8626         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8627         sync
8628 }
8629 run_test 61a "mmap() writes don't make sync hang ================"
8630
8631 test_61b() {
8632         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8633 }
8634 run_test 61b "mmap() of unstriped file is successful"
8635
8636 # bug 2330 - insufficient obd_match error checking causes LBUG
8637 test_62() {
8638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8639
8640         f="$DIR/f62"
8641         echo foo > $f
8642         cancel_lru_locks osc
8643         lctl set_param fail_loc=0x405
8644         cat $f && error "cat succeeded, expect -EIO"
8645         lctl set_param fail_loc=0
8646 }
8647 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8648 # match every page all of the time.
8649 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8650
8651 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8652 # Though this test is irrelevant anymore, it helped to reveal some
8653 # other grant bugs (LU-4482), let's keep it.
8654 test_63a() {   # was test_63
8655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8656
8657         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8658
8659         for i in `seq 10` ; do
8660                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8661                 sleep 5
8662                 kill $!
8663                 sleep 1
8664         done
8665
8666         rm -f $DIR/f63 || true
8667 }
8668 run_test 63a "Verify oig_wait interruption does not crash ======="
8669
8670 # bug 2248 - async write errors didn't return to application on sync
8671 # bug 3677 - async write errors left page locked
8672 test_63b() {
8673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8674
8675         debugsave
8676         lctl set_param debug=-1
8677
8678         # ensure we have a grant to do async writes
8679         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8680         rm $DIR/$tfile
8681
8682         sync    # sync lest earlier test intercept the fail_loc
8683
8684         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8685         lctl set_param fail_loc=0x80000406
8686         $MULTIOP $DIR/$tfile Owy && \
8687                 error "sync didn't return ENOMEM"
8688         sync; sleep 2; sync     # do a real sync this time to flush page
8689         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8690                 error "locked page left in cache after async error" || true
8691         debugrestore
8692 }
8693 run_test 63b "async write errors should be returned to fsync ==="
8694
8695 test_64a () {
8696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8697
8698         lfs df $DIR
8699         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8700 }
8701 run_test 64a "verify filter grant calculations (in kernel) ====="
8702
8703 test_64b () {
8704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8705
8706         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8707 }
8708 run_test 64b "check out-of-space detection on client"
8709
8710 test_64c() {
8711         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8712 }
8713 run_test 64c "verify grant shrink"
8714
8715 import_param() {
8716         local tgt=$1
8717         local param=$2
8718
8719         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8720 }
8721
8722 # this does exactly what osc_request.c:osc_announce_cached() does in
8723 # order to calculate max amount of grants to ask from server
8724 want_grant() {
8725         local tgt=$1
8726
8727         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8728         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8729
8730         ((rpc_in_flight++));
8731         nrpages=$((nrpages * rpc_in_flight))
8732
8733         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8734
8735         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8736
8737         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8738         local undirty=$((nrpages * PAGE_SIZE))
8739
8740         local max_extent_pages
8741         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8742         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8743         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8744         local grant_extent_tax
8745         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8746
8747         undirty=$((undirty + nrextents * grant_extent_tax))
8748
8749         echo $undirty
8750 }
8751
8752 # this is size of unit for grant allocation. It should be equal to
8753 # what tgt_grant.c:tgt_grant_chunk() calculates
8754 grant_chunk() {
8755         local tgt=$1
8756         local max_brw_size
8757         local grant_extent_tax
8758
8759         max_brw_size=$(import_param $tgt max_brw_size)
8760
8761         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8762
8763         echo $(((max_brw_size + grant_extent_tax) * 2))
8764 }
8765
8766 test_64d() {
8767         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8768                 skip "OST < 2.10.55 doesn't limit grants enough"
8769
8770         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8771
8772         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8773                 skip "no grant_param connect flag"
8774
8775         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8776
8777         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8778         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8779
8780
8781         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8782         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8783
8784         $LFS setstripe $DIR/$tfile -i 0 -c 1
8785         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8786         ddpid=$!
8787
8788         while kill -0 $ddpid; do
8789                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8790
8791                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8792                         kill $ddpid
8793                         error "cur_grant $cur_grant > $max_cur_granted"
8794                 fi
8795
8796                 sleep 1
8797         done
8798 }
8799 run_test 64d "check grant limit exceed"
8800
8801 check_grants() {
8802         local tgt=$1
8803         local expected=$2
8804         local msg=$3
8805         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8806
8807         ((cur_grants == expected)) ||
8808                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8809 }
8810
8811 round_up_p2() {
8812         echo $((($1 + $2 - 1) & ~($2 - 1)))
8813 }
8814
8815 test_64e() {
8816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8817         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8818                 skip "Need OSS version at least 2.11.56"
8819
8820         # Remount client to reset grant
8821         remount_client $MOUNT || error "failed to remount client"
8822         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8823
8824         local init_grants=$(import_param $osc_tgt initial_grant)
8825
8826         check_grants $osc_tgt $init_grants "init grants"
8827
8828         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8829         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8830         local gbs=$(import_param $osc_tgt grant_block_size)
8831
8832         # write random number of bytes from max_brw_size / 4 to max_brw_size
8833         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8834         # align for direct io
8835         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8836         # round to grant consumption unit
8837         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8838
8839         local grants=$((wb_round_up + extent_tax))
8840
8841         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8842
8843         # define OBD_FAIL_TGT_NO_GRANT 0x725
8844         # make the server not grant more back
8845         do_facet ost1 $LCTL set_param fail_loc=0x725
8846         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8847
8848         do_facet ost1 $LCTL set_param fail_loc=0
8849
8850         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8851
8852         rm -f $DIR/$tfile || error "rm failed"
8853
8854         # Remount client to reset grant
8855         remount_client $MOUNT || error "failed to remount client"
8856         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8857
8858         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8859
8860         # define OBD_FAIL_TGT_NO_GRANT 0x725
8861         # make the server not grant more back
8862         do_facet ost1 $LCTL set_param fail_loc=0x725
8863         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8864         do_facet ost1 $LCTL set_param fail_loc=0
8865
8866         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8867 }
8868 run_test 64e "check grant consumption (no grant allocation)"
8869
8870 test_64f() {
8871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8872
8873         # Remount client to reset grant
8874         remount_client $MOUNT || error "failed to remount client"
8875         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8876
8877         local init_grants=$(import_param $osc_tgt initial_grant)
8878         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8879         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8880         local gbs=$(import_param $osc_tgt grant_block_size)
8881         local chunk=$(grant_chunk $osc_tgt)
8882
8883         # write random number of bytes from max_brw_size / 4 to max_brw_size
8884         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8885         # align for direct io
8886         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8887         # round to grant consumption unit
8888         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8889
8890         local grants=$((wb_round_up + extent_tax))
8891
8892         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8893         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8894                 error "error writing to $DIR/$tfile"
8895
8896         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8897                 "direct io with grant allocation"
8898
8899         rm -f $DIR/$tfile || error "rm failed"
8900
8901         # Remount client to reset grant
8902         remount_client $MOUNT || error "failed to remount client"
8903         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8904
8905         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8906
8907         local cmd="oO_WRONLY:w${write_bytes}_yc"
8908
8909         $MULTIOP $DIR/$tfile $cmd &
8910         MULTIPID=$!
8911         sleep 1
8912
8913         check_grants $osc_tgt $((init_grants - grants)) \
8914                 "buffered io, not write rpc"
8915
8916         kill -USR1 $MULTIPID
8917         wait
8918
8919         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8920                 "buffered io, one RPC"
8921 }
8922 run_test 64f "check grant consumption (with grant allocation)"
8923
8924 test_64g() {
8925         #[ $MDS1_VERSION -lt $(version_code 2.14.54) ] &&
8926         #       skip "Need MDS version at least 2.14.54"
8927
8928         local mdts=$(comma_list $(mdts_nodes))
8929
8930         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8931                         tr '\n' ' ')
8932         stack_trap "$LCTL set_param $old"
8933
8934         # generate dirty pages and increase dirty granted on MDT
8935         stack_trap "rm -f $DIR/$tfile-*"
8936         for (( i = 0; i < 10; i++)); do
8937                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8938                         error "can't set stripe"
8939                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8940                         error "can't dd"
8941                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8942                         $LFS getstripe $DIR/$tfile-$i
8943                         error "not DoM file"
8944                 }
8945         done
8946
8947         # flush dirty pages
8948         sync
8949
8950         # wait until grant shrink reset grant dirty on MDTs
8951         for ((i = 0; i < 120; i++)); do
8952                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8953                         awk '{sum=sum+$1} END {print sum}')
8954                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8955                 echo "$grant_dirty grants, $vm_dirty pages"
8956                 (( grant_dirty + vm_dirty == 0 )) && break
8957                 (( i == 3 )) && sync &&
8958                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8959                 sleep 1
8960         done
8961
8962         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8963                 awk '{sum=sum+$1} END {print sum}')
8964         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8965 }
8966 run_test 64g "grant shrink on MDT"
8967
8968 test_64h() {
8969         local instance=$($LFS getname -i $DIR)
8970         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8971         local num_exps=$(do_facet ost1 \
8972             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8973         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8974         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8975         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8976
8977         # 10MiB is for file to be written, max_brw_size * 16 *
8978         # num_exps is space reserve so that tgt_grant_shrink() decided
8979         # to not shrink
8980         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8981         (( avail * 1024 < expect )) &&
8982                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8983
8984         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8985         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
8986         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
8987         $LCTL set_param osc.*OST0000*.grant_shrink=1
8988         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
8989
8990         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8991         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
8992
8993         # drop cache so that coming read would do rpc
8994         cancel_lru_locks osc
8995
8996         # shrink interval is set to 10, pause for 7 seconds so that
8997         # grant thread did not wake up yet but coming read entered
8998         # shrink mode for rpc (osc_should_shrink_grant())
8999         sleep 7
9000
9001         declare -a cur_grant_bytes
9002         declare -a tot_granted
9003         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9004         tot_granted[0]=$(do_facet ost1 \
9005             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9006
9007         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9008
9009         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9010         tot_granted[1]=$(do_facet ost1 \
9011             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9012
9013         # grant change should be equal on both sides
9014         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9015                 tot_granted[0] - tot_granted[1])) ||
9016                 error "grant change mismatch, "                                \
9017                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9018                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9019 }
9020 run_test 64h "grant shrink on read"
9021
9022 test_64i() {
9023         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
9024                 skip "need OST at least 2.14.55 to avoid grant shrink on replay"
9025
9026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9027         remote_ost_nodsh && skip "remote OSTs with nodsh"
9028
9029         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9030
9031         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9032
9033         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9034         local instance=$($LFS getname -i $DIR)
9035
9036         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9037         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9038
9039         # shrink grants and simulate rpc loss
9040         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9041         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9042         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9043
9044         fail ost1
9045
9046         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9047
9048         local testid=$(echo $TESTNAME | tr '_' ' ')
9049
9050         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9051                 grep "GRANT, real grant" &&
9052                 error "client has more grants then it owns" || true
9053 }
9054 run_test 64i "shrink on reconnect"
9055
9056 # bug 1414 - set/get directories' stripe info
9057 test_65a() {
9058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9059
9060         test_mkdir $DIR/$tdir
9061         touch $DIR/$tdir/f1
9062         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9063 }
9064 run_test 65a "directory with no stripe info"
9065
9066 test_65b() {
9067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9068
9069         test_mkdir $DIR/$tdir
9070         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9071
9072         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9073                                                 error "setstripe"
9074         touch $DIR/$tdir/f2
9075         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9076 }
9077 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9078
9079 test_65c() {
9080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9081         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9082
9083         test_mkdir $DIR/$tdir
9084         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9085
9086         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9087                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9088         touch $DIR/$tdir/f3
9089         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9090 }
9091 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9092
9093 test_65d() {
9094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9095
9096         test_mkdir $DIR/$tdir
9097         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9098         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9099
9100         if [[ $STRIPECOUNT -le 0 ]]; then
9101                 sc=1
9102         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9103                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9104                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9105         else
9106                 sc=$(($STRIPECOUNT - 1))
9107         fi
9108         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9109         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9110         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9111                 error "lverify failed"
9112 }
9113 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9114
9115 test_65e() {
9116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9117
9118         test_mkdir $DIR/$tdir
9119
9120         $LFS setstripe $DIR/$tdir || error "setstripe"
9121         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9122                                         error "no stripe info failed"
9123         touch $DIR/$tdir/f6
9124         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9125 }
9126 run_test 65e "directory setstripe defaults"
9127
9128 test_65f() {
9129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9130
9131         test_mkdir $DIR/${tdir}f
9132         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9133                 error "setstripe succeeded" || true
9134 }
9135 run_test 65f "dir setstripe permission (should return error) ==="
9136
9137 test_65g() {
9138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9139
9140         test_mkdir $DIR/$tdir
9141         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9142
9143         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9144                 error "setstripe -S failed"
9145         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9146         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9147                 error "delete default stripe failed"
9148 }
9149 run_test 65g "directory setstripe -d"
9150
9151 test_65h() {
9152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9153
9154         test_mkdir $DIR/$tdir
9155         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9156
9157         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9158                 error "setstripe -S failed"
9159         test_mkdir $DIR/$tdir/dd1
9160         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9161                 error "stripe info inherit failed"
9162 }
9163 run_test 65h "directory stripe info inherit ===================="
9164
9165 test_65i() {
9166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9167
9168         save_layout_restore_at_exit $MOUNT
9169
9170         # bug6367: set non-default striping on root directory
9171         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9172
9173         # bug12836: getstripe on -1 default directory striping
9174         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9175
9176         # bug12836: getstripe -v on -1 default directory striping
9177         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9178
9179         # bug12836: new find on -1 default directory striping
9180         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9181 }
9182 run_test 65i "various tests to set root directory striping"
9183
9184 test_65j() { # bug6367
9185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9186
9187         sync; sleep 1
9188
9189         # if we aren't already remounting for each test, do so for this test
9190         if [ "$I_MOUNTED" = "yes" ]; then
9191                 cleanup || error "failed to unmount"
9192                 setup
9193         fi
9194
9195         save_layout_restore_at_exit $MOUNT
9196
9197         $LFS setstripe -d $MOUNT || error "setstripe failed"
9198 }
9199 run_test 65j "set default striping on root directory (bug 6367)="
9200
9201 cleanup_65k() {
9202         rm -rf $DIR/$tdir
9203         wait_delete_completed
9204         do_facet $SINGLEMDS "lctl set_param -n \
9205                 osp.$ost*MDT0000.max_create_count=$max_count"
9206         do_facet $SINGLEMDS "lctl set_param -n \
9207                 osp.$ost*MDT0000.create_count=$count"
9208         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9209         echo $INACTIVE_OSC "is Activate"
9210
9211         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9212 }
9213
9214 test_65k() { # bug11679
9215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9216         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9217         remote_mds_nodsh && skip "remote MDS with nodsh"
9218
9219         local disable_precreate=true
9220         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9221                 disable_precreate=false
9222
9223         echo "Check OST status: "
9224         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9225                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9226
9227         for OSC in $MDS_OSCS; do
9228                 echo $OSC "is active"
9229                 do_facet $SINGLEMDS lctl --device %$OSC activate
9230         done
9231
9232         for INACTIVE_OSC in $MDS_OSCS; do
9233                 local ost=$(osc_to_ost $INACTIVE_OSC)
9234                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9235                                lov.*md*.target_obd |
9236                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9237
9238                 mkdir -p $DIR/$tdir
9239                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9240                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9241
9242                 echo "Deactivate: " $INACTIVE_OSC
9243                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9244
9245                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9246                               osp.$ost*MDT0000.create_count")
9247                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9248                                   osp.$ost*MDT0000.max_create_count")
9249                 $disable_precreate &&
9250                         do_facet $SINGLEMDS "lctl set_param -n \
9251                                 osp.$ost*MDT0000.max_create_count=0"
9252
9253                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9254                         [ -f $DIR/$tdir/$idx ] && continue
9255                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9256                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9257                                 { cleanup_65k;
9258                                   error "setstripe $idx should succeed"; }
9259                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9260                 done
9261                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9262                 rmdir $DIR/$tdir
9263
9264                 do_facet $SINGLEMDS "lctl set_param -n \
9265                         osp.$ost*MDT0000.max_create_count=$max_count"
9266                 do_facet $SINGLEMDS "lctl set_param -n \
9267                         osp.$ost*MDT0000.create_count=$count"
9268                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9269                 echo $INACTIVE_OSC "is Activate"
9270
9271                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9272         done
9273 }
9274 run_test 65k "validate manual striping works properly with deactivated OSCs"
9275
9276 test_65l() { # bug 12836
9277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9278
9279         test_mkdir -p $DIR/$tdir/test_dir
9280         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9281         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9282 }
9283 run_test 65l "lfs find on -1 stripe dir ========================"
9284
9285 test_65m() {
9286         local layout=$(save_layout $MOUNT)
9287         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9288                 restore_layout $MOUNT $layout
9289                 error "setstripe should fail by non-root users"
9290         }
9291         true
9292 }
9293 run_test 65m "normal user can't set filesystem default stripe"
9294
9295 test_65n() {
9296         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9297         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9298                 skip "Need MDS version at least 2.12.50"
9299         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9300
9301         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9302         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9303         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9304
9305         save_layout_restore_at_exit $MOUNT
9306
9307         # new subdirectory under root directory should not inherit
9308         # the default layout from root
9309         local dir1=$MOUNT/$tdir-1
9310         mkdir $dir1 || error "mkdir $dir1 failed"
9311         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9312                 error "$dir1 shouldn't have LOV EA"
9313
9314         # delete the default layout on root directory
9315         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9316
9317         local dir2=$MOUNT/$tdir-2
9318         mkdir $dir2 || error "mkdir $dir2 failed"
9319         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9320                 error "$dir2 shouldn't have LOV EA"
9321
9322         # set a new striping pattern on root directory
9323         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9324         local new_def_stripe_size=$((def_stripe_size * 2))
9325         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9326                 error "set stripe size on $MOUNT failed"
9327
9328         # new file created in $dir2 should inherit the new stripe size from
9329         # the filesystem default
9330         local file2=$dir2/$tfile-2
9331         touch $file2 || error "touch $file2 failed"
9332
9333         local file2_stripe_size=$($LFS getstripe -S $file2)
9334         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9335         {
9336                 echo "file2_stripe_size: '$file2_stripe_size'"
9337                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9338                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9339         }
9340
9341         local dir3=$MOUNT/$tdir-3
9342         mkdir $dir3 || error "mkdir $dir3 failed"
9343         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9344         # the root layout, which is the actual default layout that will be used
9345         # when new files are created in $dir3.
9346         local dir3_layout=$(get_layout_param $dir3)
9347         local root_dir_layout=$(get_layout_param $MOUNT)
9348         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9349         {
9350                 echo "dir3_layout: '$dir3_layout'"
9351                 echo "root_dir_layout: '$root_dir_layout'"
9352                 error "$dir3 should show the default layout from $MOUNT"
9353         }
9354
9355         # set OST pool on root directory
9356         local pool=$TESTNAME
9357         pool_add $pool || error "add $pool failed"
9358         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9359                 error "add targets to $pool failed"
9360
9361         $LFS setstripe -p $pool $MOUNT ||
9362                 error "set OST pool on $MOUNT failed"
9363
9364         # new file created in $dir3 should inherit the pool from
9365         # the filesystem default
9366         local file3=$dir3/$tfile-3
9367         touch $file3 || error "touch $file3 failed"
9368
9369         local file3_pool=$($LFS getstripe -p $file3)
9370         [[ "$file3_pool" = "$pool" ]] ||
9371                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9372
9373         local dir4=$MOUNT/$tdir-4
9374         mkdir $dir4 || error "mkdir $dir4 failed"
9375         local dir4_layout=$(get_layout_param $dir4)
9376         root_dir_layout=$(get_layout_param $MOUNT)
9377         echo "$LFS getstripe -d $dir4"
9378         $LFS getstripe -d $dir4
9379         echo "$LFS getstripe -d $MOUNT"
9380         $LFS getstripe -d $MOUNT
9381         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9382         {
9383                 echo "dir4_layout: '$dir4_layout'"
9384                 echo "root_dir_layout: '$root_dir_layout'"
9385                 error "$dir4 should show the default layout from $MOUNT"
9386         }
9387
9388         # new file created in $dir4 should inherit the pool from
9389         # the filesystem default
9390         local file4=$dir4/$tfile-4
9391         touch $file4 || error "touch $file4 failed"
9392
9393         local file4_pool=$($LFS getstripe -p $file4)
9394         [[ "$file4_pool" = "$pool" ]] ||
9395                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9396
9397         # new subdirectory under non-root directory should inherit
9398         # the default layout from its parent directory
9399         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9400                 error "set directory layout on $dir4 failed"
9401
9402         local dir5=$dir4/$tdir-5
9403         mkdir $dir5 || error "mkdir $dir5 failed"
9404
9405         dir4_layout=$(get_layout_param $dir4)
9406         local dir5_layout=$(get_layout_param $dir5)
9407         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9408         {
9409                 echo "dir4_layout: '$dir4_layout'"
9410                 echo "dir5_layout: '$dir5_layout'"
9411                 error "$dir5 should inherit the default layout from $dir4"
9412         }
9413
9414         # though subdir under ROOT doesn't inherit default layout, but
9415         # its sub dir/file should be created with default layout.
9416         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9417         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9418                 skip "Need MDS version at least 2.12.59"
9419
9420         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9421         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9422         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9423
9424         if [ $default_lmv_hash == "none" ]; then
9425                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9426         else
9427                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9428                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9429         fi
9430
9431         $LFS setdirstripe -D -c 2 $MOUNT ||
9432                 error "setdirstripe -D -c 2 failed"
9433         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9434         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9435         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9436
9437         # $dir4 layout includes pool
9438         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9439         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9440                 error "pool lost on setstripe"
9441         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9442         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9443                 error "pool lost on compound layout setstripe"
9444 }
9445 run_test 65n "don't inherit default layout from root for new subdirectories"
9446
9447 # bug 2543 - update blocks count on client
9448 test_66() {
9449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9450
9451         COUNT=${COUNT:-8}
9452         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9453         sync; sync_all_data; sync; sync_all_data
9454         cancel_lru_locks osc
9455         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9456         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9457 }
9458 run_test 66 "update inode blocks count on client ==============="
9459
9460 meminfo() {
9461         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9462 }
9463
9464 swap_used() {
9465         swapon -s | awk '($1 == "'$1'") { print $4 }'
9466 }
9467
9468 # bug5265, obdfilter oa2dentry return -ENOENT
9469 # #define OBD_FAIL_SRV_ENOENT 0x217
9470 test_69() {
9471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9472         remote_ost_nodsh && skip "remote OST with nodsh"
9473
9474         f="$DIR/$tfile"
9475         $LFS setstripe -c 1 -i 0 $f
9476
9477         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9478
9479         do_facet ost1 lctl set_param fail_loc=0x217
9480         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9481         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9482
9483         do_facet ost1 lctl set_param fail_loc=0
9484         $DIRECTIO write $f 0 2 || error "write error"
9485
9486         cancel_lru_locks osc
9487         $DIRECTIO read $f 0 1 || error "read error"
9488
9489         do_facet ost1 lctl set_param fail_loc=0x217
9490         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9491
9492         do_facet ost1 lctl set_param fail_loc=0
9493         rm -f $f
9494 }
9495 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9496
9497 test_71() {
9498         test_mkdir $DIR/$tdir
9499         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9500         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9501 }
9502 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9503
9504 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9506         [ "$RUNAS_ID" = "$UID" ] &&
9507                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9508         # Check that testing environment is properly set up. Skip if not
9509         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9510                 skip_env "User $RUNAS_ID does not exist - skipping"
9511
9512         touch $DIR/$tfile
9513         chmod 777 $DIR/$tfile
9514         chmod ug+s $DIR/$tfile
9515         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9516                 error "$RUNAS dd $DIR/$tfile failed"
9517         # See if we are still setuid/sgid
9518         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9519                 error "S/gid is not dropped on write"
9520         # Now test that MDS is updated too
9521         cancel_lru_locks mdc
9522         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9523                 error "S/gid is not dropped on MDS"
9524         rm -f $DIR/$tfile
9525 }
9526 run_test 72a "Test that remove suid works properly (bug5695) ===="
9527
9528 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9529         local perm
9530
9531         [ "$RUNAS_ID" = "$UID" ] &&
9532                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9533         [ "$RUNAS_ID" -eq 0 ] &&
9534                 skip_env "RUNAS_ID = 0 -- skipping"
9535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9536         # Check that testing environment is properly set up. Skip if not
9537         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9538                 skip_env "User $RUNAS_ID does not exist - skipping"
9539
9540         touch $DIR/${tfile}-f{g,u}
9541         test_mkdir $DIR/${tfile}-dg
9542         test_mkdir $DIR/${tfile}-du
9543         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9544         chmod g+s $DIR/${tfile}-{f,d}g
9545         chmod u+s $DIR/${tfile}-{f,d}u
9546         for perm in 777 2777 4777; do
9547                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9548                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9549                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9550                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9551         done
9552         true
9553 }
9554 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9555
9556 # bug 3462 - multiple simultaneous MDC requests
9557 test_73() {
9558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9559
9560         test_mkdir $DIR/d73-1
9561         test_mkdir $DIR/d73-2
9562         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9563         pid1=$!
9564
9565         lctl set_param fail_loc=0x80000129
9566         $MULTIOP $DIR/d73-1/f73-2 Oc &
9567         sleep 1
9568         lctl set_param fail_loc=0
9569
9570         $MULTIOP $DIR/d73-2/f73-3 Oc &
9571         pid3=$!
9572
9573         kill -USR1 $pid1
9574         wait $pid1 || return 1
9575
9576         sleep 25
9577
9578         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9579         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9580         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9581
9582         rm -rf $DIR/d73-*
9583 }
9584 run_test 73 "multiple MDC requests (should not deadlock)"
9585
9586 test_74a() { # bug 6149, 6184
9587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9588
9589         touch $DIR/f74a
9590         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9591         #
9592         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9593         # will spin in a tight reconnection loop
9594         $LCTL set_param fail_loc=0x8000030e
9595         # get any lock that won't be difficult - lookup works.
9596         ls $DIR/f74a
9597         $LCTL set_param fail_loc=0
9598         rm -f $DIR/f74a
9599         true
9600 }
9601 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9602
9603 test_74b() { # bug 13310
9604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9605
9606         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9607         #
9608         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9609         # will spin in a tight reconnection loop
9610         $LCTL set_param fail_loc=0x8000030e
9611         # get a "difficult" lock
9612         touch $DIR/f74b
9613         $LCTL set_param fail_loc=0
9614         rm -f $DIR/f74b
9615         true
9616 }
9617 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9618
9619 test_74c() {
9620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9621
9622         #define OBD_FAIL_LDLM_NEW_LOCK
9623         $LCTL set_param fail_loc=0x319
9624         touch $DIR/$tfile && error "touch successful"
9625         $LCTL set_param fail_loc=0
9626         true
9627 }
9628 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9629
9630 slab_lic=/sys/kernel/slab/lustre_inode_cache
9631 num_objects() {
9632         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9633         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9634                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9635 }
9636
9637 test_76a() { # Now for b=20433, added originally in b=1443
9638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9639
9640         cancel_lru_locks osc
9641         # there may be some slab objects cached per core
9642         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9643         local before=$(num_objects)
9644         local count=$((512 * cpus))
9645         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9646         local margin=$((count / 10))
9647         if [[ -f $slab_lic/aliases ]]; then
9648                 local aliases=$(cat $slab_lic/aliases)
9649                 (( aliases > 0 )) && margin=$((margin * aliases))
9650         fi
9651
9652         echo "before slab objects: $before"
9653         for i in $(seq $count); do
9654                 touch $DIR/$tfile
9655                 rm -f $DIR/$tfile
9656         done
9657         cancel_lru_locks osc
9658         local after=$(num_objects)
9659         echo "created: $count, after slab objects: $after"
9660         # shared slab counts are not very accurate, allow significant margin
9661         # the main goal is that the cache growth is not permanently > $count
9662         while (( after > before + margin )); do
9663                 sleep 1
9664                 after=$(num_objects)
9665                 wait=$((wait + 1))
9666                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9667                 if (( wait > 60 )); then
9668                         error "inode slab grew from $before+$margin to $after"
9669                 fi
9670         done
9671 }
9672 run_test 76a "confirm clients recycle inodes properly ===="
9673
9674 test_76b() {
9675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9676         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9677
9678         local count=512
9679         local before=$(num_objects)
9680
9681         for i in $(seq $count); do
9682                 mkdir $DIR/$tdir
9683                 rmdir $DIR/$tdir
9684         done
9685
9686         local after=$(num_objects)
9687         local wait=0
9688
9689         while (( after > before )); do
9690                 sleep 1
9691                 after=$(num_objects)
9692                 wait=$((wait + 1))
9693                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9694                 if (( wait > 60 )); then
9695                         error "inode slab grew from $before to $after"
9696                 fi
9697         done
9698
9699         echo "slab objects before: $before, after: $after"
9700 }
9701 run_test 76b "confirm clients recycle directory inodes properly ===="
9702
9703 export ORIG_CSUM=""
9704 set_checksums()
9705 {
9706         # Note: in sptlrpc modes which enable its own bulk checksum, the
9707         # original crc32_le bulk checksum will be automatically disabled,
9708         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9709         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9710         # In this case set_checksums() will not be no-op, because sptlrpc
9711         # bulk checksum will be enabled all through the test.
9712
9713         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9714         lctl set_param -n osc.*.checksums $1
9715         return 0
9716 }
9717
9718 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9719                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9720 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9721                              tr -d [] | head -n1)}
9722 set_checksum_type()
9723 {
9724         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9725         rc=$?
9726         log "set checksum type to $1, rc = $rc"
9727         return $rc
9728 }
9729
9730 get_osc_checksum_type()
9731 {
9732         # arugment 1: OST name, like OST0000
9733         ost=$1
9734         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9735                         sed 's/.*\[\(.*\)\].*/\1/g')
9736         rc=$?
9737         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9738         echo $checksum_type
9739 }
9740
9741 F77_TMP=$TMP/f77-temp
9742 F77SZ=8
9743 setup_f77() {
9744         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9745                 error "error writing to $F77_TMP"
9746 }
9747
9748 test_77a() { # bug 10889
9749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9750         $GSS && skip_env "could not run with gss"
9751
9752         [ ! -f $F77_TMP ] && setup_f77
9753         set_checksums 1
9754         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9755         set_checksums 0
9756         rm -f $DIR/$tfile
9757 }
9758 run_test 77a "normal checksum read/write operation"
9759
9760 test_77b() { # bug 10889
9761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9762         $GSS && skip_env "could not run with gss"
9763
9764         [ ! -f $F77_TMP ] && setup_f77
9765         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9766         $LCTL set_param fail_loc=0x80000409
9767         set_checksums 1
9768
9769         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9770                 error "dd error: $?"
9771         $LCTL set_param fail_loc=0
9772
9773         for algo in $CKSUM_TYPES; do
9774                 cancel_lru_locks osc
9775                 set_checksum_type $algo
9776                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9777                 $LCTL set_param fail_loc=0x80000408
9778                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9779                 $LCTL set_param fail_loc=0
9780         done
9781         set_checksums 0
9782         set_checksum_type $ORIG_CSUM_TYPE
9783         rm -f $DIR/$tfile
9784 }
9785 run_test 77b "checksum error on client write, read"
9786
9787 cleanup_77c() {
9788         trap 0
9789         set_checksums 0
9790         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9791         $check_ost &&
9792                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9793         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9794         $check_ost && [ -n "$ost_file_prefix" ] &&
9795                 do_facet ost1 rm -f ${ost_file_prefix}\*
9796 }
9797
9798 test_77c() {
9799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9800         $GSS && skip_env "could not run with gss"
9801         remote_ost_nodsh && skip "remote OST with nodsh"
9802
9803         local bad1
9804         local osc_file_prefix
9805         local osc_file
9806         local check_ost=false
9807         local ost_file_prefix
9808         local ost_file
9809         local orig_cksum
9810         local dump_cksum
9811         local fid
9812
9813         # ensure corruption will occur on first OSS/OST
9814         $LFS setstripe -i 0 $DIR/$tfile
9815
9816         [ ! -f $F77_TMP ] && setup_f77
9817         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9818                 error "dd write error: $?"
9819         fid=$($LFS path2fid $DIR/$tfile)
9820
9821         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9822         then
9823                 check_ost=true
9824                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9825                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9826         else
9827                 echo "OSS do not support bulk pages dump upon error"
9828         fi
9829
9830         osc_file_prefix=$($LCTL get_param -n debug_path)
9831         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9832
9833         trap cleanup_77c EXIT
9834
9835         set_checksums 1
9836         # enable bulk pages dump upon error on Client
9837         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9838         # enable bulk pages dump upon error on OSS
9839         $check_ost &&
9840                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9841
9842         # flush Client cache to allow next read to reach OSS
9843         cancel_lru_locks osc
9844
9845         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9846         $LCTL set_param fail_loc=0x80000408
9847         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9848         $LCTL set_param fail_loc=0
9849
9850         rm -f $DIR/$tfile
9851
9852         # check cksum dump on Client
9853         osc_file=$(ls ${osc_file_prefix}*)
9854         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9855         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9856         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9857         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9858         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9859                      cksum)
9860         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9861         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9862                 error "dump content does not match on Client"
9863
9864         $check_ost || skip "No need to check cksum dump on OSS"
9865
9866         # check cksum dump on OSS
9867         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9868         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9869         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9870         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9871         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9872                 error "dump content does not match on OSS"
9873
9874         cleanup_77c
9875 }
9876 run_test 77c "checksum error on client read with debug"
9877
9878 test_77d() { # bug 10889
9879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9880         $GSS && skip_env "could not run with gss"
9881
9882         stack_trap "rm -f $DIR/$tfile"
9883         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9884         $LCTL set_param fail_loc=0x80000409
9885         set_checksums 1
9886         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9887                 error "direct write: rc=$?"
9888         $LCTL set_param fail_loc=0
9889         set_checksums 0
9890
9891         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9892         $LCTL set_param fail_loc=0x80000408
9893         set_checksums 1
9894         cancel_lru_locks osc
9895         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9896                 error "direct read: rc=$?"
9897         $LCTL set_param fail_loc=0
9898         set_checksums 0
9899 }
9900 run_test 77d "checksum error on OST direct write, read"
9901
9902 test_77f() { # bug 10889
9903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9904         $GSS && skip_env "could not run with gss"
9905
9906         set_checksums 1
9907         stack_trap "rm -f $DIR/$tfile"
9908         for algo in $CKSUM_TYPES; do
9909                 cancel_lru_locks osc
9910                 set_checksum_type $algo
9911                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9912                 $LCTL set_param fail_loc=0x409
9913                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9914                         error "direct write succeeded"
9915                 $LCTL set_param fail_loc=0
9916         done
9917         set_checksum_type $ORIG_CSUM_TYPE
9918         set_checksums 0
9919 }
9920 run_test 77f "repeat checksum error on write (expect error)"
9921
9922 test_77g() { # bug 10889
9923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9924         $GSS && skip_env "could not run with gss"
9925         remote_ost_nodsh && skip "remote OST with nodsh"
9926
9927         [ ! -f $F77_TMP ] && setup_f77
9928
9929         local file=$DIR/$tfile
9930         stack_trap "rm -f $file" EXIT
9931
9932         $LFS setstripe -c 1 -i 0 $file
9933         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9934         do_facet ost1 lctl set_param fail_loc=0x8000021a
9935         set_checksums 1
9936         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9937                 error "write error: rc=$?"
9938         do_facet ost1 lctl set_param fail_loc=0
9939         set_checksums 0
9940
9941         cancel_lru_locks osc
9942         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9943         do_facet ost1 lctl set_param fail_loc=0x8000021b
9944         set_checksums 1
9945         cmp $F77_TMP $file || error "file compare failed"
9946         do_facet ost1 lctl set_param fail_loc=0
9947         set_checksums 0
9948 }
9949 run_test 77g "checksum error on OST write, read"
9950
9951 test_77k() { # LU-10906
9952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9953         $GSS && skip_env "could not run with gss"
9954
9955         local cksum_param="osc.$FSNAME*.checksums"
9956         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9957         local checksum
9958         local i
9959
9960         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9961         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9962         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9963
9964         for i in 0 1; do
9965                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9966                         error "failed to set checksum=$i on MGS"
9967                 wait_update $HOSTNAME "$get_checksum" $i
9968                 #remount
9969                 echo "remount client, checksum should be $i"
9970                 remount_client $MOUNT || error "failed to remount client"
9971                 checksum=$(eval $get_checksum)
9972                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9973         done
9974         # remove persistent param to avoid races with checksum mountopt below
9975         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9976                 error "failed to delete checksum on MGS"
9977
9978         for opt in "checksum" "nochecksum"; do
9979                 #remount with mount option
9980                 echo "remount client with option $opt, checksum should be $i"
9981                 umount_client $MOUNT || error "failed to umount client"
9982                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9983                         error "failed to mount client with option '$opt'"
9984                 checksum=$(eval $get_checksum)
9985                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9986                 i=$((i - 1))
9987         done
9988
9989         remount_client $MOUNT || error "failed to remount client"
9990 }
9991 run_test 77k "enable/disable checksum correctly"
9992
9993 test_77l() {
9994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9995         $GSS && skip_env "could not run with gss"
9996
9997         set_checksums 1
9998         stack_trap "set_checksums $ORIG_CSUM" EXIT
9999         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10000
10001         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10002
10003         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10004         for algo in $CKSUM_TYPES; do
10005                 set_checksum_type $algo || error "fail to set checksum type $algo"
10006                 osc_algo=$(get_osc_checksum_type OST0000)
10007                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10008
10009                 # no locks, no reqs to let the connection idle
10010                 cancel_lru_locks osc
10011                 lru_resize_disable osc
10012                 wait_osc_import_state client ost1 IDLE
10013
10014                 # ensure ost1 is connected
10015                 stat $DIR/$tfile >/dev/null || error "can't stat"
10016                 wait_osc_import_state client ost1 FULL
10017
10018                 osc_algo=$(get_osc_checksum_type OST0000)
10019                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10020         done
10021         return 0
10022 }
10023 run_test 77l "preferred checksum type is remembered after reconnected"
10024
10025 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10026 rm -f $F77_TMP
10027 unset F77_TMP
10028
10029 test_77m() {
10030         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10031                 skip "Need at least version 2.14.52"
10032         local param=checksum_speed
10033
10034         $LCTL get_param $param || error "reading $param failed"
10035
10036         csum_speeds=$($LCTL get_param -n $param)
10037
10038         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10039                 error "known checksum types are missing"
10040 }
10041 run_test 77m "Verify checksum_speed is correctly read"
10042
10043 check_filefrag_77n() {
10044         local nr_ext=0
10045         local starts=()
10046         local ends=()
10047
10048         while read extidx a b start end rest; do
10049                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10050                         nr_ext=$(( $nr_ext + 1 ))
10051                         starts+=( ${start%..} )
10052                         ends+=( ${end%:} )
10053                 fi
10054         done < <( filefrag -sv $1 )
10055
10056         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10057         return 1
10058 }
10059
10060 test_77n() {
10061         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10062
10063         touch $DIR/$tfile
10064         $TRUNCATE $DIR/$tfile 0
10065         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10066         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10067         check_filefrag_77n $DIR/$tfile ||
10068                 skip "$tfile blocks not contiguous around hole"
10069
10070         set_checksums 1
10071         stack_trap "set_checksums $ORIG_CSUM" EXIT
10072         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10073         stack_trap "rm -f $DIR/$tfile"
10074
10075         for algo in $CKSUM_TYPES; do
10076                 if [[ "$algo" =~ ^t10 ]]; then
10077                         set_checksum_type $algo ||
10078                                 error "fail to set checksum type $algo"
10079                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10080                                 error "fail to read $tfile with $algo"
10081                 fi
10082         done
10083         rm -f $DIR/$tfile
10084         return 0
10085 }
10086 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10087
10088 test_77o() {
10089         (( $CLIENT_VERSION >= $(version_code 2.14.54) )) ||
10090                 skip "Need at least version 2.14.54"
10091         local ofd=obdfilter
10092         local mdt=mdt
10093
10094         # print OST checksum_type
10095         echo "$ofd.$FSNAME-*.checksum_type:"
10096         do_nodes $(comma_list $(osts_nodes)) \
10097                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10098
10099         # print MDT checksum_type
10100         echo "$mdt.$FSNAME-*.checksum_type:"
10101         do_nodes $(comma_list $(mdts_nodes)) \
10102                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10103
10104         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10105                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10106
10107         (( $o_count == $OSTCOUNT )) ||
10108                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10109
10110         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10111                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10112
10113         (( $m_count == $MDSCOUNT )) ||
10114                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10115 }
10116 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10117
10118 cleanup_test_78() {
10119         trap 0
10120         rm -f $DIR/$tfile
10121 }
10122
10123 test_78() { # bug 10901
10124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10125         remote_ost || skip_env "local OST"
10126
10127         NSEQ=5
10128         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10129         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10130         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10131         echo "MemTotal: $MEMTOTAL"
10132
10133         # reserve 256MB of memory for the kernel and other running processes,
10134         # and then take 1/2 of the remaining memory for the read/write buffers.
10135         if [ $MEMTOTAL -gt 512 ] ;then
10136                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10137         else
10138                 # for those poor memory-starved high-end clusters...
10139                 MEMTOTAL=$((MEMTOTAL / 2))
10140         fi
10141         echo "Mem to use for directio: $MEMTOTAL"
10142
10143         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10144         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10145         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10146         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10147                 head -n1)
10148         echo "Smallest OST: $SMALLESTOST"
10149         [[ $SMALLESTOST -lt 10240 ]] &&
10150                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10151
10152         trap cleanup_test_78 EXIT
10153
10154         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10155                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10156
10157         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10158         echo "File size: $F78SIZE"
10159         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10160         for i in $(seq 1 $NSEQ); do
10161                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10162                 echo directIO rdwr round $i of $NSEQ
10163                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10164         done
10165
10166         cleanup_test_78
10167 }
10168 run_test 78 "handle large O_DIRECT writes correctly ============"
10169
10170 test_79() { # bug 12743
10171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10172
10173         wait_delete_completed
10174
10175         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10176         BKFREE=$(calc_osc_kbytes kbytesfree)
10177         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10178
10179         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10180         DFTOTAL=`echo $STRING | cut -d, -f1`
10181         DFUSED=`echo $STRING  | cut -d, -f2`
10182         DFAVAIL=`echo $STRING | cut -d, -f3`
10183         DFFREE=$(($DFTOTAL - $DFUSED))
10184
10185         ALLOWANCE=$((64 * $OSTCOUNT))
10186
10187         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10188            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10189                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10190         fi
10191         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10192            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10193                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10194         fi
10195         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10196            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10197                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10198         fi
10199 }
10200 run_test 79 "df report consistency check ======================="
10201
10202 test_80() { # bug 10718
10203         remote_ost_nodsh && skip "remote OST with nodsh"
10204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10205
10206         # relax strong synchronous semantics for slow backends like ZFS
10207         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10208                 local soc="obdfilter.*.sync_lock_cancel"
10209                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10210
10211                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10212                 if [ -z "$save" ]; then
10213                         soc="obdfilter.*.sync_on_lock_cancel"
10214                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10215                 fi
10216
10217                 if [ "$save" != "never" ]; then
10218                         local hosts=$(comma_list $(osts_nodes))
10219
10220                         do_nodes $hosts $LCTL set_param $soc=never
10221                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10222                 fi
10223         fi
10224
10225         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10226         sync; sleep 1; sync
10227         local before=$(date +%s)
10228         cancel_lru_locks osc
10229         local after=$(date +%s)
10230         local diff=$((after - before))
10231         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10232
10233         rm -f $DIR/$tfile
10234 }
10235 run_test 80 "Page eviction is equally fast at high offsets too"
10236
10237 test_81a() { # LU-456
10238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10239         remote_ost_nodsh && skip "remote OST with nodsh"
10240
10241         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10242         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10243         do_facet ost1 lctl set_param fail_loc=0x80000228
10244
10245         # write should trigger a retry and success
10246         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10247         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10248         RC=$?
10249         if [ $RC -ne 0 ] ; then
10250                 error "write should success, but failed for $RC"
10251         fi
10252 }
10253 run_test 81a "OST should retry write when get -ENOSPC ==============="
10254
10255 test_81b() { # LU-456
10256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10257         remote_ost_nodsh && skip "remote OST with nodsh"
10258
10259         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10260         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10261         do_facet ost1 lctl set_param fail_loc=0x228
10262
10263         # write should retry several times and return -ENOSPC finally
10264         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10265         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10266         RC=$?
10267         ENOSPC=28
10268         if [ $RC -ne $ENOSPC ] ; then
10269                 error "dd should fail for -ENOSPC, but succeed."
10270         fi
10271 }
10272 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10273
10274 test_99() {
10275         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10276
10277         test_mkdir $DIR/$tdir.cvsroot
10278         chown $RUNAS_ID $DIR/$tdir.cvsroot
10279
10280         cd $TMP
10281         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10282
10283         cd /etc/init.d
10284         # some versions of cvs import exit(1) when asked to import links or
10285         # files they can't read.  ignore those files.
10286         local toignore=$(find . -type l -printf '-I %f\n' -o \
10287                          ! -perm /4 -printf '-I %f\n')
10288         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10289                 $tdir.reposname vtag rtag
10290
10291         cd $DIR
10292         test_mkdir $DIR/$tdir.reposname
10293         chown $RUNAS_ID $DIR/$tdir.reposname
10294         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10295
10296         cd $DIR/$tdir.reposname
10297         $RUNAS touch foo99
10298         $RUNAS cvs add -m 'addmsg' foo99
10299         $RUNAS cvs update
10300         $RUNAS cvs commit -m 'nomsg' foo99
10301         rm -fr $DIR/$tdir.cvsroot
10302 }
10303 run_test 99 "cvs strange file/directory operations"
10304
10305 test_100() {
10306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10307         [[ "$NETTYPE" =~ tcp ]] ||
10308                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10309         remote_ost_nodsh && skip "remote OST with nodsh"
10310         remote_mds_nodsh && skip "remote MDS with nodsh"
10311         remote_servers ||
10312                 skip "useless for local single node setup"
10313
10314         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10315                 [ "$PROT" != "tcp" ] && continue
10316                 RPORT=$(echo $REMOTE | cut -d: -f2)
10317                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10318
10319                 rc=0
10320                 LPORT=`echo $LOCAL | cut -d: -f2`
10321                 if [ $LPORT -ge 1024 ]; then
10322                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10323                         netstat -tna
10324                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10325                 fi
10326         done
10327         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10328 }
10329 run_test 100 "check local port using privileged port ==========="
10330
10331 function get_named_value()
10332 {
10333     local tag=$1
10334
10335     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10336 }
10337
10338 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10339                    awk '/^max_cached_mb/ { print $2 }')
10340
10341 cleanup_101a() {
10342         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10343         trap 0
10344 }
10345
10346 test_101a() {
10347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10348
10349         local s
10350         local discard
10351         local nreads=10000
10352         local cache_limit=32
10353
10354         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10355         trap cleanup_101a EXIT
10356         $LCTL set_param -n llite.*.read_ahead_stats=0
10357         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10358
10359         #
10360         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10361         #
10362         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10363         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10364
10365         discard=0
10366         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10367                    get_named_value 'read.but.discarded'); do
10368                         discard=$(($discard + $s))
10369         done
10370         cleanup_101a
10371
10372         $LCTL get_param osc.*-osc*.rpc_stats
10373         $LCTL get_param llite.*.read_ahead_stats
10374
10375         # Discard is generally zero, but sometimes a few random reads line up
10376         # and trigger larger readahead, which is wasted & leads to discards.
10377         if [[ $(($discard)) -gt $nreads ]]; then
10378                 error "too many ($discard) discarded pages"
10379         fi
10380         rm -f $DIR/$tfile || true
10381 }
10382 run_test 101a "check read-ahead for random reads"
10383
10384 setup_test101bc() {
10385         test_mkdir $DIR/$tdir
10386         local ssize=$1
10387         local FILE_LENGTH=$2
10388         STRIPE_OFFSET=0
10389
10390         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10391
10392         local list=$(comma_list $(osts_nodes))
10393         set_osd_param $list '' read_cache_enable 0
10394         set_osd_param $list '' writethrough_cache_enable 0
10395
10396         trap cleanup_test101bc EXIT
10397         # prepare the read-ahead file
10398         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10399
10400         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10401                                 count=$FILE_SIZE_MB 2> /dev/null
10402
10403 }
10404
10405 cleanup_test101bc() {
10406         trap 0
10407         rm -rf $DIR/$tdir
10408         rm -f $DIR/$tfile
10409
10410         local list=$(comma_list $(osts_nodes))
10411         set_osd_param $list '' read_cache_enable 1
10412         set_osd_param $list '' writethrough_cache_enable 1
10413 }
10414
10415 calc_total() {
10416         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10417 }
10418
10419 ra_check_101() {
10420         local READ_SIZE=$1
10421         local STRIPE_SIZE=$2
10422         local FILE_LENGTH=$3
10423         local RA_INC=1048576
10424         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10425         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10426                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10427         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10428                   get_named_value 'read.but.discarded' | calc_total)
10429         if [[ $DISCARD -gt $discard_limit ]]; then
10430                 $LCTL get_param llite.*.read_ahead_stats
10431                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10432         else
10433                 echo "Read-ahead success for size ${READ_SIZE}"
10434         fi
10435 }
10436
10437 test_101b() {
10438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10439         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10440
10441         local STRIPE_SIZE=1048576
10442         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10443
10444         if [ $SLOW == "yes" ]; then
10445                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10446         else
10447                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10448         fi
10449
10450         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10451
10452         # prepare the read-ahead file
10453         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10454         cancel_lru_locks osc
10455         for BIDX in 2 4 8 16 32 64 128 256
10456         do
10457                 local BSIZE=$((BIDX*4096))
10458                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10459                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10460                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10461                 $LCTL set_param -n llite.*.read_ahead_stats=0
10462                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10463                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10464                 cancel_lru_locks osc
10465                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10466         done
10467         cleanup_test101bc
10468         true
10469 }
10470 run_test 101b "check stride-io mode read-ahead ================="
10471
10472 test_101c() {
10473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10474
10475         local STRIPE_SIZE=1048576
10476         local FILE_LENGTH=$((STRIPE_SIZE*100))
10477         local nreads=10000
10478         local rsize=65536
10479         local osc_rpc_stats
10480
10481         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10482
10483         cancel_lru_locks osc
10484         $LCTL set_param osc.*.rpc_stats=0
10485         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10486         $LCTL get_param osc.*.rpc_stats
10487         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10488                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10489                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10490                 local size
10491
10492                 if [ $lines -le 20 ]; then
10493                         echo "continue debug"
10494                         continue
10495                 fi
10496                 for size in 1 2 4 8; do
10497                         local rpc=$(echo "$stats" |
10498                                     awk '($1 == "'$size':") {print $2; exit; }')
10499                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10500                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10501                 done
10502                 echo "$osc_rpc_stats check passed!"
10503         done
10504         cleanup_test101bc
10505         true
10506 }
10507 run_test 101c "check stripe_size aligned read-ahead"
10508
10509 test_101d() {
10510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10511
10512         local file=$DIR/$tfile
10513         local sz_MB=${FILESIZE_101d:-80}
10514         local ra_MB=${READAHEAD_MB:-40}
10515
10516         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10517         [ $free_MB -lt $sz_MB ] &&
10518                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10519
10520         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10521         $LFS setstripe -c -1 $file || error "setstripe failed"
10522
10523         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10524         echo Cancel LRU locks on lustre client to flush the client cache
10525         cancel_lru_locks osc
10526
10527         echo Disable read-ahead
10528         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10529         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10530         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10531         $LCTL get_param -n llite.*.max_read_ahead_mb
10532
10533         echo "Reading the test file $file with read-ahead disabled"
10534         local sz_KB=$((sz_MB * 1024 / 4))
10535         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10536         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10537         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10538                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10539
10540         echo "Cancel LRU locks on lustre client to flush the client cache"
10541         cancel_lru_locks osc
10542         echo Enable read-ahead with ${ra_MB}MB
10543         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10544
10545         echo "Reading the test file $file with read-ahead enabled"
10546         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10547                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10548
10549         echo "read-ahead disabled time read $raOFF"
10550         echo "read-ahead enabled time read $raON"
10551
10552         rm -f $file
10553         wait_delete_completed
10554
10555         # use awk for this check instead of bash because it handles decimals
10556         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10557                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10558 }
10559 run_test 101d "file read with and without read-ahead enabled"
10560
10561 test_101e() {
10562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10563
10564         local file=$DIR/$tfile
10565         local size_KB=500  #KB
10566         local count=100
10567         local bsize=1024
10568
10569         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10570         local need_KB=$((count * size_KB))
10571         [[ $free_KB -le $need_KB ]] &&
10572                 skip_env "Need free space $need_KB, have $free_KB"
10573
10574         echo "Creating $count ${size_KB}K test files"
10575         for ((i = 0; i < $count; i++)); do
10576                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10577         done
10578
10579         echo "Cancel LRU locks on lustre client to flush the client cache"
10580         cancel_lru_locks $OSC
10581
10582         echo "Reset readahead stats"
10583         $LCTL set_param -n llite.*.read_ahead_stats=0
10584
10585         for ((i = 0; i < $count; i++)); do
10586                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10587         done
10588
10589         $LCTL get_param llite.*.max_cached_mb
10590         $LCTL get_param llite.*.read_ahead_stats
10591         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10592                      get_named_value 'misses' | calc_total)
10593
10594         for ((i = 0; i < $count; i++)); do
10595                 rm -rf $file.$i 2>/dev/null
10596         done
10597
10598         #10000 means 20% reads are missing in readahead
10599         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10600 }
10601 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10602
10603 test_101f() {
10604         which iozone || skip_env "no iozone installed"
10605
10606         local old_debug=$($LCTL get_param debug)
10607         old_debug=${old_debug#*=}
10608         $LCTL set_param debug="reada mmap"
10609
10610         # create a test file
10611         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10612
10613         echo Cancel LRU locks on lustre client to flush the client cache
10614         cancel_lru_locks osc
10615
10616         echo Reset readahead stats
10617         $LCTL set_param -n llite.*.read_ahead_stats=0
10618
10619         echo mmap read the file with small block size
10620         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10621                 > /dev/null 2>&1
10622
10623         echo checking missing pages
10624         $LCTL get_param llite.*.read_ahead_stats
10625         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10626                         get_named_value 'misses' | calc_total)
10627
10628         $LCTL set_param debug="$old_debug"
10629         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10630         rm -f $DIR/$tfile
10631 }
10632 run_test 101f "check mmap read performance"
10633
10634 test_101g_brw_size_test() {
10635         local mb=$1
10636         local pages=$((mb * 1048576 / PAGE_SIZE))
10637         local file=$DIR/$tfile
10638
10639         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10640                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10641         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10642                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10643                         return 2
10644         done
10645
10646         stack_trap "rm -f $file" EXIT
10647         $LCTL set_param -n osc.*.rpc_stats=0
10648
10649         # 10 RPCs should be enough for the test
10650         local count=10
10651         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10652                 { error "dd write ${mb} MB blocks failed"; return 3; }
10653         cancel_lru_locks osc
10654         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10655                 { error "dd write ${mb} MB blocks failed"; return 4; }
10656
10657         # calculate number of full-sized read and write RPCs
10658         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10659                 sed -n '/pages per rpc/,/^$/p' |
10660                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10661                 END { print reads,writes }'))
10662         # allow one extra full-sized read RPC for async readahead
10663         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10664                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10665         [[ ${rpcs[1]} == $count ]] ||
10666                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10667 }
10668
10669 test_101g() {
10670         remote_ost_nodsh && skip "remote OST with nodsh"
10671
10672         local rpcs
10673         local osts=$(get_facets OST)
10674         local list=$(comma_list $(osts_nodes))
10675         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10676         local brw_size="obdfilter.*.brw_size"
10677
10678         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10679
10680         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10681
10682         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10683                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10684                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10685            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10686                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10687                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10688
10689                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10690                         suffix="M"
10691
10692                 if [[ $orig_mb -lt 16 ]]; then
10693                         save_lustre_params $osts "$brw_size" > $p
10694                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10695                                 error "set 16MB RPC size failed"
10696
10697                         echo "remount client to enable new RPC size"
10698                         remount_client $MOUNT || error "remount_client failed"
10699                 fi
10700
10701                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10702                 # should be able to set brw_size=12, but no rpc_stats for that
10703                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10704         fi
10705
10706         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10707
10708         if [[ $orig_mb -lt 16 ]]; then
10709                 restore_lustre_params < $p
10710                 remount_client $MOUNT || error "remount_client restore failed"
10711         fi
10712
10713         rm -f $p $DIR/$tfile
10714 }
10715 run_test 101g "Big bulk(4/16 MiB) readahead"
10716
10717 test_101h() {
10718         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10719
10720         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10721                 error "dd 70M file failed"
10722         echo Cancel LRU locks on lustre client to flush the client cache
10723         cancel_lru_locks osc
10724
10725         echo "Reset readahead stats"
10726         $LCTL set_param -n llite.*.read_ahead_stats 0
10727
10728         echo "Read 10M of data but cross 64M bundary"
10729         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10730         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10731                      get_named_value 'misses' | calc_total)
10732         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10733         rm -f $p $DIR/$tfile
10734 }
10735 run_test 101h "Readahead should cover current read window"
10736
10737 test_101i() {
10738         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10739                 error "dd 10M file failed"
10740
10741         local max_per_file_mb=$($LCTL get_param -n \
10742                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10743         cancel_lru_locks osc
10744         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10745         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10746                 error "set max_read_ahead_per_file_mb to 1 failed"
10747
10748         echo "Reset readahead stats"
10749         $LCTL set_param llite.*.read_ahead_stats=0
10750
10751         dd if=$DIR/$tfile of=/dev/null bs=2M
10752
10753         $LCTL get_param llite.*.read_ahead_stats
10754         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10755                      awk '/misses/ { print $2 }')
10756         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10757         rm -f $DIR/$tfile
10758 }
10759 run_test 101i "allow current readahead to exceed reservation"
10760
10761 test_101j() {
10762         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10763                 error "setstripe $DIR/$tfile failed"
10764         local file_size=$((1048576 * 16))
10765         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10766         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10767
10768         echo Disable read-ahead
10769         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10770
10771         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10772         for blk in $PAGE_SIZE 1048576 $file_size; do
10773                 cancel_lru_locks osc
10774                 echo "Reset readahead stats"
10775                 $LCTL set_param -n llite.*.read_ahead_stats=0
10776                 local count=$(($file_size / $blk))
10777                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10778                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10779                              get_named_value 'failed.to.fast.read' | calc_total)
10780                 $LCTL get_param -n llite.*.read_ahead_stats
10781                 [ $miss -eq $count ] || error "expected $count got $miss"
10782         done
10783
10784         rm -f $p $DIR/$tfile
10785 }
10786 run_test 101j "A complete read block should be submitted when no RA"
10787
10788 setup_test102() {
10789         test_mkdir $DIR/$tdir
10790         chown $RUNAS_ID $DIR/$tdir
10791         STRIPE_SIZE=65536
10792         STRIPE_OFFSET=1
10793         STRIPE_COUNT=$OSTCOUNT
10794         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10795
10796         trap cleanup_test102 EXIT
10797         cd $DIR
10798         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10799         cd $DIR/$tdir
10800         for num in 1 2 3 4; do
10801                 for count in $(seq 1 $STRIPE_COUNT); do
10802                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10803                                 local size=`expr $STRIPE_SIZE \* $num`
10804                                 local file=file"$num-$idx-$count"
10805                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10806                         done
10807                 done
10808         done
10809
10810         cd $DIR
10811         $1 tar cf $TMP/f102.tar $tdir --xattrs
10812 }
10813
10814 cleanup_test102() {
10815         trap 0
10816         rm -f $TMP/f102.tar
10817         rm -rf $DIR/d0.sanity/d102
10818 }
10819
10820 test_102a() {
10821         [ "$UID" != 0 ] && skip "must run as root"
10822         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10823                 skip_env "must have user_xattr"
10824
10825         [ -z "$(which setfattr 2>/dev/null)" ] &&
10826                 skip_env "could not find setfattr"
10827
10828         local testfile=$DIR/$tfile
10829
10830         touch $testfile
10831         echo "set/get xattr..."
10832         setfattr -n trusted.name1 -v value1 $testfile ||
10833                 error "setfattr -n trusted.name1=value1 $testfile failed"
10834         getfattr -n trusted.name1 $testfile 2> /dev/null |
10835           grep "trusted.name1=.value1" ||
10836                 error "$testfile missing trusted.name1=value1"
10837
10838         setfattr -n user.author1 -v author1 $testfile ||
10839                 error "setfattr -n user.author1=author1 $testfile failed"
10840         getfattr -n user.author1 $testfile 2> /dev/null |
10841           grep "user.author1=.author1" ||
10842                 error "$testfile missing trusted.author1=author1"
10843
10844         echo "listxattr..."
10845         setfattr -n trusted.name2 -v value2 $testfile ||
10846                 error "$testfile unable to set trusted.name2"
10847         setfattr -n trusted.name3 -v value3 $testfile ||
10848                 error "$testfile unable to set trusted.name3"
10849         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10850             grep "trusted.name" | wc -l) -eq 3 ] ||
10851                 error "$testfile missing 3 trusted.name xattrs"
10852
10853         setfattr -n user.author2 -v author2 $testfile ||
10854                 error "$testfile unable to set user.author2"
10855         setfattr -n user.author3 -v author3 $testfile ||
10856                 error "$testfile unable to set user.author3"
10857         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10858             grep "user.author" | wc -l) -eq 3 ] ||
10859                 error "$testfile missing 3 user.author xattrs"
10860
10861         echo "remove xattr..."
10862         setfattr -x trusted.name1 $testfile ||
10863                 error "$testfile error deleting trusted.name1"
10864         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10865                 error "$testfile did not delete trusted.name1 xattr"
10866
10867         setfattr -x user.author1 $testfile ||
10868                 error "$testfile error deleting user.author1"
10869         echo "set lustre special xattr ..."
10870         $LFS setstripe -c1 $testfile
10871         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10872                 awk -F "=" '/trusted.lov/ { print $2 }' )
10873         setfattr -n "trusted.lov" -v $lovea $testfile ||
10874                 error "$testfile doesn't ignore setting trusted.lov again"
10875         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10876                 error "$testfile allow setting invalid trusted.lov"
10877         rm -f $testfile
10878 }
10879 run_test 102a "user xattr test =================================="
10880
10881 check_102b_layout() {
10882         local layout="$*"
10883         local testfile=$DIR/$tfile
10884
10885         echo "test layout '$layout'"
10886         $LFS setstripe $layout $testfile || error "setstripe failed"
10887         $LFS getstripe -y $testfile
10888
10889         echo "get/set/list trusted.lov xattr ..." # b=10930
10890         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10891         [[ "$value" =~ "trusted.lov" ]] ||
10892                 error "can't get trusted.lov from $testfile"
10893         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10894                 error "getstripe failed"
10895
10896         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10897
10898         value=$(cut -d= -f2 <<<$value)
10899         # LU-13168: truncated xattr should fail if short lov_user_md header
10900         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10901                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10902         for len in $lens; do
10903                 echo "setfattr $len $testfile.2"
10904                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10905                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10906         done
10907         local stripe_size=$($LFS getstripe -S $testfile.2)
10908         local stripe_count=$($LFS getstripe -c $testfile.2)
10909         [[ $stripe_size -eq 65536 ]] ||
10910                 error "stripe size $stripe_size != 65536"
10911         [[ $stripe_count -eq $stripe_count_orig ]] ||
10912                 error "stripe count $stripe_count != $stripe_count_orig"
10913         rm $testfile $testfile.2
10914 }
10915
10916 test_102b() {
10917         [ -z "$(which setfattr 2>/dev/null)" ] &&
10918                 skip_env "could not find setfattr"
10919         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10920
10921         # check plain layout
10922         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10923
10924         # and also check composite layout
10925         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10926
10927 }
10928 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10929
10930 test_102c() {
10931         [ -z "$(which setfattr 2>/dev/null)" ] &&
10932                 skip_env "could not find setfattr"
10933         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10934
10935         # b10930: get/set/list lustre.lov xattr
10936         echo "get/set/list lustre.lov xattr ..."
10937         test_mkdir $DIR/$tdir
10938         chown $RUNAS_ID $DIR/$tdir
10939         local testfile=$DIR/$tdir/$tfile
10940         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10941                 error "setstripe failed"
10942         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10943                 error "getstripe failed"
10944         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10945         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10946
10947         local testfile2=${testfile}2
10948         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10949                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10950
10951         $RUNAS $MCREATE $testfile2
10952         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10953         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10954         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10955         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10956         [ $stripe_count -eq $STRIPECOUNT ] ||
10957                 error "stripe count $stripe_count != $STRIPECOUNT"
10958 }
10959 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10960
10961 compare_stripe_info1() {
10962         local stripe_index_all_zero=true
10963
10964         for num in 1 2 3 4; do
10965                 for count in $(seq 1 $STRIPE_COUNT); do
10966                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10967                                 local size=$((STRIPE_SIZE * num))
10968                                 local file=file"$num-$offset-$count"
10969                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10970                                 [[ $stripe_size -ne $size ]] &&
10971                                     error "$file: size $stripe_size != $size"
10972                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10973                                 # allow fewer stripes to be created, ORI-601
10974                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10975                                     error "$file: count $stripe_count != $count"
10976                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10977                                 [[ $stripe_index -ne 0 ]] &&
10978                                         stripe_index_all_zero=false
10979                         done
10980                 done
10981         done
10982         $stripe_index_all_zero &&
10983                 error "all files are being extracted starting from OST index 0"
10984         return 0
10985 }
10986
10987 have_xattrs_include() {
10988         tar --help | grep -q xattrs-include &&
10989                 echo --xattrs-include="lustre.*"
10990 }
10991
10992 test_102d() {
10993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10994         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10995
10996         XINC=$(have_xattrs_include)
10997         setup_test102
10998         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10999         cd $DIR/$tdir/$tdir
11000         compare_stripe_info1
11001 }
11002 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11003
11004 test_102f() {
11005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11006         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11007
11008         XINC=$(have_xattrs_include)
11009         setup_test102
11010         test_mkdir $DIR/$tdir.restore
11011         cd $DIR
11012         tar cf - --xattrs $tdir | tar xf - \
11013                 -C $DIR/$tdir.restore --xattrs $XINC
11014         cd $DIR/$tdir.restore/$tdir
11015         compare_stripe_info1
11016 }
11017 run_test 102f "tar copy files, not keep osts"
11018
11019 grow_xattr() {
11020         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11021                 skip "must have user_xattr"
11022         [ -z "$(which setfattr 2>/dev/null)" ] &&
11023                 skip_env "could not find setfattr"
11024         [ -z "$(which getfattr 2>/dev/null)" ] &&
11025                 skip_env "could not find getfattr"
11026
11027         local xsize=${1:-1024}  # in bytes
11028         local file=$DIR/$tfile
11029         local value="$(generate_string $xsize)"
11030         local xbig=trusted.big
11031         local toobig=$2
11032
11033         touch $file
11034         log "save $xbig on $file"
11035         if [ -z "$toobig" ]
11036         then
11037                 setfattr -n $xbig -v $value $file ||
11038                         error "saving $xbig on $file failed"
11039         else
11040                 setfattr -n $xbig -v $value $file &&
11041                         error "saving $xbig on $file succeeded"
11042                 return 0
11043         fi
11044
11045         local orig=$(get_xattr_value $xbig $file)
11046         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11047
11048         local xsml=trusted.sml
11049         log "save $xsml on $file"
11050         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11051
11052         local new=$(get_xattr_value $xbig $file)
11053         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11054
11055         log "grow $xsml on $file"
11056         setfattr -n $xsml -v "$value" $file ||
11057                 error "growing $xsml on $file failed"
11058
11059         new=$(get_xattr_value $xbig $file)
11060         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11061         log "$xbig still valid after growing $xsml"
11062
11063         rm -f $file
11064 }
11065
11066 test_102h() { # bug 15777
11067         grow_xattr 1024
11068 }
11069 run_test 102h "grow xattr from inside inode to external block"
11070
11071 test_102ha() {
11072         large_xattr_enabled || skip_env "ea_inode feature disabled"
11073
11074         echo "setting xattr of max xattr size: $(max_xattr_size)"
11075         grow_xattr $(max_xattr_size)
11076
11077         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11078         echo "This should fail:"
11079         grow_xattr $(($(max_xattr_size) + 10)) 1
11080 }
11081 run_test 102ha "grow xattr from inside inode to external inode"
11082
11083 test_102i() { # bug 17038
11084         [ -z "$(which getfattr 2>/dev/null)" ] &&
11085                 skip "could not find getfattr"
11086
11087         touch $DIR/$tfile
11088         ln -s $DIR/$tfile $DIR/${tfile}link
11089         getfattr -n trusted.lov $DIR/$tfile ||
11090                 error "lgetxattr on $DIR/$tfile failed"
11091         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11092                 grep -i "no such attr" ||
11093                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11094         rm -f $DIR/$tfile $DIR/${tfile}link
11095 }
11096 run_test 102i "lgetxattr test on symbolic link ============"
11097
11098 test_102j() {
11099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11100         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11101
11102         XINC=$(have_xattrs_include)
11103         setup_test102 "$RUNAS"
11104         chown $RUNAS_ID $DIR/$tdir
11105         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11106         cd $DIR/$tdir/$tdir
11107         compare_stripe_info1 "$RUNAS"
11108 }
11109 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11110
11111 test_102k() {
11112         [ -z "$(which setfattr 2>/dev/null)" ] &&
11113                 skip "could not find setfattr"
11114
11115         touch $DIR/$tfile
11116         # b22187 just check that does not crash for regular file.
11117         setfattr -n trusted.lov $DIR/$tfile
11118         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11119         local test_kdir=$DIR/$tdir
11120         test_mkdir $test_kdir
11121         local default_size=$($LFS getstripe -S $test_kdir)
11122         local default_count=$($LFS getstripe -c $test_kdir)
11123         local default_offset=$($LFS getstripe -i $test_kdir)
11124         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11125                 error 'dir setstripe failed'
11126         setfattr -n trusted.lov $test_kdir
11127         local stripe_size=$($LFS getstripe -S $test_kdir)
11128         local stripe_count=$($LFS getstripe -c $test_kdir)
11129         local stripe_offset=$($LFS getstripe -i $test_kdir)
11130         [ $stripe_size -eq $default_size ] ||
11131                 error "stripe size $stripe_size != $default_size"
11132         [ $stripe_count -eq $default_count ] ||
11133                 error "stripe count $stripe_count != $default_count"
11134         [ $stripe_offset -eq $default_offset ] ||
11135                 error "stripe offset $stripe_offset != $default_offset"
11136         rm -rf $DIR/$tfile $test_kdir
11137 }
11138 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11139
11140 test_102l() {
11141         [ -z "$(which getfattr 2>/dev/null)" ] &&
11142                 skip "could not find getfattr"
11143
11144         # LU-532 trusted. xattr is invisible to non-root
11145         local testfile=$DIR/$tfile
11146
11147         touch $testfile
11148
11149         echo "listxattr as user..."
11150         chown $RUNAS_ID $testfile
11151         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11152             grep -q "trusted" &&
11153                 error "$testfile trusted xattrs are user visible"
11154
11155         return 0;
11156 }
11157 run_test 102l "listxattr size test =================================="
11158
11159 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11160         local path=$DIR/$tfile
11161         touch $path
11162
11163         listxattr_size_check $path || error "listattr_size_check $path failed"
11164 }
11165 run_test 102m "Ensure listxattr fails on small bufffer ========"
11166
11167 cleanup_test102
11168
11169 getxattr() { # getxattr path name
11170         # Return the base64 encoding of the value of xattr name on path.
11171         local path=$1
11172         local name=$2
11173
11174         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11175         # file: $path
11176         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11177         #
11178         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11179
11180         getfattr --absolute-names --encoding=base64 --name=$name $path |
11181                 awk -F= -v name=$name '$1 == name {
11182                         print substr($0, index($0, "=") + 1);
11183         }'
11184 }
11185
11186 test_102n() { # LU-4101 mdt: protect internal xattrs
11187         [ -z "$(which setfattr 2>/dev/null)" ] &&
11188                 skip "could not find setfattr"
11189         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11190         then
11191                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11192         fi
11193
11194         local file0=$DIR/$tfile.0
11195         local file1=$DIR/$tfile.1
11196         local xattr0=$TMP/$tfile.0
11197         local xattr1=$TMP/$tfile.1
11198         local namelist="lov lma lmv link fid version som hsm"
11199         local name
11200         local value
11201
11202         rm -rf $file0 $file1 $xattr0 $xattr1
11203         touch $file0 $file1
11204
11205         # Get 'before' xattrs of $file1.
11206         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11207
11208         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11209                 namelist+=" lfsck_namespace"
11210         for name in $namelist; do
11211                 # Try to copy xattr from $file0 to $file1.
11212                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11213
11214                 setfattr --name=trusted.$name --value="$value" $file1 ||
11215                         error "setxattr 'trusted.$name' failed"
11216
11217                 # Try to set a garbage xattr.
11218                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11219
11220                 if [[ x$name == "xlov" ]]; then
11221                         setfattr --name=trusted.lov --value="$value" $file1 &&
11222                         error "setxattr invalid 'trusted.lov' success"
11223                 else
11224                         setfattr --name=trusted.$name --value="$value" $file1 ||
11225                                 error "setxattr invalid 'trusted.$name' failed"
11226                 fi
11227
11228                 # Try to remove the xattr from $file1. We don't care if this
11229                 # appears to succeed or fail, we just don't want there to be
11230                 # any changes or crashes.
11231                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11232         done
11233
11234         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11235         then
11236                 name="lfsck_ns"
11237                 # Try to copy xattr from $file0 to $file1.
11238                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11239
11240                 setfattr --name=trusted.$name --value="$value" $file1 ||
11241                         error "setxattr 'trusted.$name' failed"
11242
11243                 # Try to set a garbage xattr.
11244                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11245
11246                 setfattr --name=trusted.$name --value="$value" $file1 ||
11247                         error "setxattr 'trusted.$name' failed"
11248
11249                 # Try to remove the xattr from $file1. We don't care if this
11250                 # appears to succeed or fail, we just don't want there to be
11251                 # any changes or crashes.
11252                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11253         fi
11254
11255         # Get 'after' xattrs of file1.
11256         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11257
11258         if ! diff $xattr0 $xattr1; then
11259                 error "before and after xattrs of '$file1' differ"
11260         fi
11261
11262         rm -rf $file0 $file1 $xattr0 $xattr1
11263
11264         return 0
11265 }
11266 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11267
11268 test_102p() { # LU-4703 setxattr did not check ownership
11269         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11270                 skip "MDS needs to be at least 2.5.56"
11271
11272         local testfile=$DIR/$tfile
11273
11274         touch $testfile
11275
11276         echo "setfacl as user..."
11277         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11278         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11279
11280         echo "setfattr as user..."
11281         setfacl -m "u:$RUNAS_ID:---" $testfile
11282         $RUNAS setfattr -x system.posix_acl_access $testfile
11283         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11284 }
11285 run_test 102p "check setxattr(2) correctly fails without permission"
11286
11287 test_102q() {
11288         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11289                 skip "MDS needs to be at least 2.6.92"
11290
11291         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11292 }
11293 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11294
11295 test_102r() {
11296         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11297                 skip "MDS needs to be at least 2.6.93"
11298
11299         touch $DIR/$tfile || error "touch"
11300         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11301         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11302         rm $DIR/$tfile || error "rm"
11303
11304         #normal directory
11305         mkdir -p $DIR/$tdir || error "mkdir"
11306         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11307         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11308         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11309                 error "$testfile error deleting user.author1"
11310         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11311                 grep "user.$(basename $tdir)" &&
11312                 error "$tdir did not delete user.$(basename $tdir)"
11313         rmdir $DIR/$tdir || error "rmdir"
11314
11315         #striped directory
11316         test_mkdir $DIR/$tdir
11317         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11318         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11319         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11320                 error "$testfile error deleting user.author1"
11321         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11322                 grep "user.$(basename $tdir)" &&
11323                 error "$tdir did not delete user.$(basename $tdir)"
11324         rmdir $DIR/$tdir || error "rm striped dir"
11325 }
11326 run_test 102r "set EAs with empty values"
11327
11328 test_102s() {
11329         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11330                 skip "MDS needs to be at least 2.11.52"
11331
11332         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11333
11334         save_lustre_params client "llite.*.xattr_cache" > $save
11335
11336         for cache in 0 1; do
11337                 lctl set_param llite.*.xattr_cache=$cache
11338
11339                 rm -f $DIR/$tfile
11340                 touch $DIR/$tfile || error "touch"
11341                 for prefix in lustre security system trusted user; do
11342                         # Note getxattr() may fail with 'Operation not
11343                         # supported' or 'No such attribute' depending
11344                         # on prefix and cache.
11345                         getfattr -n $prefix.n102s $DIR/$tfile &&
11346                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11347                 done
11348         done
11349
11350         restore_lustre_params < $save
11351 }
11352 run_test 102s "getting nonexistent xattrs should fail"
11353
11354 test_102t() {
11355         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11356                 skip "MDS needs to be at least 2.11.52"
11357
11358         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11359
11360         save_lustre_params client "llite.*.xattr_cache" > $save
11361
11362         for cache in 0 1; do
11363                 lctl set_param llite.*.xattr_cache=$cache
11364
11365                 for buf_size in 0 256; do
11366                         rm -f $DIR/$tfile
11367                         touch $DIR/$tfile || error "touch"
11368                         setfattr -n user.multiop $DIR/$tfile
11369                         $MULTIOP $DIR/$tfile oa$buf_size ||
11370                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11371                 done
11372         done
11373
11374         restore_lustre_params < $save
11375 }
11376 run_test 102t "zero length xattr values handled correctly"
11377
11378 run_acl_subtest()
11379 {
11380     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11381     return $?
11382 }
11383
11384 test_103a() {
11385         [ "$UID" != 0 ] && skip "must run as root"
11386         $GSS && skip_env "could not run under gss"
11387         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11388                 skip_env "must have acl enabled"
11389         [ -z "$(which setfacl 2>/dev/null)" ] &&
11390                 skip_env "could not find setfacl"
11391         remote_mds_nodsh && skip "remote MDS with nodsh"
11392
11393         gpasswd -a daemon bin                           # LU-5641
11394         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11395
11396         declare -a identity_old
11397
11398         for num in $(seq $MDSCOUNT); do
11399                 switch_identity $num true || identity_old[$num]=$?
11400         done
11401
11402         SAVE_UMASK=$(umask)
11403         umask 0022
11404         mkdir -p $DIR/$tdir
11405         cd $DIR/$tdir
11406
11407         echo "performing cp ..."
11408         run_acl_subtest cp || error "run_acl_subtest cp failed"
11409         echo "performing getfacl-noacl..."
11410         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11411         echo "performing misc..."
11412         run_acl_subtest misc || error  "misc test failed"
11413         echo "performing permissions..."
11414         run_acl_subtest permissions || error "permissions failed"
11415         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11416         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11417                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11418                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11419         then
11420                 echo "performing permissions xattr..."
11421                 run_acl_subtest permissions_xattr ||
11422                         error "permissions_xattr failed"
11423         fi
11424         echo "performing setfacl..."
11425         run_acl_subtest setfacl || error  "setfacl test failed"
11426
11427         # inheritance test got from HP
11428         echo "performing inheritance..."
11429         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11430         chmod +x make-tree || error "chmod +x failed"
11431         run_acl_subtest inheritance || error "inheritance test failed"
11432         rm -f make-tree
11433
11434         echo "LU-974 ignore umask when acl is enabled..."
11435         run_acl_subtest 974 || error "LU-974 umask test failed"
11436         if [ $MDSCOUNT -ge 2 ]; then
11437                 run_acl_subtest 974_remote ||
11438                         error "LU-974 umask test failed under remote dir"
11439         fi
11440
11441         echo "LU-2561 newly created file is same size as directory..."
11442         if [ "$mds1_FSTYPE" != "zfs" ]; then
11443                 run_acl_subtest 2561 || error "LU-2561 test failed"
11444         else
11445                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11446         fi
11447
11448         run_acl_subtest 4924 || error "LU-4924 test failed"
11449
11450         cd $SAVE_PWD
11451         umask $SAVE_UMASK
11452
11453         for num in $(seq $MDSCOUNT); do
11454                 if [ "${identity_old[$num]}" = 1 ]; then
11455                         switch_identity $num false || identity_old[$num]=$?
11456                 fi
11457         done
11458 }
11459 run_test 103a "acl test"
11460
11461 test_103b() {
11462         declare -a pids
11463         local U
11464
11465         for U in {0..511}; do
11466                 {
11467                 local O=$(printf "%04o" $U)
11468
11469                 umask $(printf "%04o" $((511 ^ $O)))
11470                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11471                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11472
11473                 (( $S == ($O & 0666) )) ||
11474                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11475
11476                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11477                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11478                 (( $S == ($O & 0666) )) ||
11479                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11480
11481                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11482                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11483                 (( $S == ($O & 0666) )) ||
11484                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11485                 rm -f $DIR/$tfile.[smp]$0
11486                 } &
11487                 local pid=$!
11488
11489                 # limit the concurrently running threads to 64. LU-11878
11490                 local idx=$((U % 64))
11491                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11492                 pids[idx]=$pid
11493         done
11494         wait
11495 }
11496 run_test 103b "umask lfs setstripe"
11497
11498 test_103c() {
11499         mkdir -p $DIR/$tdir
11500         cp -rp $DIR/$tdir $DIR/$tdir.bak
11501
11502         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11503                 error "$DIR/$tdir shouldn't contain default ACL"
11504         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11505                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11506         true
11507 }
11508 run_test 103c "'cp -rp' won't set empty acl"
11509
11510 test_103e() {
11511         local numacl
11512         local fileacl
11513         local saved_debug=$($LCTL get_param -n debug)
11514
11515         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11516                 skip "MDS needs to be at least 2.14.0"
11517
11518         large_xattr_enabled || skip_env "ea_inode feature disabled"
11519
11520         mkdir -p $DIR/$tdir
11521         # add big LOV EA to cause reply buffer overflow earlier
11522         $LFS setstripe -C 1000 $DIR/$tdir
11523         lctl set_param mdc.*-mdc*.stats=clear
11524
11525         $LCTL set_param debug=0
11526         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11527         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11528
11529         # add a large number of default ACLs (expect 8000+ for 2.13+)
11530         for U in {2..7000}; do
11531                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11532                         error "Able to add just $U default ACLs"
11533         done
11534         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11535         echo "$numacl default ACLs created"
11536
11537         stat $DIR/$tdir || error "Cannot stat directory"
11538         # check file creation
11539         touch $DIR/$tdir/$tfile ||
11540                 error "failed to create $tfile with $numacl default ACLs"
11541         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11542         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11543         echo "$fileacl ACLs were inherited"
11544         (( $fileacl == $numacl )) ||
11545                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11546         # check that new ACLs creation adds new ACLs to inherited ACLs
11547         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11548                 error "Cannot set new ACL"
11549         numacl=$((numacl + 1))
11550         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11551         (( $fileacl == $numacl )) ||
11552                 error "failed to add new ACL: $fileacl != $numacl as expected"
11553         # adds more ACLs to a file to reach their maximum at 8000+
11554         numacl=0
11555         for U in {20000..25000}; do
11556                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11557                 numacl=$((numacl + 1))
11558         done
11559         echo "Added $numacl more ACLs to the file"
11560         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11561         echo "Total $fileacl ACLs in file"
11562         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11563         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11564         rmdir $DIR/$tdir || error "Cannot remove directory"
11565 }
11566 run_test 103e "inheritance of big amount of default ACLs"
11567
11568 test_103f() {
11569         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11570                 skip "MDS needs to be at least 2.14.51"
11571
11572         large_xattr_enabled || skip_env "ea_inode feature disabled"
11573
11574         # enable changelog to consume more internal MDD buffers
11575         changelog_register
11576
11577         mkdir -p $DIR/$tdir
11578         # add big LOV EA
11579         $LFS setstripe -C 1000 $DIR/$tdir
11580         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11581         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11582         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11583         rmdir $DIR/$tdir || error "Cannot remove directory"
11584 }
11585 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11586
11587 test_104a() {
11588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11589
11590         touch $DIR/$tfile
11591         lfs df || error "lfs df failed"
11592         lfs df -ih || error "lfs df -ih failed"
11593         lfs df -h $DIR || error "lfs df -h $DIR failed"
11594         lfs df -i $DIR || error "lfs df -i $DIR failed"
11595         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11596         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11597
11598         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11599         lctl --device %$OSC deactivate
11600         lfs df || error "lfs df with deactivated OSC failed"
11601         lctl --device %$OSC activate
11602         # wait the osc back to normal
11603         wait_osc_import_ready client ost
11604
11605         lfs df || error "lfs df with reactivated OSC failed"
11606         rm -f $DIR/$tfile
11607 }
11608 run_test 104a "lfs df [-ih] [path] test ========================="
11609
11610 test_104b() {
11611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11612         [ $RUNAS_ID -eq $UID ] &&
11613                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11614
11615         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11616                         grep "Permission denied" | wc -l)))
11617         if [ $denied_cnt -ne 0 ]; then
11618                 error "lfs check servers test failed"
11619         fi
11620 }
11621 run_test 104b "$RUNAS lfs check servers test ===================="
11622
11623 #
11624 # Verify $1 is within range of $2.
11625 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11626 # $1 is <= 2% of $2. Else Fail.
11627 #
11628 value_in_range() {
11629         # Strip all units (M, G, T)
11630         actual=$(echo $1 | tr -d A-Z)
11631         expect=$(echo $2 | tr -d A-Z)
11632
11633         expect_lo=$(($expect * 98 / 100)) # 2% below
11634         expect_hi=$(($expect * 102 / 100)) # 2% above
11635
11636         # permit 2% drift above and below
11637         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11638 }
11639
11640 test_104c() {
11641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11642         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11643
11644         local ost_param="osd-zfs.$FSNAME-OST0000."
11645         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11646         local ofacets=$(get_facets OST)
11647         local mfacets=$(get_facets MDS)
11648         local saved_ost_blocks=
11649         local saved_mdt_blocks=
11650
11651         echo "Before recordsize change"
11652         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11653         df=($(df -h | grep "/mnt/lustre"$))
11654
11655         # For checking.
11656         echo "lfs output : ${lfs_df[*]}"
11657         echo "df  output : ${df[*]}"
11658
11659         for facet in ${ofacets//,/ }; do
11660                 if [ -z $saved_ost_blocks ]; then
11661                         saved_ost_blocks=$(do_facet $facet \
11662                                 lctl get_param -n $ost_param.blocksize)
11663                         echo "OST Blocksize: $saved_ost_blocks"
11664                 fi
11665                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11666                 do_facet $facet zfs set recordsize=32768 $ost
11667         done
11668
11669         # BS too small. Sufficient for functional testing.
11670         for facet in ${mfacets//,/ }; do
11671                 if [ -z $saved_mdt_blocks ]; then
11672                         saved_mdt_blocks=$(do_facet $facet \
11673                                 lctl get_param -n $mdt_param.blocksize)
11674                         echo "MDT Blocksize: $saved_mdt_blocks"
11675                 fi
11676                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11677                 do_facet $facet zfs set recordsize=32768 $mdt
11678         done
11679
11680         # Give new values chance to reflect change
11681         sleep 2
11682
11683         echo "After recordsize change"
11684         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11685         df_after=($(df -h | grep "/mnt/lustre"$))
11686
11687         # For checking.
11688         echo "lfs output : ${lfs_df_after[*]}"
11689         echo "df  output : ${df_after[*]}"
11690
11691         # Verify lfs df
11692         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11693                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11694         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11695                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11696         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11697                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11698
11699         # Verify df
11700         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11701                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11702         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11703                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11704         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11705                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11706
11707         # Restore MDT recordize back to original
11708         for facet in ${mfacets//,/ }; do
11709                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11710                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11711         done
11712
11713         # Restore OST recordize back to original
11714         for facet in ${ofacets//,/ }; do
11715                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11716                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11717         done
11718
11719         return 0
11720 }
11721 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11722
11723 test_105a() {
11724         # doesn't work on 2.4 kernels
11725         touch $DIR/$tfile
11726         if $(flock_is_enabled); then
11727                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11728         else
11729                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11730         fi
11731         rm -f $DIR/$tfile
11732 }
11733 run_test 105a "flock when mounted without -o flock test ========"
11734
11735 test_105b() {
11736         touch $DIR/$tfile
11737         if $(flock_is_enabled); then
11738                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11739         else
11740                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11741         fi
11742         rm -f $DIR/$tfile
11743 }
11744 run_test 105b "fcntl when mounted without -o flock test ========"
11745
11746 test_105c() {
11747         touch $DIR/$tfile
11748         if $(flock_is_enabled); then
11749                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11750         else
11751                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11752         fi
11753         rm -f $DIR/$tfile
11754 }
11755 run_test 105c "lockf when mounted without -o flock test"
11756
11757 test_105d() { # bug 15924
11758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11759
11760         test_mkdir $DIR/$tdir
11761         flock_is_enabled || skip_env "mount w/o flock enabled"
11762         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11763         $LCTL set_param fail_loc=0x80000315
11764         flocks_test 2 $DIR/$tdir
11765 }
11766 run_test 105d "flock race (should not freeze) ========"
11767
11768 test_105e() { # bug 22660 && 22040
11769         flock_is_enabled || skip_env "mount w/o flock enabled"
11770
11771         touch $DIR/$tfile
11772         flocks_test 3 $DIR/$tfile
11773 }
11774 run_test 105e "Two conflicting flocks from same process"
11775
11776 test_106() { #bug 10921
11777         test_mkdir $DIR/$tdir
11778         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11779         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11780 }
11781 run_test 106 "attempt exec of dir followed by chown of that dir"
11782
11783 test_107() {
11784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11785
11786         CDIR=`pwd`
11787         local file=core
11788
11789         cd $DIR
11790         rm -f $file
11791
11792         local save_pattern=$(sysctl -n kernel.core_pattern)
11793         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11794         sysctl -w kernel.core_pattern=$file
11795         sysctl -w kernel.core_uses_pid=0
11796
11797         ulimit -c unlimited
11798         sleep 60 &
11799         SLEEPPID=$!
11800
11801         sleep 1
11802
11803         kill -s 11 $SLEEPPID
11804         wait $SLEEPPID
11805         if [ -e $file ]; then
11806                 size=`stat -c%s $file`
11807                 [ $size -eq 0 ] && error "Fail to create core file $file"
11808         else
11809                 error "Fail to create core file $file"
11810         fi
11811         rm -f $file
11812         sysctl -w kernel.core_pattern=$save_pattern
11813         sysctl -w kernel.core_uses_pid=$save_uses_pid
11814         cd $CDIR
11815 }
11816 run_test 107 "Coredump on SIG"
11817
11818 test_110() {
11819         test_mkdir $DIR/$tdir
11820         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11821         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11822                 error "mkdir with 256 char should fail, but did not"
11823         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11824                 error "create with 255 char failed"
11825         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11826                 error "create with 256 char should fail, but did not"
11827
11828         ls -l $DIR/$tdir
11829         rm -rf $DIR/$tdir
11830 }
11831 run_test 110 "filename length checking"
11832
11833 #
11834 # Purpose: To verify dynamic thread (OSS) creation.
11835 #
11836 test_115() {
11837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11838         remote_ost_nodsh && skip "remote OST with nodsh"
11839
11840         # Lustre does not stop service threads once they are started.
11841         # Reset number of running threads to default.
11842         stopall
11843         setupall
11844
11845         local OSTIO_pre
11846         local save_params="$TMP/sanity-$TESTNAME.parameters"
11847
11848         # Get ll_ost_io count before I/O
11849         OSTIO_pre=$(do_facet ost1 \
11850                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11851         # Exit if lustre is not running (ll_ost_io not running).
11852         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11853
11854         echo "Starting with $OSTIO_pre threads"
11855         local thread_max=$((OSTIO_pre * 2))
11856         local rpc_in_flight=$((thread_max * 2))
11857         # this is limited to OSC_MAX_RIF_MAX (256)
11858         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
11859         thread_max=$((rpc_in_flight / 2))
11860         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
11861                 return
11862
11863         # Number of I/O Process proposed to be started.
11864         local nfiles
11865         local facets=$(get_facets OST)
11866
11867         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11868         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11869
11870         # Set in_flight to $rpc_in_flight
11871         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11872                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11873         nfiles=${rpc_in_flight}
11874         # Set ost thread_max to $thread_max
11875         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11876
11877         # 5 Minutes should be sufficient for max number of OSS
11878         # threads(thread_max) to be created.
11879         local timeout=300
11880
11881         # Start I/O.
11882         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11883         test_mkdir $DIR/$tdir
11884         for i in $(seq $nfiles); do
11885                 local file=$DIR/$tdir/${tfile}-$i
11886                 $LFS setstripe -c -1 -i 0 $file
11887                 ($WTL $file $timeout)&
11888         done
11889
11890         # I/O Started - Wait for thread_started to reach thread_max or report
11891         # error if thread_started is more than thread_max.
11892         echo "Waiting for thread_started to reach thread_max"
11893         local thread_started=0
11894         local end_time=$((SECONDS + timeout))
11895
11896         while [ $SECONDS -le $end_time ] ; do
11897                 echo -n "."
11898                 # Get ost i/o thread_started count.
11899                 thread_started=$(do_facet ost1 \
11900                         "$LCTL get_param \
11901                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11902                 # Break out if thread_started is equal/greater than thread_max
11903                 if [[ $thread_started -ge $thread_max ]]; then
11904                         echo ll_ost_io thread_started $thread_started, \
11905                                 equal/greater than thread_max $thread_max
11906                         break
11907                 fi
11908                 sleep 1
11909         done
11910
11911         # Cleanup - We have the numbers, Kill i/o jobs if running.
11912         jobcount=($(jobs -p))
11913         for i in $(seq 0 $((${#jobcount[@]}-1)))
11914         do
11915                 kill -9 ${jobcount[$i]}
11916                 if [ $? -ne 0 ] ; then
11917                         echo Warning: \
11918                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11919                 fi
11920         done
11921
11922         # Cleanup files left by WTL binary.
11923         for i in $(seq $nfiles); do
11924                 local file=$DIR/$tdir/${tfile}-$i
11925                 rm -rf $file
11926                 if [ $? -ne 0 ] ; then
11927                         echo "Warning: Failed to delete file $file"
11928                 fi
11929         done
11930
11931         restore_lustre_params <$save_params
11932         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11933
11934         # Error out if no new thread has started or Thread started is greater
11935         # than thread max.
11936         if [[ $thread_started -le $OSTIO_pre ||
11937                         $thread_started -gt $thread_max ]]; then
11938                 error "ll_ost_io: thread_started $thread_started" \
11939                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11940                       "No new thread started or thread started greater " \
11941                       "than thread_max."
11942         fi
11943 }
11944 run_test 115 "verify dynamic thread creation===================="
11945
11946 free_min_max () {
11947         wait_delete_completed
11948         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11949         echo "OST kbytes available: ${AVAIL[@]}"
11950         MAXV=${AVAIL[0]}
11951         MAXI=0
11952         MINV=${AVAIL[0]}
11953         MINI=0
11954         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11955                 #echo OST $i: ${AVAIL[i]}kb
11956                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11957                         MAXV=${AVAIL[i]}
11958                         MAXI=$i
11959                 fi
11960                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11961                         MINV=${AVAIL[i]}
11962                         MINI=$i
11963                 fi
11964         done
11965         echo "Min free space: OST $MINI: $MINV"
11966         echo "Max free space: OST $MAXI: $MAXV"
11967 }
11968
11969 test_116a() { # was previously test_116()
11970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11971         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11972         remote_mds_nodsh && skip "remote MDS with nodsh"
11973
11974         echo -n "Free space priority "
11975         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11976                 head -n1
11977         declare -a AVAIL
11978         free_min_max
11979
11980         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11981         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11982         stack_trap simple_cleanup_common
11983
11984         # Check if we need to generate uneven OSTs
11985         test_mkdir -p $DIR/$tdir/OST${MINI}
11986         local FILL=$((MINV / 4))
11987         local DIFF=$((MAXV - MINV))
11988         local DIFF2=$((DIFF * 100 / MINV))
11989
11990         local threshold=$(do_facet $SINGLEMDS \
11991                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11992         threshold=${threshold%%%}
11993         echo -n "Check for uneven OSTs: "
11994         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11995
11996         if [[ $DIFF2 -gt $threshold ]]; then
11997                 echo "ok"
11998                 echo "Don't need to fill OST$MINI"
11999         else
12000                 # generate uneven OSTs. Write 2% over the QOS threshold value
12001                 echo "no"
12002                 DIFF=$((threshold - DIFF2 + 2))
12003                 DIFF2=$((MINV * DIFF / 100))
12004                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12005                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12006                         error "setstripe failed"
12007                 DIFF=$((DIFF2 / 2048))
12008                 i=0
12009                 while [ $i -lt $DIFF ]; do
12010                         i=$((i + 1))
12011                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12012                                 bs=2M count=1 2>/dev/null
12013                         echo -n .
12014                 done
12015                 echo .
12016                 sync
12017                 sleep_maxage
12018                 free_min_max
12019         fi
12020
12021         DIFF=$((MAXV - MINV))
12022         DIFF2=$((DIFF * 100 / MINV))
12023         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12024         if [ $DIFF2 -gt $threshold ]; then
12025                 echo "ok"
12026         else
12027                 skip "QOS imbalance criteria not met"
12028         fi
12029
12030         MINI1=$MINI
12031         MINV1=$MINV
12032         MAXI1=$MAXI
12033         MAXV1=$MAXV
12034
12035         # now fill using QOS
12036         $LFS setstripe -c 1 $DIR/$tdir
12037         FILL=$((FILL / 200))
12038         if [ $FILL -gt 600 ]; then
12039                 FILL=600
12040         fi
12041         echo "writing $FILL files to QOS-assigned OSTs"
12042         i=0
12043         while [ $i -lt $FILL ]; do
12044                 i=$((i + 1))
12045                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12046                         count=1 2>/dev/null
12047                 echo -n .
12048         done
12049         echo "wrote $i 200k files"
12050         sync
12051         sleep_maxage
12052
12053         echo "Note: free space may not be updated, so measurements might be off"
12054         free_min_max
12055         DIFF2=$((MAXV - MINV))
12056         echo "free space delta: orig $DIFF final $DIFF2"
12057         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12058         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12059         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12060         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12061         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12062         if [[ $DIFF -gt 0 ]]; then
12063                 FILL=$((DIFF2 * 100 / DIFF - 100))
12064                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12065         fi
12066
12067         # Figure out which files were written where
12068         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12069                awk '/'$MINI1': / {print $2; exit}')
12070         echo $UUID
12071         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12072         echo "$MINC files created on smaller OST $MINI1"
12073         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12074                awk '/'$MAXI1': / {print $2; exit}')
12075         echo $UUID
12076         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12077         echo "$MAXC files created on larger OST $MAXI1"
12078         if [[ $MINC -gt 0 ]]; then
12079                 FILL=$((MAXC * 100 / MINC - 100))
12080                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12081         fi
12082         [[ $MAXC -gt $MINC ]] ||
12083                 error_ignore LU-9 "stripe QOS didn't balance free space"
12084 }
12085 run_test 116a "stripe QOS: free space balance ==================="
12086
12087 test_116b() { # LU-2093
12088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12089         remote_mds_nodsh && skip "remote MDS with nodsh"
12090
12091 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12092         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12093                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12094         [ -z "$old_rr" ] && skip "no QOS"
12095         do_facet $SINGLEMDS lctl set_param \
12096                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12097         mkdir -p $DIR/$tdir
12098         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12099         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12100         do_facet $SINGLEMDS lctl set_param fail_loc=0
12101         rm -rf $DIR/$tdir
12102         do_facet $SINGLEMDS lctl set_param \
12103                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12104 }
12105 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12106
12107 test_117() # bug 10891
12108 {
12109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12110
12111         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12112         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12113         lctl set_param fail_loc=0x21e
12114         > $DIR/$tfile || error "truncate failed"
12115         lctl set_param fail_loc=0
12116         echo "Truncate succeeded."
12117         rm -f $DIR/$tfile
12118 }
12119 run_test 117 "verify osd extend =========="
12120
12121 NO_SLOW_RESENDCOUNT=4
12122 export OLD_RESENDCOUNT=""
12123 set_resend_count () {
12124         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12125         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12126         lctl set_param -n $PROC_RESENDCOUNT $1
12127         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12128 }
12129
12130 # for reduce test_118* time (b=14842)
12131 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12132
12133 # Reset async IO behavior after error case
12134 reset_async() {
12135         FILE=$DIR/reset_async
12136
12137         # Ensure all OSCs are cleared
12138         $LFS setstripe -c -1 $FILE
12139         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12140         sync
12141         rm $FILE
12142 }
12143
12144 test_118a() #bug 11710
12145 {
12146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12147
12148         reset_async
12149
12150         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12151         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12152         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12153
12154         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12155                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12156                 return 1;
12157         fi
12158         rm -f $DIR/$tfile
12159 }
12160 run_test 118a "verify O_SYNC works =========="
12161
12162 test_118b()
12163 {
12164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12165         remote_ost_nodsh && skip "remote OST with nodsh"
12166
12167         reset_async
12168
12169         #define OBD_FAIL_SRV_ENOENT 0x217
12170         set_nodes_failloc "$(osts_nodes)" 0x217
12171         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12172         RC=$?
12173         set_nodes_failloc "$(osts_nodes)" 0
12174         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12175         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12176                     grep -c writeback)
12177
12178         if [[ $RC -eq 0 ]]; then
12179                 error "Must return error due to dropped pages, rc=$RC"
12180                 return 1;
12181         fi
12182
12183         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12184                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12185                 return 1;
12186         fi
12187
12188         echo "Dirty pages not leaked on ENOENT"
12189
12190         # Due to the above error the OSC will issue all RPCs syncronously
12191         # until a subsequent RPC completes successfully without error.
12192         $MULTIOP $DIR/$tfile Ow4096yc
12193         rm -f $DIR/$tfile
12194
12195         return 0
12196 }
12197 run_test 118b "Reclaim dirty pages on fatal error =========="
12198
12199 test_118c()
12200 {
12201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12202
12203         # for 118c, restore the original resend count, LU-1940
12204         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12205                                 set_resend_count $OLD_RESENDCOUNT
12206         remote_ost_nodsh && skip "remote OST with nodsh"
12207
12208         reset_async
12209
12210         #define OBD_FAIL_OST_EROFS               0x216
12211         set_nodes_failloc "$(osts_nodes)" 0x216
12212
12213         # multiop should block due to fsync until pages are written
12214         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12215         MULTIPID=$!
12216         sleep 1
12217
12218         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12219                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12220         fi
12221
12222         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12223                     grep -c writeback)
12224         if [[ $WRITEBACK -eq 0 ]]; then
12225                 error "No page in writeback, writeback=$WRITEBACK"
12226         fi
12227
12228         set_nodes_failloc "$(osts_nodes)" 0
12229         wait $MULTIPID
12230         RC=$?
12231         if [[ $RC -ne 0 ]]; then
12232                 error "Multiop fsync failed, rc=$RC"
12233         fi
12234
12235         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12236         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12237                     grep -c writeback)
12238         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12239                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12240         fi
12241
12242         rm -f $DIR/$tfile
12243         echo "Dirty pages flushed via fsync on EROFS"
12244         return 0
12245 }
12246 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12247
12248 # continue to use small resend count to reduce test_118* time (b=14842)
12249 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12250
12251 test_118d()
12252 {
12253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12254         remote_ost_nodsh && skip "remote OST with nodsh"
12255
12256         reset_async
12257
12258         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12259         set_nodes_failloc "$(osts_nodes)" 0x214
12260         # multiop should block due to fsync until pages are written
12261         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12262         MULTIPID=$!
12263         sleep 1
12264
12265         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12266                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12267         fi
12268
12269         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12270                     grep -c writeback)
12271         if [[ $WRITEBACK -eq 0 ]]; then
12272                 error "No page in writeback, writeback=$WRITEBACK"
12273         fi
12274
12275         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12276         set_nodes_failloc "$(osts_nodes)" 0
12277
12278         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12279         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12280                     grep -c writeback)
12281         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12282                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12283         fi
12284
12285         rm -f $DIR/$tfile
12286         echo "Dirty pages gaurenteed flushed via fsync"
12287         return 0
12288 }
12289 run_test 118d "Fsync validation inject a delay of the bulk =========="
12290
12291 test_118f() {
12292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12293
12294         reset_async
12295
12296         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12297         lctl set_param fail_loc=0x8000040a
12298
12299         # Should simulate EINVAL error which is fatal
12300         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12301         RC=$?
12302         if [[ $RC -eq 0 ]]; then
12303                 error "Must return error due to dropped pages, rc=$RC"
12304         fi
12305
12306         lctl set_param fail_loc=0x0
12307
12308         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12309         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12310         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12311                     grep -c writeback)
12312         if [[ $LOCKED -ne 0 ]]; then
12313                 error "Locked pages remain in cache, locked=$LOCKED"
12314         fi
12315
12316         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12317                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12318         fi
12319
12320         rm -f $DIR/$tfile
12321         echo "No pages locked after fsync"
12322
12323         reset_async
12324         return 0
12325 }
12326 run_test 118f "Simulate unrecoverable OSC side error =========="
12327
12328 test_118g() {
12329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12330
12331         reset_async
12332
12333         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12334         lctl set_param fail_loc=0x406
12335
12336         # simulate local -ENOMEM
12337         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12338         RC=$?
12339
12340         lctl set_param fail_loc=0
12341         if [[ $RC -eq 0 ]]; then
12342                 error "Must return error due to dropped pages, rc=$RC"
12343         fi
12344
12345         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12346         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12347         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12348                         grep -c writeback)
12349         if [[ $LOCKED -ne 0 ]]; then
12350                 error "Locked pages remain in cache, locked=$LOCKED"
12351         fi
12352
12353         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12354                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12355         fi
12356
12357         rm -f $DIR/$tfile
12358         echo "No pages locked after fsync"
12359
12360         reset_async
12361         return 0
12362 }
12363 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12364
12365 test_118h() {
12366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12367         remote_ost_nodsh && skip "remote OST with nodsh"
12368
12369         reset_async
12370
12371         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12372         set_nodes_failloc "$(osts_nodes)" 0x20e
12373         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12374         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12375         RC=$?
12376
12377         set_nodes_failloc "$(osts_nodes)" 0
12378         if [[ $RC -eq 0 ]]; then
12379                 error "Must return error due to dropped pages, rc=$RC"
12380         fi
12381
12382         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12383         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12384         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12385                     grep -c writeback)
12386         if [[ $LOCKED -ne 0 ]]; then
12387                 error "Locked pages remain in cache, locked=$LOCKED"
12388         fi
12389
12390         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12391                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12392         fi
12393
12394         rm -f $DIR/$tfile
12395         echo "No pages locked after fsync"
12396
12397         return 0
12398 }
12399 run_test 118h "Verify timeout in handling recoverables errors  =========="
12400
12401 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12402
12403 test_118i() {
12404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12405         remote_ost_nodsh && skip "remote OST with nodsh"
12406
12407         reset_async
12408
12409         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12410         set_nodes_failloc "$(osts_nodes)" 0x20e
12411
12412         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12413         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12414         PID=$!
12415         sleep 5
12416         set_nodes_failloc "$(osts_nodes)" 0
12417
12418         wait $PID
12419         RC=$?
12420         if [[ $RC -ne 0 ]]; then
12421                 error "got error, but should be not, rc=$RC"
12422         fi
12423
12424         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12425         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12426         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12427         if [[ $LOCKED -ne 0 ]]; then
12428                 error "Locked pages remain in cache, locked=$LOCKED"
12429         fi
12430
12431         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12432                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12433         fi
12434
12435         rm -f $DIR/$tfile
12436         echo "No pages locked after fsync"
12437
12438         return 0
12439 }
12440 run_test 118i "Fix error before timeout in recoverable error  =========="
12441
12442 [ "$SLOW" = "no" ] && set_resend_count 4
12443
12444 test_118j() {
12445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12446         remote_ost_nodsh && skip "remote OST with nodsh"
12447
12448         reset_async
12449
12450         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12451         set_nodes_failloc "$(osts_nodes)" 0x220
12452
12453         # return -EIO from OST
12454         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12455         RC=$?
12456         set_nodes_failloc "$(osts_nodes)" 0x0
12457         if [[ $RC -eq 0 ]]; then
12458                 error "Must return error due to dropped pages, rc=$RC"
12459         fi
12460
12461         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12462         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12463         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12464         if [[ $LOCKED -ne 0 ]]; then
12465                 error "Locked pages remain in cache, locked=$LOCKED"
12466         fi
12467
12468         # in recoverable error on OST we want resend and stay until it finished
12469         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12470                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12471         fi
12472
12473         rm -f $DIR/$tfile
12474         echo "No pages locked after fsync"
12475
12476         return 0
12477 }
12478 run_test 118j "Simulate unrecoverable OST side error =========="
12479
12480 test_118k()
12481 {
12482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12483         remote_ost_nodsh && skip "remote OSTs with nodsh"
12484
12485         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12486         set_nodes_failloc "$(osts_nodes)" 0x20e
12487         test_mkdir $DIR/$tdir
12488
12489         for ((i=0;i<10;i++)); do
12490                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12491                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12492                 SLEEPPID=$!
12493                 sleep 0.500s
12494                 kill $SLEEPPID
12495                 wait $SLEEPPID
12496         done
12497
12498         set_nodes_failloc "$(osts_nodes)" 0
12499         rm -rf $DIR/$tdir
12500 }
12501 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12502
12503 test_118l() # LU-646
12504 {
12505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12506
12507         test_mkdir $DIR/$tdir
12508         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12509         rm -rf $DIR/$tdir
12510 }
12511 run_test 118l "fsync dir"
12512
12513 test_118m() # LU-3066
12514 {
12515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12516
12517         test_mkdir $DIR/$tdir
12518         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12519         rm -rf $DIR/$tdir
12520 }
12521 run_test 118m "fdatasync dir ========="
12522
12523 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12524
12525 test_118n()
12526 {
12527         local begin
12528         local end
12529
12530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12531         remote_ost_nodsh && skip "remote OSTs with nodsh"
12532
12533         # Sleep to avoid a cached response.
12534         #define OBD_STATFS_CACHE_SECONDS 1
12535         sleep 2
12536
12537         # Inject a 10 second delay in the OST_STATFS handler.
12538         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12539         set_nodes_failloc "$(osts_nodes)" 0x242
12540
12541         begin=$SECONDS
12542         stat --file-system $MOUNT > /dev/null
12543         end=$SECONDS
12544
12545         set_nodes_failloc "$(osts_nodes)" 0
12546
12547         if ((end - begin > 20)); then
12548             error "statfs took $((end - begin)) seconds, expected 10"
12549         fi
12550 }
12551 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12552
12553 test_119a() # bug 11737
12554 {
12555         BSIZE=$((512 * 1024))
12556         directio write $DIR/$tfile 0 1 $BSIZE
12557         # We ask to read two blocks, which is more than a file size.
12558         # directio will indicate an error when requested and actual
12559         # sizes aren't equeal (a normal situation in this case) and
12560         # print actual read amount.
12561         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12562         if [ "$NOB" != "$BSIZE" ]; then
12563                 error "read $NOB bytes instead of $BSIZE"
12564         fi
12565         rm -f $DIR/$tfile
12566 }
12567 run_test 119a "Short directIO read must return actual read amount"
12568
12569 test_119b() # bug 11737
12570 {
12571         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12572
12573         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12574         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12575         sync
12576         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12577                 error "direct read failed"
12578         rm -f $DIR/$tfile
12579 }
12580 run_test 119b "Sparse directIO read must return actual read amount"
12581
12582 test_119c() # bug 13099
12583 {
12584         BSIZE=1048576
12585         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12586         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12587         rm -f $DIR/$tfile
12588 }
12589 run_test 119c "Testing for direct read hitting hole"
12590
12591 test_119d() # bug 15950
12592 {
12593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12594
12595         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12596         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12597         BSIZE=1048576
12598         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12599         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12600         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12601         lctl set_param fail_loc=0x40d
12602         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12603         pid_dio=$!
12604         sleep 1
12605         cat $DIR/$tfile > /dev/null &
12606         lctl set_param fail_loc=0
12607         pid_reads=$!
12608         wait $pid_dio
12609         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12610         sleep 2
12611         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12612         error "the read rpcs have not completed in 2s"
12613         rm -f $DIR/$tfile
12614         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12615 }
12616 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12617
12618 test_120a() {
12619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12620         remote_mds_nodsh && skip "remote MDS with nodsh"
12621         test_mkdir -i0 -c1 $DIR/$tdir
12622         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12623                 skip_env "no early lock cancel on server"
12624
12625         lru_resize_disable mdc
12626         lru_resize_disable osc
12627         cancel_lru_locks mdc
12628         # asynchronous object destroy at MDT could cause bl ast to client
12629         cancel_lru_locks osc
12630
12631         stat $DIR/$tdir > /dev/null
12632         can1=$(do_facet mds1 \
12633                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12634                awk '/ldlm_cancel/ {print $2}')
12635         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12636                awk '/ldlm_bl_callback/ {print $2}')
12637         test_mkdir -i0 -c1 $DIR/$tdir/d1
12638         can2=$(do_facet mds1 \
12639                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12640                awk '/ldlm_cancel/ {print $2}')
12641         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12642                awk '/ldlm_bl_callback/ {print $2}')
12643         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12644         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12645         lru_resize_enable mdc
12646         lru_resize_enable osc
12647 }
12648 run_test 120a "Early Lock Cancel: mkdir test"
12649
12650 test_120b() {
12651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12652         remote_mds_nodsh && skip "remote MDS with nodsh"
12653         test_mkdir $DIR/$tdir
12654         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12655                 skip_env "no early lock cancel on server"
12656
12657         lru_resize_disable mdc
12658         lru_resize_disable osc
12659         cancel_lru_locks mdc
12660         stat $DIR/$tdir > /dev/null
12661         can1=$(do_facet $SINGLEMDS \
12662                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12663                awk '/ldlm_cancel/ {print $2}')
12664         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12665                awk '/ldlm_bl_callback/ {print $2}')
12666         touch $DIR/$tdir/f1
12667         can2=$(do_facet $SINGLEMDS \
12668                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12669                awk '/ldlm_cancel/ {print $2}')
12670         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12671                awk '/ldlm_bl_callback/ {print $2}')
12672         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12673         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12674         lru_resize_enable mdc
12675         lru_resize_enable osc
12676 }
12677 run_test 120b "Early Lock Cancel: create test"
12678
12679 test_120c() {
12680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12681         remote_mds_nodsh && skip "remote MDS with nodsh"
12682         test_mkdir -i0 -c1 $DIR/$tdir
12683         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12684                 skip "no early lock cancel on server"
12685
12686         lru_resize_disable mdc
12687         lru_resize_disable osc
12688         test_mkdir -i0 -c1 $DIR/$tdir/d1
12689         test_mkdir -i0 -c1 $DIR/$tdir/d2
12690         touch $DIR/$tdir/d1/f1
12691         cancel_lru_locks mdc
12692         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12693         can1=$(do_facet mds1 \
12694                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12695                awk '/ldlm_cancel/ {print $2}')
12696         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12697                awk '/ldlm_bl_callback/ {print $2}')
12698         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12699         can2=$(do_facet mds1 \
12700                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12701                awk '/ldlm_cancel/ {print $2}')
12702         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12703                awk '/ldlm_bl_callback/ {print $2}')
12704         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12705         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12706         lru_resize_enable mdc
12707         lru_resize_enable osc
12708 }
12709 run_test 120c "Early Lock Cancel: link test"
12710
12711 test_120d() {
12712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12713         remote_mds_nodsh && skip "remote MDS with nodsh"
12714         test_mkdir -i0 -c1 $DIR/$tdir
12715         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12716                 skip_env "no early lock cancel on server"
12717
12718         lru_resize_disable mdc
12719         lru_resize_disable osc
12720         touch $DIR/$tdir
12721         cancel_lru_locks mdc
12722         stat $DIR/$tdir > /dev/null
12723         can1=$(do_facet mds1 \
12724                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12725                awk '/ldlm_cancel/ {print $2}')
12726         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12727                awk '/ldlm_bl_callback/ {print $2}')
12728         chmod a+x $DIR/$tdir
12729         can2=$(do_facet mds1 \
12730                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12731                awk '/ldlm_cancel/ {print $2}')
12732         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12733                awk '/ldlm_bl_callback/ {print $2}')
12734         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12735         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12736         lru_resize_enable mdc
12737         lru_resize_enable osc
12738 }
12739 run_test 120d "Early Lock Cancel: setattr test"
12740
12741 test_120e() {
12742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12743         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12744                 skip_env "no early lock cancel on server"
12745         remote_mds_nodsh && skip "remote MDS with nodsh"
12746
12747         local dlmtrace_set=false
12748
12749         test_mkdir -i0 -c1 $DIR/$tdir
12750         lru_resize_disable mdc
12751         lru_resize_disable osc
12752         ! $LCTL get_param debug | grep -q dlmtrace &&
12753                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12754         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12755         cancel_lru_locks mdc
12756         cancel_lru_locks osc
12757         dd if=$DIR/$tdir/f1 of=/dev/null
12758         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12759         # XXX client can not do early lock cancel of OST lock
12760         # during unlink (LU-4206), so cancel osc lock now.
12761         sleep 2
12762         cancel_lru_locks osc
12763         can1=$(do_facet mds1 \
12764                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12765                awk '/ldlm_cancel/ {print $2}')
12766         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12767                awk '/ldlm_bl_callback/ {print $2}')
12768         unlink $DIR/$tdir/f1
12769         sleep 5
12770         can2=$(do_facet mds1 \
12771                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12772                awk '/ldlm_cancel/ {print $2}')
12773         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12774                awk '/ldlm_bl_callback/ {print $2}')
12775         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12776                 $LCTL dk $TMP/cancel.debug.txt
12777         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12778                 $LCTL dk $TMP/blocking.debug.txt
12779         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12780         lru_resize_enable mdc
12781         lru_resize_enable osc
12782 }
12783 run_test 120e "Early Lock Cancel: unlink test"
12784
12785 test_120f() {
12786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12787         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12788                 skip_env "no early lock cancel on server"
12789         remote_mds_nodsh && skip "remote MDS with nodsh"
12790
12791         test_mkdir -i0 -c1 $DIR/$tdir
12792         lru_resize_disable mdc
12793         lru_resize_disable osc
12794         test_mkdir -i0 -c1 $DIR/$tdir/d1
12795         test_mkdir -i0 -c1 $DIR/$tdir/d2
12796         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12797         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12798         cancel_lru_locks mdc
12799         cancel_lru_locks osc
12800         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12801         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12802         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12803         # XXX client can not do early lock cancel of OST lock
12804         # during rename (LU-4206), so cancel osc lock now.
12805         sleep 2
12806         cancel_lru_locks osc
12807         can1=$(do_facet mds1 \
12808                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12809                awk '/ldlm_cancel/ {print $2}')
12810         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12811                awk '/ldlm_bl_callback/ {print $2}')
12812         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12813         sleep 5
12814         can2=$(do_facet mds1 \
12815                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12816                awk '/ldlm_cancel/ {print $2}')
12817         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12818                awk '/ldlm_bl_callback/ {print $2}')
12819         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12820         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12821         lru_resize_enable mdc
12822         lru_resize_enable osc
12823 }
12824 run_test 120f "Early Lock Cancel: rename test"
12825
12826 test_120g() {
12827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12828         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12829                 skip_env "no early lock cancel on server"
12830         remote_mds_nodsh && skip "remote MDS with nodsh"
12831
12832         lru_resize_disable mdc
12833         lru_resize_disable osc
12834         count=10000
12835         echo create $count files
12836         test_mkdir $DIR/$tdir
12837         cancel_lru_locks mdc
12838         cancel_lru_locks osc
12839         t0=$(date +%s)
12840
12841         can0=$(do_facet $SINGLEMDS \
12842                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12843                awk '/ldlm_cancel/ {print $2}')
12844         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12845                awk '/ldlm_bl_callback/ {print $2}')
12846         createmany -o $DIR/$tdir/f $count
12847         sync
12848         can1=$(do_facet $SINGLEMDS \
12849                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12850                awk '/ldlm_cancel/ {print $2}')
12851         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12852                awk '/ldlm_bl_callback/ {print $2}')
12853         t1=$(date +%s)
12854         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12855         echo rm $count files
12856         rm -r $DIR/$tdir
12857         sync
12858         can2=$(do_facet $SINGLEMDS \
12859                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12860                awk '/ldlm_cancel/ {print $2}')
12861         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12862                awk '/ldlm_bl_callback/ {print $2}')
12863         t2=$(date +%s)
12864         echo total: $count removes in $((t2-t1))
12865         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12866         sleep 2
12867         # wait for commitment of removal
12868         lru_resize_enable mdc
12869         lru_resize_enable osc
12870 }
12871 run_test 120g "Early Lock Cancel: performance test"
12872
12873 test_121() { #bug #10589
12874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12875
12876         rm -rf $DIR/$tfile
12877         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12878 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12879         lctl set_param fail_loc=0x310
12880         cancel_lru_locks osc > /dev/null
12881         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12882         lctl set_param fail_loc=0
12883         [[ $reads -eq $writes ]] ||
12884                 error "read $reads blocks, must be $writes blocks"
12885 }
12886 run_test 121 "read cancel race ========="
12887
12888 test_123a_base() { # was test 123, statahead(bug 11401)
12889         local lsx="$1"
12890
12891         SLOWOK=0
12892         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12893                 log "testing UP system. Performance may be lower than expected."
12894                 SLOWOK=1
12895         fi
12896
12897         rm -rf $DIR/$tdir
12898         test_mkdir $DIR/$tdir
12899         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12900         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12901         MULT=10
12902         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12903                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12904
12905                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12906                 lctl set_param -n llite.*.statahead_max 0
12907                 lctl get_param llite.*.statahead_max
12908                 cancel_lru_locks mdc
12909                 cancel_lru_locks osc
12910                 stime=$(date +%s)
12911                 time $lsx $DIR/$tdir | wc -l
12912                 etime=$(date +%s)
12913                 delta=$((etime - stime))
12914                 log "$lsx $i files without statahead: $delta sec"
12915                 lctl set_param llite.*.statahead_max=$max
12916
12917                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12918                         grep "statahead wrong:" | awk '{print $3}')
12919                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12920                 cancel_lru_locks mdc
12921                 cancel_lru_locks osc
12922                 stime=$(date +%s)
12923                 time $lsx $DIR/$tdir | wc -l
12924                 etime=$(date +%s)
12925                 delta_sa=$((etime - stime))
12926                 log "$lsx $i files with statahead: $delta_sa sec"
12927                 lctl get_param -n llite.*.statahead_stats
12928                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12929                         grep "statahead wrong:" | awk '{print $3}')
12930
12931                 [[ $swrong -lt $ewrong ]] &&
12932                         log "statahead was stopped, maybe too many locks held!"
12933                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12934
12935                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12936                         max=$(lctl get_param -n llite.*.statahead_max |
12937                                 head -n 1)
12938                         lctl set_param -n llite.*.statahead_max 0
12939                         lctl get_param llite.*.statahead_max
12940                         cancel_lru_locks mdc
12941                         cancel_lru_locks osc
12942                         stime=$(date +%s)
12943                         time $lsx $DIR/$tdir | wc -l
12944                         etime=$(date +%s)
12945                         delta=$((etime - stime))
12946                         log "$lsx $i files again without statahead: $delta sec"
12947                         lctl set_param llite.*.statahead_max=$max
12948                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12949                                 if [  $SLOWOK -eq 0 ]; then
12950                                         error "$lsx $i files is slower with statahead!"
12951                                 else
12952                                         log "$lsx $i files is slower with statahead!"
12953                                 fi
12954                                 break
12955                         fi
12956                 fi
12957
12958                 [ $delta -gt 20 ] && break
12959                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12960                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12961         done
12962         log "$lsx done"
12963
12964         stime=$(date +%s)
12965         rm -r $DIR/$tdir
12966         sync
12967         etime=$(date +%s)
12968         delta=$((etime - stime))
12969         log "rm -r $DIR/$tdir/: $delta seconds"
12970         log "rm done"
12971         lctl get_param -n llite.*.statahead_stats
12972 }
12973
12974 test_123aa() {
12975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12976
12977         test_123a_base "ls -l"
12978 }
12979 run_test 123aa "verify statahead work"
12980
12981 test_123ab() {
12982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12983
12984         statx_supported || skip_env "Test must be statx() syscall supported"
12985
12986         test_123a_base "$STATX -l"
12987 }
12988 run_test 123ab "verify statahead work by using statx"
12989
12990 test_123ac() {
12991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12992
12993         statx_supported || skip_env "Test must be statx() syscall supported"
12994
12995         local rpcs_before
12996         local rpcs_after
12997         local agl_before
12998         local agl_after
12999
13000         cancel_lru_locks $OSC
13001         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13002         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13003                 awk '/agl.total:/ {print $3}')
13004         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13005         test_123a_base "$STATX --cached=always -D"
13006         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13007                 awk '/agl.total:/ {print $3}')
13008         [ $agl_before -eq $agl_after ] ||
13009                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13010         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13011         [ $rpcs_after -eq $rpcs_before ] ||
13012                 error "$STATX should not send glimpse RPCs to $OSC"
13013 }
13014 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13015
13016 test_123b () { # statahead(bug 15027)
13017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13018
13019         test_mkdir $DIR/$tdir
13020         createmany -o $DIR/$tdir/$tfile-%d 1000
13021
13022         cancel_lru_locks mdc
13023         cancel_lru_locks osc
13024
13025 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13026         lctl set_param fail_loc=0x80000803
13027         ls -lR $DIR/$tdir > /dev/null
13028         log "ls done"
13029         lctl set_param fail_loc=0x0
13030         lctl get_param -n llite.*.statahead_stats
13031         rm -r $DIR/$tdir
13032         sync
13033
13034 }
13035 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13036
13037 test_123c() {
13038         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13039
13040         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13041         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13042         touch $DIR/$tdir.1/{1..3}
13043         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13044
13045         remount_client $MOUNT
13046
13047         $MULTIOP $DIR/$tdir.0 Q
13048
13049         # let statahead to complete
13050         ls -l $DIR/$tdir.0 > /dev/null
13051
13052         testid=$(echo $TESTNAME | tr '_' ' ')
13053         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13054                 error "statahead warning" || true
13055 }
13056 run_test 123c "Can not initialize inode warning on DNE statahead"
13057
13058 test_124a() {
13059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13060         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13061                 skip_env "no lru resize on server"
13062
13063         local NR=2000
13064
13065         test_mkdir $DIR/$tdir
13066
13067         log "create $NR files at $DIR/$tdir"
13068         createmany -o $DIR/$tdir/f $NR ||
13069                 error "failed to create $NR files in $DIR/$tdir"
13070
13071         cancel_lru_locks mdc
13072         ls -l $DIR/$tdir > /dev/null
13073
13074         local NSDIR=""
13075         local LRU_SIZE=0
13076         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13077                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13078                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13079                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13080                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13081                         log "NSDIR=$NSDIR"
13082                         log "NS=$(basename $NSDIR)"
13083                         break
13084                 fi
13085         done
13086
13087         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13088                 skip "Not enough cached locks created!"
13089         fi
13090         log "LRU=$LRU_SIZE"
13091
13092         local SLEEP=30
13093
13094         # We know that lru resize allows one client to hold $LIMIT locks
13095         # for 10h. After that locks begin to be killed by client.
13096         local MAX_HRS=10
13097         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13098         log "LIMIT=$LIMIT"
13099         if [ $LIMIT -lt $LRU_SIZE ]; then
13100                 skip "Limit is too small $LIMIT"
13101         fi
13102
13103         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13104         # killing locks. Some time was spent for creating locks. This means
13105         # that up to the moment of sleep finish we must have killed some of
13106         # them (10-100 locks). This depends on how fast ther were created.
13107         # Many of them were touched in almost the same moment and thus will
13108         # be killed in groups.
13109         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13110
13111         # Use $LRU_SIZE_B here to take into account real number of locks
13112         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13113         local LRU_SIZE_B=$LRU_SIZE
13114         log "LVF=$LVF"
13115         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13116         log "OLD_LVF=$OLD_LVF"
13117         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13118
13119         # Let's make sure that we really have some margin. Client checks
13120         # cached locks every 10 sec.
13121         SLEEP=$((SLEEP+20))
13122         log "Sleep ${SLEEP} sec"
13123         local SEC=0
13124         while ((SEC<$SLEEP)); do
13125                 echo -n "..."
13126                 sleep 5
13127                 SEC=$((SEC+5))
13128                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13129                 echo -n "$LRU_SIZE"
13130         done
13131         echo ""
13132         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13133         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13134
13135         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13136                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13137                 unlinkmany $DIR/$tdir/f $NR
13138                 return
13139         }
13140
13141         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13142         log "unlink $NR files at $DIR/$tdir"
13143         unlinkmany $DIR/$tdir/f $NR
13144 }
13145 run_test 124a "lru resize ======================================="
13146
13147 get_max_pool_limit()
13148 {
13149         local limit=$($LCTL get_param \
13150                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13151         local max=0
13152         for l in $limit; do
13153                 if [[ $l -gt $max ]]; then
13154                         max=$l
13155                 fi
13156         done
13157         echo $max
13158 }
13159
13160 test_124b() {
13161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13162         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13163                 skip_env "no lru resize on server"
13164
13165         LIMIT=$(get_max_pool_limit)
13166
13167         NR=$(($(default_lru_size)*20))
13168         if [[ $NR -gt $LIMIT ]]; then
13169                 log "Limit lock number by $LIMIT locks"
13170                 NR=$LIMIT
13171         fi
13172
13173         IFree=$(mdsrate_inodes_available)
13174         if [ $IFree -lt $NR ]; then
13175                 log "Limit lock number by $IFree inodes"
13176                 NR=$IFree
13177         fi
13178
13179         lru_resize_disable mdc
13180         test_mkdir -p $DIR/$tdir/disable_lru_resize
13181
13182         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13183         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13184         cancel_lru_locks mdc
13185         stime=`date +%s`
13186         PID=""
13187         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13188         PID="$PID $!"
13189         sleep 2
13190         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13191         PID="$PID $!"
13192         sleep 2
13193         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13194         PID="$PID $!"
13195         wait $PID
13196         etime=`date +%s`
13197         nolruresize_delta=$((etime-stime))
13198         log "ls -la time: $nolruresize_delta seconds"
13199         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13200         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13201
13202         lru_resize_enable mdc
13203         test_mkdir -p $DIR/$tdir/enable_lru_resize
13204
13205         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13206         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13207         cancel_lru_locks mdc
13208         stime=`date +%s`
13209         PID=""
13210         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13211         PID="$PID $!"
13212         sleep 2
13213         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13214         PID="$PID $!"
13215         sleep 2
13216         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13217         PID="$PID $!"
13218         wait $PID
13219         etime=`date +%s`
13220         lruresize_delta=$((etime-stime))
13221         log "ls -la time: $lruresize_delta seconds"
13222         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13223
13224         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13225                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13226         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13227                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13228         else
13229                 log "lru resize performs the same with no lru resize"
13230         fi
13231         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13232 }
13233 run_test 124b "lru resize (performance test) ======================="
13234
13235 test_124c() {
13236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13237         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13238                 skip_env "no lru resize on server"
13239
13240         # cache ununsed locks on client
13241         local nr=100
13242         cancel_lru_locks mdc
13243         test_mkdir $DIR/$tdir
13244         createmany -o $DIR/$tdir/f $nr ||
13245                 error "failed to create $nr files in $DIR/$tdir"
13246         ls -l $DIR/$tdir > /dev/null
13247
13248         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13249         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13250         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13251         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13252         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13253
13254         # set lru_max_age to 1 sec
13255         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13256         echo "sleep $((recalc_p * 2)) seconds..."
13257         sleep $((recalc_p * 2))
13258
13259         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13260         # restore lru_max_age
13261         $LCTL set_param -n $nsdir.lru_max_age $max_age
13262         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13263         unlinkmany $DIR/$tdir/f $nr
13264 }
13265 run_test 124c "LRUR cancel very aged locks"
13266
13267 test_124d() {
13268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13269         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13270                 skip_env "no lru resize on server"
13271
13272         # cache ununsed locks on client
13273         local nr=100
13274
13275         lru_resize_disable mdc
13276         stack_trap "lru_resize_enable mdc" EXIT
13277
13278         cancel_lru_locks mdc
13279
13280         # asynchronous object destroy at MDT could cause bl ast to client
13281         test_mkdir $DIR/$tdir
13282         createmany -o $DIR/$tdir/f $nr ||
13283                 error "failed to create $nr files in $DIR/$tdir"
13284         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13285
13286         ls -l $DIR/$tdir > /dev/null
13287
13288         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13289         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13290         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13291         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13292
13293         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13294
13295         # set lru_max_age to 1 sec
13296         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13297         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13298
13299         echo "sleep $((recalc_p * 2)) seconds..."
13300         sleep $((recalc_p * 2))
13301
13302         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13303
13304         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13305 }
13306 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13307
13308 test_125() { # 13358
13309         $LCTL get_param -n llite.*.client_type | grep -q local ||
13310                 skip "must run as local client"
13311         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13312                 skip_env "must have acl enabled"
13313         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13314
13315         test_mkdir $DIR/$tdir
13316         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13317         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13318         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13319 }
13320 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13321
13322 test_126() { # bug 12829/13455
13323         $GSS && skip_env "must run as gss disabled"
13324         $LCTL get_param -n llite.*.client_type | grep -q local ||
13325                 skip "must run as local client"
13326         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13327
13328         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13329         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13330         rm -f $DIR/$tfile
13331         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13332 }
13333 run_test 126 "check that the fsgid provided by the client is taken into account"
13334
13335 test_127a() { # bug 15521
13336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13337         local name count samp unit min max sum sumsq
13338
13339         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13340         echo "stats before reset"
13341         $LCTL get_param osc.*.stats
13342         $LCTL set_param osc.*.stats=0
13343         local fsize=$((2048 * 1024))
13344
13345         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13346         cancel_lru_locks osc
13347         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13348
13349         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13350         stack_trap "rm -f $TMP/$tfile.tmp"
13351         while read name count samp unit min max sum sumsq; do
13352                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13353                 [ ! $min ] && error "Missing min value for $name proc entry"
13354                 eval $name=$count || error "Wrong proc format"
13355
13356                 case $name in
13357                 read_bytes|write_bytes)
13358                         [[ "$unit" =~ "bytes" ]] ||
13359                                 error "unit is not 'bytes': $unit"
13360                         (( $min >= 4096 )) || error "min is too small: $min"
13361                         (( $min <= $fsize )) || error "min is too big: $min"
13362                         (( $max >= 4096 )) || error "max is too small: $max"
13363                         (( $max <= $fsize )) || error "max is too big: $max"
13364                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13365                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13366                                 error "sumsquare is too small: $sumsq"
13367                         (( $sumsq <= $fsize * $fsize )) ||
13368                                 error "sumsquare is too big: $sumsq"
13369                         ;;
13370                 ost_read|ost_write)
13371                         [[ "$unit" =~ "usec" ]] ||
13372                                 error "unit is not 'usec': $unit"
13373                         ;;
13374                 *)      ;;
13375                 esac
13376         done < $DIR/$tfile.tmp
13377
13378         #check that we actually got some stats
13379         [ "$read_bytes" ] || error "Missing read_bytes stats"
13380         [ "$write_bytes" ] || error "Missing write_bytes stats"
13381         [ "$read_bytes" != 0 ] || error "no read done"
13382         [ "$write_bytes" != 0 ] || error "no write done"
13383 }
13384 run_test 127a "verify the client stats are sane"
13385
13386 test_127b() { # bug LU-333
13387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13388         local name count samp unit min max sum sumsq
13389
13390         echo "stats before reset"
13391         $LCTL get_param llite.*.stats
13392         $LCTL set_param llite.*.stats=0
13393
13394         # perform 2 reads and writes so MAX is different from SUM.
13395         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13396         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13397         cancel_lru_locks osc
13398         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13399         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13400
13401         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13402         stack_trap "rm -f $TMP/$tfile.tmp"
13403         while read name count samp unit min max sum sumsq; do
13404                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13405                 eval $name=$count || error "Wrong proc format"
13406
13407                 case $name in
13408                 read_bytes|write_bytes)
13409                         [[ "$unit" =~ "bytes" ]] ||
13410                                 error "unit is not 'bytes': $unit"
13411                         (( $count == 2 )) || error "count is not 2: $count"
13412                         (( $min == $PAGE_SIZE )) ||
13413                                 error "min is not $PAGE_SIZE: $min"
13414                         (( $max == $PAGE_SIZE )) ||
13415                                 error "max is not $PAGE_SIZE: $max"
13416                         (( $sum == $PAGE_SIZE * 2 )) ||
13417                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13418                         ;;
13419                 read|write)
13420                         [[ "$unit" =~ "usec" ]] ||
13421                                 error "unit is not 'usec': $unit"
13422                         ;;
13423                 *)      ;;
13424                 esac
13425         done < $TMP/$tfile.tmp
13426
13427         #check that we actually got some stats
13428         [ "$read_bytes" ] || error "Missing read_bytes stats"
13429         [ "$write_bytes" ] || error "Missing write_bytes stats"
13430         [ "$read_bytes" != 0 ] || error "no read done"
13431         [ "$write_bytes" != 0 ] || error "no write done"
13432 }
13433 run_test 127b "verify the llite client stats are sane"
13434
13435 test_127c() { # LU-12394
13436         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13437         local size
13438         local bsize
13439         local reads
13440         local writes
13441         local count
13442
13443         $LCTL set_param llite.*.extents_stats=1
13444         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13445
13446         # Use two stripes so there is enough space in default config
13447         $LFS setstripe -c 2 $DIR/$tfile
13448
13449         # Extent stats start at 0-4K and go in power of two buckets
13450         # LL_HIST_START = 12 --> 2^12 = 4K
13451         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13452         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13453         # small configs
13454         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13455                 do
13456                 # Write and read, 2x each, second time at a non-zero offset
13457                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13458                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13459                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13460                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13461                 rm -f $DIR/$tfile
13462         done
13463
13464         $LCTL get_param llite.*.extents_stats
13465
13466         count=2
13467         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13468                 do
13469                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13470                                 grep -m 1 $bsize)
13471                 reads=$(echo $bucket | awk '{print $5}')
13472                 writes=$(echo $bucket | awk '{print $9}')
13473                 [ "$reads" -eq $count ] ||
13474                         error "$reads reads in < $bsize bucket, expect $count"
13475                 [ "$writes" -eq $count ] ||
13476                         error "$writes writes in < $bsize bucket, expect $count"
13477         done
13478
13479         # Test mmap write and read
13480         $LCTL set_param llite.*.extents_stats=c
13481         size=512
13482         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13483         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13484         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13485
13486         $LCTL get_param llite.*.extents_stats
13487
13488         count=$(((size*1024) / PAGE_SIZE))
13489
13490         bsize=$((2 * PAGE_SIZE / 1024))K
13491
13492         bucket=$($LCTL get_param -n llite.*.extents_stats |
13493                         grep -m 1 $bsize)
13494         reads=$(echo $bucket | awk '{print $5}')
13495         writes=$(echo $bucket | awk '{print $9}')
13496         # mmap writes fault in the page first, creating an additonal read
13497         [ "$reads" -eq $((2 * count)) ] ||
13498                 error "$reads reads in < $bsize bucket, expect $count"
13499         [ "$writes" -eq $count ] ||
13500                 error "$writes writes in < $bsize bucket, expect $count"
13501 }
13502 run_test 127c "test llite extent stats with regular & mmap i/o"
13503
13504 test_128() { # bug 15212
13505         touch $DIR/$tfile
13506         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13507                 find $DIR/$tfile
13508                 find $DIR/$tfile
13509         EOF
13510
13511         result=$(grep error $TMP/$tfile.log)
13512         rm -f $DIR/$tfile $TMP/$tfile.log
13513         [ -z "$result" ] ||
13514                 error "consecutive find's under interactive lfs failed"
13515 }
13516 run_test 128 "interactive lfs for 2 consecutive find's"
13517
13518 set_dir_limits () {
13519         local mntdev
13520         local canondev
13521         local node
13522
13523         local ldproc=/proc/fs/ldiskfs
13524         local facets=$(get_facets MDS)
13525
13526         for facet in ${facets//,/ }; do
13527                 canondev=$(ldiskfs_canon \
13528                            *.$(convert_facet2label $facet).mntdev $facet)
13529                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13530                         ldproc=/sys/fs/ldiskfs
13531                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13532                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13533         done
13534 }
13535
13536 check_mds_dmesg() {
13537         local facets=$(get_facets MDS)
13538         for facet in ${facets//,/ }; do
13539                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13540         done
13541         return 1
13542 }
13543
13544 test_129() {
13545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13546         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13547                 skip "Need MDS version with at least 2.5.56"
13548         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13549                 skip_env "ldiskfs only test"
13550         fi
13551         remote_mds_nodsh && skip "remote MDS with nodsh"
13552
13553         local ENOSPC=28
13554         local has_warning=false
13555
13556         rm -rf $DIR/$tdir
13557         mkdir -p $DIR/$tdir
13558
13559         # block size of mds1
13560         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13561         set_dir_limits $maxsize $((maxsize * 6 / 8))
13562         stack_trap "set_dir_limits 0 0"
13563         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13564         local dirsize=$(stat -c%s "$DIR/$tdir")
13565         local nfiles=0
13566         while (( $dirsize <= $maxsize )); do
13567                 $MCREATE $DIR/$tdir/file_base_$nfiles
13568                 rc=$?
13569                 # check two errors:
13570                 # ENOSPC for ext4 max_dir_size, which has been used since
13571                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13572                 if (( rc == ENOSPC )); then
13573                         set_dir_limits 0 0
13574                         echo "rc=$rc returned as expected after $nfiles files"
13575
13576                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13577                                 error "create failed w/o dir size limit"
13578
13579                         # messages may be rate limited if test is run repeatedly
13580                         check_mds_dmesg '"is approaching max"' ||
13581                                 echo "warning message should be output"
13582                         check_mds_dmesg '"has reached max"' ||
13583                                 echo "reached message should be output"
13584
13585                         dirsize=$(stat -c%s "$DIR/$tdir")
13586
13587                         [[ $dirsize -ge $maxsize ]] && return 0
13588                         error "dirsize $dirsize < $maxsize after $nfiles files"
13589                 elif (( rc != 0 )); then
13590                         break
13591                 fi
13592                 nfiles=$((nfiles + 1))
13593                 dirsize=$(stat -c%s "$DIR/$tdir")
13594         done
13595
13596         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13597 }
13598 run_test 129 "test directory size limit ========================"
13599
13600 OLDIFS="$IFS"
13601 cleanup_130() {
13602         trap 0
13603         IFS="$OLDIFS"
13604 }
13605
13606 test_130a() {
13607         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13608         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13609
13610         trap cleanup_130 EXIT RETURN
13611
13612         local fm_file=$DIR/$tfile
13613         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13614         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13615                 error "dd failed for $fm_file"
13616
13617         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13618         filefrag -ves $fm_file
13619         RC=$?
13620         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13621                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13622         [ $RC != 0 ] && error "filefrag $fm_file failed"
13623
13624         filefrag_op=$(filefrag -ve -k $fm_file |
13625                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13626         lun=$($LFS getstripe -i $fm_file)
13627
13628         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13629         IFS=$'\n'
13630         tot_len=0
13631         for line in $filefrag_op
13632         do
13633                 frag_lun=`echo $line | cut -d: -f5`
13634                 ext_len=`echo $line | cut -d: -f4`
13635                 if (( $frag_lun != $lun )); then
13636                         cleanup_130
13637                         error "FIEMAP on 1-stripe file($fm_file) failed"
13638                         return
13639                 fi
13640                 (( tot_len += ext_len ))
13641         done
13642
13643         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13644                 cleanup_130
13645                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13646                 return
13647         fi
13648
13649         cleanup_130
13650
13651         echo "FIEMAP on single striped file succeeded"
13652 }
13653 run_test 130a "FIEMAP (1-stripe file)"
13654
13655 test_130b() {
13656         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13657
13658         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13659         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13660
13661         trap cleanup_130 EXIT RETURN
13662
13663         local fm_file=$DIR/$tfile
13664         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13665                         error "setstripe on $fm_file"
13666         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13667                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13668
13669         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13670                 error "dd failed on $fm_file"
13671
13672         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13673         filefrag_op=$(filefrag -ve -k $fm_file |
13674                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13675
13676         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13677                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13678
13679         IFS=$'\n'
13680         tot_len=0
13681         num_luns=1
13682         for line in $filefrag_op
13683         do
13684                 frag_lun=$(echo $line | cut -d: -f5 |
13685                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13686                 ext_len=$(echo $line | cut -d: -f4)
13687                 if (( $frag_lun != $last_lun )); then
13688                         if (( tot_len != 1024 )); then
13689                                 cleanup_130
13690                                 error "FIEMAP on $fm_file failed; returned " \
13691                                 "len $tot_len for OST $last_lun instead of 1024"
13692                                 return
13693                         else
13694                                 (( num_luns += 1 ))
13695                                 tot_len=0
13696                         fi
13697                 fi
13698                 (( tot_len += ext_len ))
13699                 last_lun=$frag_lun
13700         done
13701         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13702                 cleanup_130
13703                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13704                         "luns or wrong len for OST $last_lun"
13705                 return
13706         fi
13707
13708         cleanup_130
13709
13710         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13711 }
13712 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13713
13714 test_130c() {
13715         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13716
13717         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13718         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13719
13720         trap cleanup_130 EXIT RETURN
13721
13722         local fm_file=$DIR/$tfile
13723         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13724         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13725                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13726
13727         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13728                         error "dd failed on $fm_file"
13729
13730         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13731         filefrag_op=$(filefrag -ve -k $fm_file |
13732                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13733
13734         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13735                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13736
13737         IFS=$'\n'
13738         tot_len=0
13739         num_luns=1
13740         for line in $filefrag_op
13741         do
13742                 frag_lun=$(echo $line | cut -d: -f5 |
13743                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13744                 ext_len=$(echo $line | cut -d: -f4)
13745                 if (( $frag_lun != $last_lun )); then
13746                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13747                         if (( logical != 512 )); then
13748                                 cleanup_130
13749                                 error "FIEMAP on $fm_file failed; returned " \
13750                                 "logical start for lun $logical instead of 512"
13751                                 return
13752                         fi
13753                         if (( tot_len != 512 )); then
13754                                 cleanup_130
13755                                 error "FIEMAP on $fm_file failed; returned " \
13756                                 "len $tot_len for OST $last_lun instead of 1024"
13757                                 return
13758                         else
13759                                 (( num_luns += 1 ))
13760                                 tot_len=0
13761                         fi
13762                 fi
13763                 (( tot_len += ext_len ))
13764                 last_lun=$frag_lun
13765         done
13766         if (( num_luns != 2 || tot_len != 512 )); then
13767                 cleanup_130
13768                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13769                         "luns or wrong len for OST $last_lun"
13770                 return
13771         fi
13772
13773         cleanup_130
13774
13775         echo "FIEMAP on 2-stripe file with hole succeeded"
13776 }
13777 run_test 130c "FIEMAP (2-stripe file with hole)"
13778
13779 test_130d() {
13780         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13781
13782         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13783         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13784
13785         trap cleanup_130 EXIT RETURN
13786
13787         local fm_file=$DIR/$tfile
13788         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13789                         error "setstripe on $fm_file"
13790         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13791                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13792
13793         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13794         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13795                 error "dd failed on $fm_file"
13796
13797         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13798         filefrag_op=$(filefrag -ve -k $fm_file |
13799                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13800
13801         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13802                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13803
13804         IFS=$'\n'
13805         tot_len=0
13806         num_luns=1
13807         for line in $filefrag_op
13808         do
13809                 frag_lun=$(echo $line | cut -d: -f5 |
13810                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13811                 ext_len=$(echo $line | cut -d: -f4)
13812                 if (( $frag_lun != $last_lun )); then
13813                         if (( tot_len != 1024 )); then
13814                                 cleanup_130
13815                                 error "FIEMAP on $fm_file failed; returned " \
13816                                 "len $tot_len for OST $last_lun instead of 1024"
13817                                 return
13818                         else
13819                                 (( num_luns += 1 ))
13820                                 tot_len=0
13821                         fi
13822                 fi
13823                 (( tot_len += ext_len ))
13824                 last_lun=$frag_lun
13825         done
13826         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13827                 cleanup_130
13828                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13829                         "luns or wrong len for OST $last_lun"
13830                 return
13831         fi
13832
13833         cleanup_130
13834
13835         echo "FIEMAP on N-stripe file succeeded"
13836 }
13837 run_test 130d "FIEMAP (N-stripe file)"
13838
13839 test_130e() {
13840         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13841
13842         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13843         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13844
13845         trap cleanup_130 EXIT RETURN
13846
13847         local fm_file=$DIR/$tfile
13848         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13849
13850         NUM_BLKS=512
13851         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13852         for ((i = 0; i < $NUM_BLKS; i++)); do
13853                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13854                         conv=notrunc > /dev/null 2>&1
13855         done
13856
13857         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13858         filefrag_op=$(filefrag -ve -k $fm_file |
13859                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13860
13861         last_lun=$(echo $filefrag_op | cut -d: -f5)
13862
13863         IFS=$'\n'
13864         tot_len=0
13865         num_luns=1
13866         for line in $filefrag_op; do
13867                 frag_lun=$(echo $line | cut -d: -f5)
13868                 ext_len=$(echo $line | cut -d: -f4)
13869                 if [[ "$frag_lun" != "$last_lun" ]]; then
13870                         if (( tot_len != $EXPECTED_LEN )); then
13871                                 cleanup_130
13872                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13873                         else
13874                                 (( num_luns += 1 ))
13875                                 tot_len=0
13876                         fi
13877                 fi
13878                 (( tot_len += ext_len ))
13879                 last_lun=$frag_lun
13880         done
13881         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13882                 cleanup_130
13883                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13884         fi
13885
13886         echo "FIEMAP with continuation calls succeeded"
13887 }
13888 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13889
13890 test_130f() {
13891         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13892         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13893
13894         local fm_file=$DIR/$tfile
13895         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13896                 error "multiop create with lov_delay_create on $fm_file"
13897
13898         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13899         filefrag_extents=$(filefrag -vek $fm_file |
13900                            awk '/extents? found/ { print $2 }')
13901         if [[ "$filefrag_extents" != "0" ]]; then
13902                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13903         fi
13904
13905         rm -f $fm_file
13906 }
13907 run_test 130f "FIEMAP (unstriped file)"
13908
13909 test_130g() {
13910         local file=$DIR/$tfile
13911         local nr=$((OSTCOUNT * 100))
13912
13913         $LFS setstripe -C $nr $file ||
13914                 error "failed to setstripe -C $nr $file"
13915
13916         dd if=/dev/zero of=$file count=$nr bs=1M
13917         sync
13918         nr=$($LFS getstripe -c $file)
13919
13920         local extents=$(filefrag -v $file |
13921                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13922
13923         echo "filefrag list $extents extents in file with stripecount $nr"
13924         if (( extents < nr )); then
13925                 $LFS getstripe $file
13926                 filefrag -v $file
13927                 error "filefrag printed $extents < $nr extents"
13928         fi
13929
13930         rm -f $file
13931 }
13932 run_test 130g "FIEMAP (overstripe file)"
13933
13934 # Test for writev/readv
13935 test_131a() {
13936         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13937                 error "writev test failed"
13938         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13939                 error "readv failed"
13940         rm -f $DIR/$tfile
13941 }
13942 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13943
13944 test_131b() {
13945         local fsize=$((524288 + 1048576 + 1572864))
13946         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13947                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13948                         error "append writev test failed"
13949
13950         ((fsize += 1572864 + 1048576))
13951         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13952                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13953                         error "append writev test failed"
13954         rm -f $DIR/$tfile
13955 }
13956 run_test 131b "test append writev"
13957
13958 test_131c() {
13959         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13960         error "NOT PASS"
13961 }
13962 run_test 131c "test read/write on file w/o objects"
13963
13964 test_131d() {
13965         rwv -f $DIR/$tfile -w -n 1 1572864
13966         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13967         if [ "$NOB" != 1572864 ]; then
13968                 error "Short read filed: read $NOB bytes instead of 1572864"
13969         fi
13970         rm -f $DIR/$tfile
13971 }
13972 run_test 131d "test short read"
13973
13974 test_131e() {
13975         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13976         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13977         error "read hitting hole failed"
13978         rm -f $DIR/$tfile
13979 }
13980 run_test 131e "test read hitting hole"
13981
13982 check_stats() {
13983         local facet=$1
13984         local op=$2
13985         local want=${3:-0}
13986         local res
13987
13988         case $facet in
13989         mds*) res=$(do_facet $facet \
13990                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13991                  ;;
13992         ost*) res=$(do_facet $facet \
13993                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13994                  ;;
13995         *) error "Wrong facet '$facet'" ;;
13996         esac
13997         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13998         # if the argument $3 is zero, it means any stat increment is ok.
13999         if [[ $want -gt 0 ]]; then
14000                 local count=$(echo $res | awk '{ print $2 }')
14001                 [[ $count -ne $want ]] &&
14002                         error "The $op counter on $facet is $count, not $want"
14003         fi
14004 }
14005
14006 test_133a() {
14007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14008         remote_ost_nodsh && skip "remote OST with nodsh"
14009         remote_mds_nodsh && skip "remote MDS with nodsh"
14010         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14011                 skip_env "MDS doesn't support rename stats"
14012
14013         local testdir=$DIR/${tdir}/stats_testdir
14014
14015         mkdir -p $DIR/${tdir}
14016
14017         # clear stats.
14018         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14019         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14020
14021         # verify mdt stats first.
14022         mkdir ${testdir} || error "mkdir failed"
14023         check_stats $SINGLEMDS "mkdir" 1
14024         touch ${testdir}/${tfile} || error "touch failed"
14025         check_stats $SINGLEMDS "open" 1
14026         check_stats $SINGLEMDS "close" 1
14027         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14028                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14029                 check_stats $SINGLEMDS "mknod" 2
14030         }
14031         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14032         check_stats $SINGLEMDS "unlink" 1
14033         rm -f ${testdir}/${tfile} || error "file remove failed"
14034         check_stats $SINGLEMDS "unlink" 2
14035
14036         # remove working dir and check mdt stats again.
14037         rmdir ${testdir} || error "rmdir failed"
14038         check_stats $SINGLEMDS "rmdir" 1
14039
14040         local testdir1=$DIR/${tdir}/stats_testdir1
14041         mkdir -p ${testdir}
14042         mkdir -p ${testdir1}
14043         touch ${testdir1}/test1
14044         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14045         check_stats $SINGLEMDS "crossdir_rename" 1
14046
14047         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14048         check_stats $SINGLEMDS "samedir_rename" 1
14049
14050         rm -rf $DIR/${tdir}
14051 }
14052 run_test 133a "Verifying MDT stats ========================================"
14053
14054 test_133b() {
14055         local res
14056
14057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14058         remote_ost_nodsh && skip "remote OST with nodsh"
14059         remote_mds_nodsh && skip "remote MDS with nodsh"
14060
14061         local testdir=$DIR/${tdir}/stats_testdir
14062
14063         mkdir -p ${testdir} || error "mkdir failed"
14064         touch ${testdir}/${tfile} || error "touch failed"
14065         cancel_lru_locks mdc
14066
14067         # clear stats.
14068         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14069         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14070
14071         # extra mdt stats verification.
14072         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14073         check_stats $SINGLEMDS "setattr" 1
14074         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14075         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14076         then            # LU-1740
14077                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14078                 check_stats $SINGLEMDS "getattr" 1
14079         fi
14080         rm -rf $DIR/${tdir}
14081
14082         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14083         # so the check below is not reliable
14084         [ $MDSCOUNT -eq 1 ] || return 0
14085
14086         # Sleep to avoid a cached response.
14087         #define OBD_STATFS_CACHE_SECONDS 1
14088         sleep 2
14089         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14090         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14091         $LFS df || error "lfs failed"
14092         check_stats $SINGLEMDS "statfs" 1
14093
14094         # check aggregated statfs (LU-10018)
14095         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14096                 return 0
14097         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14098                 return 0
14099         sleep 2
14100         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14101         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14102         df $DIR
14103         check_stats $SINGLEMDS "statfs" 1
14104
14105         # We want to check that the client didn't send OST_STATFS to
14106         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14107         # extra care is needed here.
14108         if remote_mds; then
14109                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14110                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14111
14112                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14113                 [ "$res" ] && error "OST got STATFS"
14114         fi
14115
14116         return 0
14117 }
14118 run_test 133b "Verifying extra MDT stats =================================="
14119
14120 test_133c() {
14121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14122         remote_ost_nodsh && skip "remote OST with nodsh"
14123         remote_mds_nodsh && skip "remote MDS with nodsh"
14124
14125         local testdir=$DIR/$tdir/stats_testdir
14126
14127         test_mkdir -p $testdir
14128
14129         # verify obdfilter stats.
14130         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14131         sync
14132         cancel_lru_locks osc
14133         wait_delete_completed
14134
14135         # clear stats.
14136         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14137         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14138
14139         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14140                 error "dd failed"
14141         sync
14142         cancel_lru_locks osc
14143         check_stats ost1 "write" 1
14144
14145         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14146         check_stats ost1 "read" 1
14147
14148         > $testdir/$tfile || error "truncate failed"
14149         check_stats ost1 "punch" 1
14150
14151         rm -f $testdir/$tfile || error "file remove failed"
14152         wait_delete_completed
14153         check_stats ost1 "destroy" 1
14154
14155         rm -rf $DIR/$tdir
14156 }
14157 run_test 133c "Verifying OST stats ========================================"
14158
14159 order_2() {
14160         local value=$1
14161         local orig=$value
14162         local order=1
14163
14164         while [ $value -ge 2 ]; do
14165                 order=$((order*2))
14166                 value=$((value/2))
14167         done
14168
14169         if [ $orig -gt $order ]; then
14170                 order=$((order*2))
14171         fi
14172         echo $order
14173 }
14174
14175 size_in_KMGT() {
14176     local value=$1
14177     local size=('K' 'M' 'G' 'T');
14178     local i=0
14179     local size_string=$value
14180
14181     while [ $value -ge 1024 ]; do
14182         if [ $i -gt 3 ]; then
14183             #T is the biggest unit we get here, if that is bigger,
14184             #just return XXXT
14185             size_string=${value}T
14186             break
14187         fi
14188         value=$((value >> 10))
14189         if [ $value -lt 1024 ]; then
14190             size_string=${value}${size[$i]}
14191             break
14192         fi
14193         i=$((i + 1))
14194     done
14195
14196     echo $size_string
14197 }
14198
14199 get_rename_size() {
14200         local size=$1
14201         local context=${2:-.}
14202         local sample=$(do_facet $SINGLEMDS $LCTL \
14203                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14204                 grep -A1 $context |
14205                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14206         echo $sample
14207 }
14208
14209 test_133d() {
14210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14211         remote_ost_nodsh && skip "remote OST with nodsh"
14212         remote_mds_nodsh && skip "remote MDS with nodsh"
14213         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14214                 skip_env "MDS doesn't support rename stats"
14215
14216         local testdir1=$DIR/${tdir}/stats_testdir1
14217         local testdir2=$DIR/${tdir}/stats_testdir2
14218         mkdir -p $DIR/${tdir}
14219
14220         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14221
14222         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14223         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14224
14225         createmany -o $testdir1/test 512 || error "createmany failed"
14226
14227         # check samedir rename size
14228         mv ${testdir1}/test0 ${testdir1}/test_0
14229
14230         local testdir1_size=$(ls -l $DIR/${tdir} |
14231                 awk '/stats_testdir1/ {print $5}')
14232         local testdir2_size=$(ls -l $DIR/${tdir} |
14233                 awk '/stats_testdir2/ {print $5}')
14234
14235         testdir1_size=$(order_2 $testdir1_size)
14236         testdir2_size=$(order_2 $testdir2_size)
14237
14238         testdir1_size=$(size_in_KMGT $testdir1_size)
14239         testdir2_size=$(size_in_KMGT $testdir2_size)
14240
14241         echo "source rename dir size: ${testdir1_size}"
14242         echo "target rename dir size: ${testdir2_size}"
14243
14244         local cmd="do_facet $SINGLEMDS $LCTL "
14245         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14246
14247         eval $cmd || error "$cmd failed"
14248         local samedir=$($cmd | grep 'same_dir')
14249         local same_sample=$(get_rename_size $testdir1_size)
14250         [ -z "$samedir" ] && error "samedir_rename_size count error"
14251         [[ $same_sample -eq 1 ]] ||
14252                 error "samedir_rename_size error $same_sample"
14253         echo "Check same dir rename stats success"
14254
14255         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14256
14257         # check crossdir rename size
14258         mv ${testdir1}/test_0 ${testdir2}/test_0
14259
14260         testdir1_size=$(ls -l $DIR/${tdir} |
14261                 awk '/stats_testdir1/ {print $5}')
14262         testdir2_size=$(ls -l $DIR/${tdir} |
14263                 awk '/stats_testdir2/ {print $5}')
14264
14265         testdir1_size=$(order_2 $testdir1_size)
14266         testdir2_size=$(order_2 $testdir2_size)
14267
14268         testdir1_size=$(size_in_KMGT $testdir1_size)
14269         testdir2_size=$(size_in_KMGT $testdir2_size)
14270
14271         echo "source rename dir size: ${testdir1_size}"
14272         echo "target rename dir size: ${testdir2_size}"
14273
14274         eval $cmd || error "$cmd failed"
14275         local crossdir=$($cmd | grep 'crossdir')
14276         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14277         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14278         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14279         [[ $src_sample -eq 1 ]] ||
14280                 error "crossdir_rename_size error $src_sample"
14281         [[ $tgt_sample -eq 1 ]] ||
14282                 error "crossdir_rename_size error $tgt_sample"
14283         echo "Check cross dir rename stats success"
14284         rm -rf $DIR/${tdir}
14285 }
14286 run_test 133d "Verifying rename_stats ========================================"
14287
14288 test_133e() {
14289         remote_mds_nodsh && skip "remote MDS with nodsh"
14290         remote_ost_nodsh && skip "remote OST with nodsh"
14291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14292
14293         local testdir=$DIR/${tdir}/stats_testdir
14294         local ctr f0 f1 bs=32768 count=42 sum
14295
14296         mkdir -p ${testdir} || error "mkdir failed"
14297
14298         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14299
14300         for ctr in {write,read}_bytes; do
14301                 sync
14302                 cancel_lru_locks osc
14303
14304                 do_facet ost1 $LCTL set_param -n \
14305                         "obdfilter.*.exports.clear=clear"
14306
14307                 if [ $ctr = write_bytes ]; then
14308                         f0=/dev/zero
14309                         f1=${testdir}/${tfile}
14310                 else
14311                         f0=${testdir}/${tfile}
14312                         f1=/dev/null
14313                 fi
14314
14315                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14316                         error "dd failed"
14317                 sync
14318                 cancel_lru_locks osc
14319
14320                 sum=$(do_facet ost1 $LCTL get_param \
14321                         "obdfilter.*.exports.*.stats" |
14322                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14323                                 $1 == ctr { sum += $7 }
14324                                 END { printf("%0.0f", sum) }')
14325
14326                 if ((sum != bs * count)); then
14327                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14328                 fi
14329         done
14330
14331         rm -rf $DIR/${tdir}
14332 }
14333 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14334
14335 test_133f() {
14336         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14337                 skip "too old lustre for get_param -R ($facet_ver)"
14338
14339         # verifying readability.
14340         $LCTL get_param -R '*' &> /dev/null
14341
14342         # Verifing writability with badarea_io.
14343         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14344         local skipped_params='force_lbug|changelog_mask|daemon_file'
14345         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14346                 egrep -v "$skipped_params" |
14347                 xargs -n 1 find $proc_dirs -name |
14348                 xargs -n 1 badarea_io ||
14349                 error "client badarea_io failed"
14350
14351         # remount the FS in case writes/reads /proc break the FS
14352         cleanup || error "failed to unmount"
14353         setup || error "failed to setup"
14354 }
14355 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14356
14357 test_133g() {
14358         remote_mds_nodsh && skip "remote MDS with nodsh"
14359         remote_ost_nodsh && skip "remote OST with nodsh"
14360
14361         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14362         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14363         local facet
14364         for facet in mds1 ost1; do
14365                 local facet_ver=$(lustre_version_code $facet)
14366                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14367                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14368                 else
14369                         log "$facet: too old lustre for get_param -R"
14370                 fi
14371                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14372                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14373                                 tr -d = | egrep -v $skipped_params |
14374                                 xargs -n 1 find $proc_dirs -name |
14375                                 xargs -n 1 badarea_io" ||
14376                                         error "$facet badarea_io failed"
14377                 else
14378                         skip_noexit "$facet: too old lustre for get_param -R"
14379                 fi
14380         done
14381
14382         # remount the FS in case writes/reads /proc break the FS
14383         cleanup || error "failed to unmount"
14384         setup || error "failed to setup"
14385 }
14386 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14387
14388 test_133h() {
14389         remote_mds_nodsh && skip "remote MDS with nodsh"
14390         remote_ost_nodsh && skip "remote OST with nodsh"
14391         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14392                 skip "Need MDS version at least 2.9.54"
14393
14394         local facet
14395         for facet in client mds1 ost1; do
14396                 # Get the list of files that are missing the terminating newline
14397                 local plist=$(do_facet $facet
14398                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14399                 local ent
14400                 for ent in $plist; do
14401                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14402                                 awk -v FS='\v' -v RS='\v\v' \
14403                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14404                                         print FILENAME}'" 2>/dev/null)
14405                         [ -z $missing ] || {
14406                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14407                                 error "file does not end with newline: $facet-$ent"
14408                         }
14409                 done
14410         done
14411 }
14412 run_test 133h "Proc files should end with newlines"
14413
14414 test_134a() {
14415         remote_mds_nodsh && skip "remote MDS with nodsh"
14416         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14417                 skip "Need MDS version at least 2.7.54"
14418
14419         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14420         cancel_lru_locks mdc
14421
14422         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14423         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14424         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14425
14426         local nr=1000
14427         createmany -o $DIR/$tdir/f $nr ||
14428                 error "failed to create $nr files in $DIR/$tdir"
14429         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14430
14431         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14432         do_facet mds1 $LCTL set_param fail_loc=0x327
14433         do_facet mds1 $LCTL set_param fail_val=500
14434         touch $DIR/$tdir/m
14435
14436         echo "sleep 10 seconds ..."
14437         sleep 10
14438         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14439
14440         do_facet mds1 $LCTL set_param fail_loc=0
14441         do_facet mds1 $LCTL set_param fail_val=0
14442         [ $lck_cnt -lt $unused ] ||
14443                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14444
14445         rm $DIR/$tdir/m
14446         unlinkmany $DIR/$tdir/f $nr
14447 }
14448 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14449
14450 test_134b() {
14451         remote_mds_nodsh && skip "remote MDS with nodsh"
14452         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14453                 skip "Need MDS version at least 2.7.54"
14454
14455         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14456         cancel_lru_locks mdc
14457
14458         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14459                         ldlm.lock_reclaim_threshold_mb)
14460         # disable reclaim temporarily
14461         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14462
14463         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14464         do_facet mds1 $LCTL set_param fail_loc=0x328
14465         do_facet mds1 $LCTL set_param fail_val=500
14466
14467         $LCTL set_param debug=+trace
14468
14469         local nr=600
14470         createmany -o $DIR/$tdir/f $nr &
14471         local create_pid=$!
14472
14473         echo "Sleep $TIMEOUT seconds ..."
14474         sleep $TIMEOUT
14475         if ! ps -p $create_pid  > /dev/null 2>&1; then
14476                 do_facet mds1 $LCTL set_param fail_loc=0
14477                 do_facet mds1 $LCTL set_param fail_val=0
14478                 do_facet mds1 $LCTL set_param \
14479                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14480                 error "createmany finished incorrectly!"
14481         fi
14482         do_facet mds1 $LCTL set_param fail_loc=0
14483         do_facet mds1 $LCTL set_param fail_val=0
14484         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14485         wait $create_pid || return 1
14486
14487         unlinkmany $DIR/$tdir/f $nr
14488 }
14489 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14490
14491 test_135() {
14492         remote_mds_nodsh && skip "remote MDS with nodsh"
14493         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14494                 skip "Need MDS version at least 2.13.50"
14495         local fname
14496
14497         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14498
14499 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14500         #set only one record at plain llog
14501         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14502
14503         #fill already existed plain llog each 64767
14504         #wrapping whole catalog
14505         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14506
14507         createmany -o $DIR/$tdir/$tfile_ 64700
14508         for (( i = 0; i < 64700; i = i + 2 ))
14509         do
14510                 rm $DIR/$tdir/$tfile_$i &
14511                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14512                 local pid=$!
14513                 wait $pid
14514         done
14515
14516         #waiting osp synchronization
14517         wait_delete_completed
14518 }
14519 run_test 135 "Race catalog processing"
14520
14521 test_136() {
14522         remote_mds_nodsh && skip "remote MDS with nodsh"
14523         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14524                 skip "Need MDS version at least 2.13.50"
14525         local fname
14526
14527         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14528         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14529         #set only one record at plain llog
14530 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14531         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14532
14533         #fill already existed 2 plain llogs each 64767
14534         #wrapping whole catalog
14535         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14536         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14537         wait_delete_completed
14538
14539         createmany -o $DIR/$tdir/$tfile_ 10
14540         sleep 25
14541
14542         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14543         for (( i = 0; i < 10; i = i + 3 ))
14544         do
14545                 rm $DIR/$tdir/$tfile_$i &
14546                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14547                 local pid=$!
14548                 wait $pid
14549                 sleep 7
14550                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14551         done
14552
14553         #waiting osp synchronization
14554         wait_delete_completed
14555 }
14556 run_test 136 "Race catalog processing 2"
14557
14558 test_140() { #bug-17379
14559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14560
14561         test_mkdir $DIR/$tdir
14562         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14563         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14564
14565         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14566         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14567         local i=0
14568         while i=$((i + 1)); do
14569                 test_mkdir $i
14570                 cd $i || error "Changing to $i"
14571                 ln -s ../stat stat || error "Creating stat symlink"
14572                 # Read the symlink until ELOOP present,
14573                 # not LBUGing the system is considered success,
14574                 # we didn't overrun the stack.
14575                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14576                 if [ $ret -ne 0 ]; then
14577                         if [ $ret -eq 40 ]; then
14578                                 break  # -ELOOP
14579                         else
14580                                 error "Open stat symlink"
14581                                         return
14582                         fi
14583                 fi
14584         done
14585         i=$((i - 1))
14586         echo "The symlink depth = $i"
14587         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14588                 error "Invalid symlink depth"
14589
14590         # Test recursive symlink
14591         ln -s symlink_self symlink_self
14592         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14593         echo "open symlink_self returns $ret"
14594         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14595 }
14596 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14597
14598 test_150a() {
14599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14600
14601         local TF="$TMP/$tfile"
14602
14603         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14604         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14605         cp $TF $DIR/$tfile
14606         cancel_lru_locks $OSC
14607         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14608         remount_client $MOUNT
14609         df -P $MOUNT
14610         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14611
14612         $TRUNCATE $TF 6000
14613         $TRUNCATE $DIR/$tfile 6000
14614         cancel_lru_locks $OSC
14615         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14616
14617         echo "12345" >>$TF
14618         echo "12345" >>$DIR/$tfile
14619         cancel_lru_locks $OSC
14620         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14621
14622         echo "12345" >>$TF
14623         echo "12345" >>$DIR/$tfile
14624         cancel_lru_locks $OSC
14625         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14626 }
14627 run_test 150a "truncate/append tests"
14628
14629 test_150b() {
14630         check_set_fallocate_or_skip
14631
14632         touch $DIR/$tfile
14633         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14634         check_fallocate $DIR/$tfile || error "fallocate failed"
14635 }
14636 run_test 150b "Verify fallocate (prealloc) functionality"
14637
14638 test_150bb() {
14639         check_set_fallocate_or_skip
14640
14641         touch $DIR/$tfile
14642         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14643         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14644         > $DIR/$tfile
14645         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14646         # precomputed md5sum for 20MB of zeroes
14647         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14648         local sum=($(md5sum $DIR/$tfile))
14649
14650         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14651
14652         check_set_fallocate 1
14653
14654         > $DIR/$tfile
14655         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14656         sum=($(md5sum $DIR/$tfile))
14657
14658         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14659 }
14660 run_test 150bb "Verify fallocate modes both zero space"
14661
14662 test_150c() {
14663         check_set_fallocate_or_skip
14664         local striping="-c2"
14665
14666         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14667         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14668         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14669         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14670         local want=$((OSTCOUNT * 1048576))
14671
14672         # Must allocate all requested space, not more than 5% extra
14673         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14674                 error "bytes $bytes is not $want"
14675
14676         rm -f $DIR/$tfile
14677
14678         echo "verify fallocate on PFL file"
14679
14680         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14681
14682         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14683                 error "Create $DIR/$tfile failed"
14684         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14685                         error "fallocate failed"
14686         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14687         want=$((512 * 1048576))
14688
14689         # Must allocate all requested space, not more than 5% extra
14690         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14691                 error "bytes $bytes is not $want"
14692 }
14693 run_test 150c "Verify fallocate Size and Blocks"
14694
14695 test_150d() {
14696         check_set_fallocate_or_skip
14697         local striping="-c2"
14698
14699         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14700
14701         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14702         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14703                 error "setstripe failed"
14704         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14705         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14706         local want=$((OSTCOUNT * 1048576))
14707
14708         # Must allocate all requested space, not more than 5% extra
14709         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14710                 error "bytes $bytes is not $want"
14711 }
14712 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14713
14714 test_150e() {
14715         check_set_fallocate_or_skip
14716
14717         echo "df before:"
14718         $LFS df
14719         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14720         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14721                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14722
14723         # Find OST with Minimum Size
14724         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14725                        sort -un | head -1)
14726
14727         # Get 100MB per OST of the available space to reduce run time
14728         # else 60% of the available space if we are running SLOW tests
14729         if [ $SLOW == "no" ]; then
14730                 local space=$((1024 * 100 * OSTCOUNT))
14731         else
14732                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14733         fi
14734
14735         fallocate -l${space}k $DIR/$tfile ||
14736                 error "fallocate ${space}k $DIR/$tfile failed"
14737         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14738
14739         # get size immediately after fallocate. This should be correctly
14740         # updated
14741         local size=$(stat -c '%s' $DIR/$tfile)
14742         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14743
14744         # Sleep for a while for statfs to get updated. And not pull from cache.
14745         sleep 2
14746
14747         echo "df after fallocate:"
14748         $LFS df
14749
14750         (( size / 1024 == space )) || error "size $size != requested $space"
14751         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14752                 error "used $used < space $space"
14753
14754         rm $DIR/$tfile || error "rm failed"
14755         sync
14756         wait_delete_completed
14757
14758         echo "df after unlink:"
14759         $LFS df
14760 }
14761 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14762
14763 test_150f() {
14764         local size
14765         local blocks
14766         local want_size_before=20480 # in bytes
14767         local want_blocks_before=40 # 512 sized blocks
14768         local want_blocks_after=24  # 512 sized blocks
14769         local length=$(((want_blocks_before - want_blocks_after) * 512))
14770
14771         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14772                 skip "need at least 2.14.0 for fallocate punch"
14773
14774         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14775                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14776         fi
14777
14778         check_set_fallocate_or_skip
14779         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14780
14781         [[ "x$DOM" == "xyes" ]] &&
14782                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14783
14784         echo "Verify fallocate punch: Range within the file range"
14785         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14786                 error "dd failed for bs 4096 and count 5"
14787
14788         # Call fallocate with punch range which is within the file range
14789         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14790                 error "fallocate failed: offset 4096 and length $length"
14791         # client must see changes immediately after fallocate
14792         size=$(stat -c '%s' $DIR/$tfile)
14793         blocks=$(stat -c '%b' $DIR/$tfile)
14794
14795         # Verify punch worked.
14796         (( blocks == want_blocks_after )) ||
14797                 error "punch failed: blocks $blocks != $want_blocks_after"
14798
14799         (( size == want_size_before )) ||
14800                 error "punch failed: size $size != $want_size_before"
14801
14802         # Verify there is hole in file
14803         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14804         # precomputed md5sum
14805         local expect="4a9a834a2db02452929c0a348273b4aa"
14806
14807         cksum=($(md5sum $DIR/$tfile))
14808         [[ "${cksum[0]}" == "$expect" ]] ||
14809                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14810
14811         # Start second sub-case for fallocate punch.
14812         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14813         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14814                 error "dd failed for bs 4096 and count 5"
14815
14816         # Punch range less than block size will have no change in block count
14817         want_blocks_after=40  # 512 sized blocks
14818
14819         # Punch overlaps two blocks and less than blocksize
14820         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14821                 error "fallocate failed: offset 4000 length 3000"
14822         size=$(stat -c '%s' $DIR/$tfile)
14823         blocks=$(stat -c '%b' $DIR/$tfile)
14824
14825         # Verify punch worked.
14826         (( blocks == want_blocks_after )) ||
14827                 error "punch failed: blocks $blocks != $want_blocks_after"
14828
14829         (( size == want_size_before )) ||
14830                 error "punch failed: size $size != $want_size_before"
14831
14832         # Verify if range is really zero'ed out. We expect Zeros.
14833         # precomputed md5sum
14834         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14835         cksum=($(md5sum $DIR/$tfile))
14836         [[ "${cksum[0]}" == "$expect" ]] ||
14837                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14838 }
14839 run_test 150f "Verify fallocate punch functionality"
14840
14841 test_150g() {
14842         local space
14843         local size
14844         local blocks
14845         local blocks_after
14846         local size_after
14847         local BS=4096 # Block size in bytes
14848
14849         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14850                 skip "need at least 2.14.0 for fallocate punch"
14851
14852         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14853                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14854         fi
14855
14856         check_set_fallocate_or_skip
14857         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14858
14859         if [[ "x$DOM" == "xyes" ]]; then
14860                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14861                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14862         else
14863                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14864                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14865         fi
14866
14867         # Get 100MB per OST of the available space to reduce run time
14868         # else 60% of the available space if we are running SLOW tests
14869         if [ $SLOW == "no" ]; then
14870                 space=$((1024 * 100 * OSTCOUNT))
14871         else
14872                 # Find OST with Minimum Size
14873                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14874                         sort -un | head -1)
14875                 echo "min size OST: $space"
14876                 space=$(((space * 60)/100 * OSTCOUNT))
14877         fi
14878         # space in 1k units, round to 4k blocks
14879         local blkcount=$((space * 1024 / $BS))
14880
14881         echo "Verify fallocate punch: Very large Range"
14882         fallocate -l${space}k $DIR/$tfile ||
14883                 error "fallocate ${space}k $DIR/$tfile failed"
14884         # write 1M at the end, start and in the middle
14885         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14886                 error "dd failed: bs $BS count 256"
14887         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14888                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14889         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14890                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14891
14892         # Gather stats.
14893         size=$(stat -c '%s' $DIR/$tfile)
14894
14895         # gather punch length.
14896         local punch_size=$((size - (BS * 2)))
14897
14898         echo "punch_size = $punch_size"
14899         echo "size - punch_size: $((size - punch_size))"
14900         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14901
14902         # Call fallocate to punch all except 2 blocks. We leave the
14903         # first and the last block
14904         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14905         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14906                 error "fallocate failed: offset $BS length $punch_size"
14907
14908         size_after=$(stat -c '%s' $DIR/$tfile)
14909         blocks_after=$(stat -c '%b' $DIR/$tfile)
14910
14911         # Verify punch worked.
14912         # Size should be kept
14913         (( size == size_after )) ||
14914                 error "punch failed: size $size != $size_after"
14915
14916         # two 4k data blocks to remain plus possible 1 extra extent block
14917         (( blocks_after <= ((BS / 512) * 3) )) ||
14918                 error "too many blocks remains: $blocks_after"
14919
14920         # Verify that file has hole between the first and the last blocks
14921         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14922         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14923
14924         echo "Hole at [$hole_start, $hole_end)"
14925         (( hole_start == BS )) ||
14926                 error "no hole at offset $BS after punch"
14927
14928         (( hole_end == BS + punch_size )) ||
14929                 error "data at offset $hole_end < $((BS + punch_size))"
14930 }
14931 run_test 150g "Verify fallocate punch on large range"
14932
14933 #LU-2902 roc_hit was not able to read all values from lproc
14934 function roc_hit_init() {
14935         local list=$(comma_list $(osts_nodes))
14936         local dir=$DIR/$tdir-check
14937         local file=$dir/$tfile
14938         local BEFORE
14939         local AFTER
14940         local idx
14941
14942         test_mkdir $dir
14943         #use setstripe to do a write to every ost
14944         for i in $(seq 0 $((OSTCOUNT-1))); do
14945                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14946                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14947                 idx=$(printf %04x $i)
14948                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14949                         awk '$1 == "cache_access" {sum += $7}
14950                                 END { printf("%0.0f", sum) }')
14951
14952                 cancel_lru_locks osc
14953                 cat $file >/dev/null
14954
14955                 AFTER=$(get_osd_param $list *OST*$idx stats |
14956                         awk '$1 == "cache_access" {sum += $7}
14957                                 END { printf("%0.0f", sum) }')
14958
14959                 echo BEFORE:$BEFORE AFTER:$AFTER
14960                 if ! let "AFTER - BEFORE == 4"; then
14961                         rm -rf $dir
14962                         error "roc_hit is not safe to use"
14963                 fi
14964                 rm $file
14965         done
14966
14967         rm -rf $dir
14968 }
14969
14970 function roc_hit() {
14971         local list=$(comma_list $(osts_nodes))
14972         echo $(get_osd_param $list '' stats |
14973                 awk '$1 == "cache_hit" {sum += $7}
14974                         END { printf("%0.0f", sum) }')
14975 }
14976
14977 function set_cache() {
14978         local on=1
14979
14980         if [ "$2" == "off" ]; then
14981                 on=0;
14982         fi
14983         local list=$(comma_list $(osts_nodes))
14984         set_osd_param $list '' $1_cache_enable $on
14985
14986         cancel_lru_locks osc
14987 }
14988
14989 test_151() {
14990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14991         remote_ost_nodsh && skip "remote OST with nodsh"
14992
14993         local CPAGES=3
14994         local list=$(comma_list $(osts_nodes))
14995
14996         # check whether obdfilter is cache capable at all
14997         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14998                 skip "not cache-capable obdfilter"
14999         fi
15000
15001         # check cache is enabled on all obdfilters
15002         if get_osd_param $list '' read_cache_enable | grep 0; then
15003                 skip "oss cache is disabled"
15004         fi
15005
15006         set_osd_param $list '' writethrough_cache_enable 1
15007
15008         # check write cache is enabled on all obdfilters
15009         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15010                 skip "oss write cache is NOT enabled"
15011         fi
15012
15013         roc_hit_init
15014
15015         #define OBD_FAIL_OBD_NO_LRU  0x609
15016         do_nodes $list $LCTL set_param fail_loc=0x609
15017
15018         # pages should be in the case right after write
15019         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15020                 error "dd failed"
15021
15022         local BEFORE=$(roc_hit)
15023         cancel_lru_locks osc
15024         cat $DIR/$tfile >/dev/null
15025         local AFTER=$(roc_hit)
15026
15027         do_nodes $list $LCTL set_param fail_loc=0
15028
15029         if ! let "AFTER - BEFORE == CPAGES"; then
15030                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15031         fi
15032
15033         cancel_lru_locks osc
15034         # invalidates OST cache
15035         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15036         set_osd_param $list '' read_cache_enable 0
15037         cat $DIR/$tfile >/dev/null
15038
15039         # now data shouldn't be found in the cache
15040         BEFORE=$(roc_hit)
15041         cancel_lru_locks osc
15042         cat $DIR/$tfile >/dev/null
15043         AFTER=$(roc_hit)
15044         if let "AFTER - BEFORE != 0"; then
15045                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15046         fi
15047
15048         set_osd_param $list '' read_cache_enable 1
15049         rm -f $DIR/$tfile
15050 }
15051 run_test 151 "test cache on oss and controls ==============================="
15052
15053 test_152() {
15054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15055
15056         local TF="$TMP/$tfile"
15057
15058         # simulate ENOMEM during write
15059 #define OBD_FAIL_OST_NOMEM      0x226
15060         lctl set_param fail_loc=0x80000226
15061         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15062         cp $TF $DIR/$tfile
15063         sync || error "sync failed"
15064         lctl set_param fail_loc=0
15065
15066         # discard client's cache
15067         cancel_lru_locks osc
15068
15069         # simulate ENOMEM during read
15070         lctl set_param fail_loc=0x80000226
15071         cmp $TF $DIR/$tfile || error "cmp failed"
15072         lctl set_param fail_loc=0
15073
15074         rm -f $TF
15075 }
15076 run_test 152 "test read/write with enomem ============================"
15077
15078 test_153() {
15079         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15080 }
15081 run_test 153 "test if fdatasync does not crash ======================="
15082
15083 dot_lustre_fid_permission_check() {
15084         local fid=$1
15085         local ffid=$MOUNT/.lustre/fid/$fid
15086         local test_dir=$2
15087
15088         echo "stat fid $fid"
15089         stat $ffid > /dev/null || error "stat $ffid failed."
15090         echo "touch fid $fid"
15091         touch $ffid || error "touch $ffid failed."
15092         echo "write to fid $fid"
15093         cat /etc/hosts > $ffid || error "write $ffid failed."
15094         echo "read fid $fid"
15095         diff /etc/hosts $ffid || error "read $ffid failed."
15096         echo "append write to fid $fid"
15097         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15098         echo "rename fid $fid"
15099         mv $ffid $test_dir/$tfile.1 &&
15100                 error "rename $ffid to $tfile.1 should fail."
15101         touch $test_dir/$tfile.1
15102         mv $test_dir/$tfile.1 $ffid &&
15103                 error "rename $tfile.1 to $ffid should fail."
15104         rm -f $test_dir/$tfile.1
15105         echo "truncate fid $fid"
15106         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15107         echo "link fid $fid"
15108         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15109         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15110                 echo "setfacl fid $fid"
15111                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15112                 echo "getfacl fid $fid"
15113                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15114         fi
15115         echo "unlink fid $fid"
15116         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15117         echo "mknod fid $fid"
15118         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15119
15120         fid=[0xf00000400:0x1:0x0]
15121         ffid=$MOUNT/.lustre/fid/$fid
15122
15123         echo "stat non-exist fid $fid"
15124         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15125         echo "write to non-exist fid $fid"
15126         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15127         echo "link new fid $fid"
15128         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15129
15130         mkdir -p $test_dir/$tdir
15131         touch $test_dir/$tdir/$tfile
15132         fid=$($LFS path2fid $test_dir/$tdir)
15133         rc=$?
15134         [ $rc -ne 0 ] &&
15135                 error "error: could not get fid for $test_dir/$dir/$tfile."
15136
15137         ffid=$MOUNT/.lustre/fid/$fid
15138
15139         echo "ls $fid"
15140         ls $ffid > /dev/null || error "ls $ffid failed."
15141         echo "touch $fid/$tfile.1"
15142         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15143
15144         echo "touch $MOUNT/.lustre/fid/$tfile"
15145         touch $MOUNT/.lustre/fid/$tfile && \
15146                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15147
15148         echo "setxattr to $MOUNT/.lustre/fid"
15149         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15150
15151         echo "listxattr for $MOUNT/.lustre/fid"
15152         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15153
15154         echo "delxattr from $MOUNT/.lustre/fid"
15155         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15156
15157         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15158         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15159                 error "touch invalid fid should fail."
15160
15161         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15162         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15163                 error "touch non-normal fid should fail."
15164
15165         echo "rename $tdir to $MOUNT/.lustre/fid"
15166         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15167                 error "rename to $MOUNT/.lustre/fid should fail."
15168
15169         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15170         then            # LU-3547
15171                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15172                 local new_obf_mode=777
15173
15174                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15175                 chmod $new_obf_mode $DIR/.lustre/fid ||
15176                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15177
15178                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15179                 [ $obf_mode -eq $new_obf_mode ] ||
15180                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15181
15182                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15183                 chmod $old_obf_mode $DIR/.lustre/fid ||
15184                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15185         fi
15186
15187         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15188         fid=$($LFS path2fid $test_dir/$tfile-2)
15189
15190         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15191         then # LU-5424
15192                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15193                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15194                         error "create lov data thru .lustre failed"
15195         fi
15196         echo "cp /etc/passwd $test_dir/$tfile-2"
15197         cp /etc/passwd $test_dir/$tfile-2 ||
15198                 error "copy to $test_dir/$tfile-2 failed."
15199         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15200         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15201                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15202
15203         rm -rf $test_dir/tfile.lnk
15204         rm -rf $test_dir/$tfile-2
15205 }
15206
15207 test_154A() {
15208         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15209                 skip "Need MDS version at least 2.4.1"
15210
15211         local tf=$DIR/$tfile
15212         touch $tf
15213
15214         local fid=$($LFS path2fid $tf)
15215         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15216
15217         # check that we get the same pathname back
15218         local rootpath
15219         local found
15220         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15221                 echo "$rootpath $fid"
15222                 found=$($LFS fid2path $rootpath "$fid")
15223                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15224                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15225         done
15226
15227         # check wrong root path format
15228         rootpath=$MOUNT"_wrong"
15229         found=$($LFS fid2path $rootpath "$fid")
15230         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15231 }
15232 run_test 154A "lfs path2fid and fid2path basic checks"
15233
15234 test_154B() {
15235         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15236                 skip "Need MDS version at least 2.4.1"
15237
15238         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15239         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15240         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15241         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15242
15243         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15244         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15245
15246         # check that we get the same pathname
15247         echo "PFID: $PFID, name: $name"
15248         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15249         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15250         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15251                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15252
15253         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15254 }
15255 run_test 154B "verify the ll_decode_linkea tool"
15256
15257 test_154a() {
15258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15259         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15260         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15261                 skip "Need MDS version at least 2.2.51"
15262         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15263
15264         cp /etc/hosts $DIR/$tfile
15265
15266         fid=$($LFS path2fid $DIR/$tfile)
15267         rc=$?
15268         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15269
15270         dot_lustre_fid_permission_check "$fid" $DIR ||
15271                 error "dot lustre permission check $fid failed"
15272
15273         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15274
15275         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15276
15277         touch $MOUNT/.lustre/file &&
15278                 error "creation is not allowed under .lustre"
15279
15280         mkdir $MOUNT/.lustre/dir &&
15281                 error "mkdir is not allowed under .lustre"
15282
15283         rm -rf $DIR/$tfile
15284 }
15285 run_test 154a "Open-by-FID"
15286
15287 test_154b() {
15288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15289         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15290         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15291         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15292                 skip "Need MDS version at least 2.2.51"
15293
15294         local remote_dir=$DIR/$tdir/remote_dir
15295         local MDTIDX=1
15296         local rc=0
15297
15298         mkdir -p $DIR/$tdir
15299         $LFS mkdir -i $MDTIDX $remote_dir ||
15300                 error "create remote directory failed"
15301
15302         cp /etc/hosts $remote_dir/$tfile
15303
15304         fid=$($LFS path2fid $remote_dir/$tfile)
15305         rc=$?
15306         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15307
15308         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15309                 error "dot lustre permission check $fid failed"
15310         rm -rf $DIR/$tdir
15311 }
15312 run_test 154b "Open-by-FID for remote directory"
15313
15314 test_154c() {
15315         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15316                 skip "Need MDS version at least 2.4.1"
15317
15318         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15319         local FID1=$($LFS path2fid $DIR/$tfile.1)
15320         local FID2=$($LFS path2fid $DIR/$tfile.2)
15321         local FID3=$($LFS path2fid $DIR/$tfile.3)
15322
15323         local N=1
15324         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15325                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15326                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15327                 local want=FID$N
15328                 [ "$FID" = "${!want}" ] ||
15329                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15330                 N=$((N + 1))
15331         done
15332
15333         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15334         do
15335                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15336                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15337                 N=$((N + 1))
15338         done
15339 }
15340 run_test 154c "lfs path2fid and fid2path multiple arguments"
15341
15342 test_154d() {
15343         remote_mds_nodsh && skip "remote MDS with nodsh"
15344         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15345                 skip "Need MDS version at least 2.5.53"
15346
15347         if remote_mds; then
15348                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15349         else
15350                 nid="0@lo"
15351         fi
15352         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15353         local fd
15354         local cmd
15355
15356         rm -f $DIR/$tfile
15357         touch $DIR/$tfile
15358
15359         local fid=$($LFS path2fid $DIR/$tfile)
15360         # Open the file
15361         fd=$(free_fd)
15362         cmd="exec $fd<$DIR/$tfile"
15363         eval $cmd
15364         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15365         echo "$fid_list" | grep "$fid"
15366         rc=$?
15367
15368         cmd="exec $fd>/dev/null"
15369         eval $cmd
15370         if [ $rc -ne 0 ]; then
15371                 error "FID $fid not found in open files list $fid_list"
15372         fi
15373 }
15374 run_test 154d "Verify open file fid"
15375
15376 test_154e()
15377 {
15378         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15379                 skip "Need MDS version at least 2.6.50"
15380
15381         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15382                 error ".lustre returned by readdir"
15383         fi
15384 }
15385 run_test 154e ".lustre is not returned by readdir"
15386
15387 test_154f() {
15388         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15389
15390         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15391         mkdir_on_mdt0 $DIR/$tdir
15392         # test dirs inherit from its stripe
15393         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15394         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15395         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15396         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15397         touch $DIR/f
15398
15399         # get fid of parents
15400         local FID0=$($LFS path2fid $DIR/$tdir)
15401         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15402         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15403         local FID3=$($LFS path2fid $DIR)
15404
15405         # check that path2fid --parents returns expected <parent_fid>/name
15406         # 1) test for a directory (single parent)
15407         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15408         [ "$parent" == "$FID0/foo1" ] ||
15409                 error "expected parent: $FID0/foo1, got: $parent"
15410
15411         # 2) test for a file with nlink > 1 (multiple parents)
15412         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15413         echo "$parent" | grep -F "$FID1/$tfile" ||
15414                 error "$FID1/$tfile not returned in parent list"
15415         echo "$parent" | grep -F "$FID2/link" ||
15416                 error "$FID2/link not returned in parent list"
15417
15418         # 3) get parent by fid
15419         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15420         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15421         echo "$parent" | grep -F "$FID1/$tfile" ||
15422                 error "$FID1/$tfile not returned in parent list (by fid)"
15423         echo "$parent" | grep -F "$FID2/link" ||
15424                 error "$FID2/link not returned in parent list (by fid)"
15425
15426         # 4) test for entry in root directory
15427         parent=$($LFS path2fid --parents $DIR/f)
15428         echo "$parent" | grep -F "$FID3/f" ||
15429                 error "$FID3/f not returned in parent list"
15430
15431         # 5) test it on root directory
15432         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15433                 error "$MOUNT should not have parents"
15434
15435         # enable xattr caching and check that linkea is correctly updated
15436         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15437         save_lustre_params client "llite.*.xattr_cache" > $save
15438         lctl set_param llite.*.xattr_cache 1
15439
15440         # 6.1) linkea update on rename
15441         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15442
15443         # get parents by fid
15444         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15445         # foo1 should no longer be returned in parent list
15446         echo "$parent" | grep -F "$FID1" &&
15447                 error "$FID1 should no longer be in parent list"
15448         # the new path should appear
15449         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15450                 error "$FID2/$tfile.moved is not in parent list"
15451
15452         # 6.2) linkea update on unlink
15453         rm -f $DIR/$tdir/foo2/link
15454         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15455         # foo2/link should no longer be returned in parent list
15456         echo "$parent" | grep -F "$FID2/link" &&
15457                 error "$FID2/link should no longer be in parent list"
15458         true
15459
15460         rm -f $DIR/f
15461         restore_lustre_params < $save
15462         rm -f $save
15463 }
15464 run_test 154f "get parent fids by reading link ea"
15465
15466 test_154g()
15467 {
15468         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15469         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15470            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15471                 skip "Need MDS version at least 2.6.92"
15472
15473         mkdir_on_mdt0 $DIR/$tdir
15474         llapi_fid_test -d $DIR/$tdir
15475 }
15476 run_test 154g "various llapi FID tests"
15477
15478 test_155_small_load() {
15479     local temp=$TMP/$tfile
15480     local file=$DIR/$tfile
15481
15482     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15483         error "dd of=$temp bs=6096 count=1 failed"
15484     cp $temp $file
15485     cancel_lru_locks $OSC
15486     cmp $temp $file || error "$temp $file differ"
15487
15488     $TRUNCATE $temp 6000
15489     $TRUNCATE $file 6000
15490     cmp $temp $file || error "$temp $file differ (truncate1)"
15491
15492     echo "12345" >>$temp
15493     echo "12345" >>$file
15494     cmp $temp $file || error "$temp $file differ (append1)"
15495
15496     echo "12345" >>$temp
15497     echo "12345" >>$file
15498     cmp $temp $file || error "$temp $file differ (append2)"
15499
15500     rm -f $temp $file
15501     true
15502 }
15503
15504 test_155_big_load() {
15505         remote_ost_nodsh && skip "remote OST with nodsh"
15506
15507         local temp=$TMP/$tfile
15508         local file=$DIR/$tfile
15509
15510         free_min_max
15511         local cache_size=$(do_facet ost$((MAXI+1)) \
15512                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15513         local large_file_size=$((cache_size * 2))
15514
15515         echo "OSS cache size: $cache_size KB"
15516         echo "Large file size: $large_file_size KB"
15517
15518         [ $MAXV -le $large_file_size ] &&
15519                 skip_env "max available OST size needs > $large_file_size KB"
15520
15521         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15522
15523         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15524                 error "dd of=$temp bs=$large_file_size count=1k failed"
15525         cp $temp $file
15526         ls -lh $temp $file
15527         cancel_lru_locks osc
15528         cmp $temp $file || error "$temp $file differ"
15529
15530         rm -f $temp $file
15531         true
15532 }
15533
15534 save_writethrough() {
15535         local facets=$(get_facets OST)
15536
15537         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15538 }
15539
15540 test_155a() {
15541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15542
15543         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15544
15545         save_writethrough $p
15546
15547         set_cache read on
15548         set_cache writethrough on
15549         test_155_small_load
15550         restore_lustre_params < $p
15551         rm -f $p
15552 }
15553 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15554
15555 test_155b() {
15556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15557
15558         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15559
15560         save_writethrough $p
15561
15562         set_cache read on
15563         set_cache writethrough off
15564         test_155_small_load
15565         restore_lustre_params < $p
15566         rm -f $p
15567 }
15568 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15569
15570 test_155c() {
15571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15572
15573         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15574
15575         save_writethrough $p
15576
15577         set_cache read off
15578         set_cache writethrough on
15579         test_155_small_load
15580         restore_lustre_params < $p
15581         rm -f $p
15582 }
15583 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15584
15585 test_155d() {
15586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15587
15588         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15589
15590         save_writethrough $p
15591
15592         set_cache read off
15593         set_cache writethrough off
15594         test_155_small_load
15595         restore_lustre_params < $p
15596         rm -f $p
15597 }
15598 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15599
15600 test_155e() {
15601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15602
15603         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15604
15605         save_writethrough $p
15606
15607         set_cache read on
15608         set_cache writethrough on
15609         test_155_big_load
15610         restore_lustre_params < $p
15611         rm -f $p
15612 }
15613 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15614
15615 test_155f() {
15616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15617
15618         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15619
15620         save_writethrough $p
15621
15622         set_cache read on
15623         set_cache writethrough off
15624         test_155_big_load
15625         restore_lustre_params < $p
15626         rm -f $p
15627 }
15628 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15629
15630 test_155g() {
15631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15632
15633         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15634
15635         save_writethrough $p
15636
15637         set_cache read off
15638         set_cache writethrough on
15639         test_155_big_load
15640         restore_lustre_params < $p
15641         rm -f $p
15642 }
15643 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15644
15645 test_155h() {
15646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15647
15648         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15649
15650         save_writethrough $p
15651
15652         set_cache read off
15653         set_cache writethrough off
15654         test_155_big_load
15655         restore_lustre_params < $p
15656         rm -f $p
15657 }
15658 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15659
15660 test_156() {
15661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15662         remote_ost_nodsh && skip "remote OST with nodsh"
15663         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15664                 skip "stats not implemented on old servers"
15665         [ "$ost1_FSTYPE" = "zfs" ] &&
15666                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15667
15668         local CPAGES=3
15669         local BEFORE
15670         local AFTER
15671         local file="$DIR/$tfile"
15672         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15673
15674         save_writethrough $p
15675         roc_hit_init
15676
15677         log "Turn on read and write cache"
15678         set_cache read on
15679         set_cache writethrough on
15680
15681         log "Write data and read it back."
15682         log "Read should be satisfied from the cache."
15683         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15684         BEFORE=$(roc_hit)
15685         cancel_lru_locks osc
15686         cat $file >/dev/null
15687         AFTER=$(roc_hit)
15688         if ! let "AFTER - BEFORE == CPAGES"; then
15689                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15690         else
15691                 log "cache hits: before: $BEFORE, after: $AFTER"
15692         fi
15693
15694         log "Read again; it should be satisfied from the cache."
15695         BEFORE=$AFTER
15696         cancel_lru_locks osc
15697         cat $file >/dev/null
15698         AFTER=$(roc_hit)
15699         if ! let "AFTER - BEFORE == CPAGES"; then
15700                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15701         else
15702                 log "cache hits:: before: $BEFORE, after: $AFTER"
15703         fi
15704
15705         log "Turn off the read cache and turn on the write cache"
15706         set_cache read off
15707         set_cache writethrough on
15708
15709         log "Read again; it should be satisfied from the cache."
15710         BEFORE=$(roc_hit)
15711         cancel_lru_locks osc
15712         cat $file >/dev/null
15713         AFTER=$(roc_hit)
15714         if ! let "AFTER - BEFORE == CPAGES"; then
15715                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15716         else
15717                 log "cache hits:: before: $BEFORE, after: $AFTER"
15718         fi
15719
15720         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15721                 # > 2.12.56 uses pagecache if cached
15722                 log "Read again; it should not be satisfied from the cache."
15723                 BEFORE=$AFTER
15724                 cancel_lru_locks osc
15725                 cat $file >/dev/null
15726                 AFTER=$(roc_hit)
15727                 if ! let "AFTER - BEFORE == 0"; then
15728                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15729                 else
15730                         log "cache hits:: before: $BEFORE, after: $AFTER"
15731                 fi
15732         fi
15733
15734         log "Write data and read it back."
15735         log "Read should be satisfied from the cache."
15736         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15737         BEFORE=$(roc_hit)
15738         cancel_lru_locks osc
15739         cat $file >/dev/null
15740         AFTER=$(roc_hit)
15741         if ! let "AFTER - BEFORE == CPAGES"; then
15742                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15743         else
15744                 log "cache hits:: before: $BEFORE, after: $AFTER"
15745         fi
15746
15747         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15748                 # > 2.12.56 uses pagecache if cached
15749                 log "Read again; it should not be satisfied from the cache."
15750                 BEFORE=$AFTER
15751                 cancel_lru_locks osc
15752                 cat $file >/dev/null
15753                 AFTER=$(roc_hit)
15754                 if ! let "AFTER - BEFORE == 0"; then
15755                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15756                 else
15757                         log "cache hits:: before: $BEFORE, after: $AFTER"
15758                 fi
15759         fi
15760
15761         log "Turn off read and write cache"
15762         set_cache read off
15763         set_cache writethrough off
15764
15765         log "Write data and read it back"
15766         log "It should not be satisfied from the cache."
15767         rm -f $file
15768         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15769         cancel_lru_locks osc
15770         BEFORE=$(roc_hit)
15771         cat $file >/dev/null
15772         AFTER=$(roc_hit)
15773         if ! let "AFTER - BEFORE == 0"; then
15774                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15775         else
15776                 log "cache hits:: before: $BEFORE, after: $AFTER"
15777         fi
15778
15779         log "Turn on the read cache and turn off the write cache"
15780         set_cache read on
15781         set_cache writethrough off
15782
15783         log "Write data and read it back"
15784         log "It should not be satisfied from the cache."
15785         rm -f $file
15786         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15787         BEFORE=$(roc_hit)
15788         cancel_lru_locks osc
15789         cat $file >/dev/null
15790         AFTER=$(roc_hit)
15791         if ! let "AFTER - BEFORE == 0"; then
15792                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15793         else
15794                 log "cache hits:: before: $BEFORE, after: $AFTER"
15795         fi
15796
15797         log "Read again; it should be satisfied from the cache."
15798         BEFORE=$(roc_hit)
15799         cancel_lru_locks osc
15800         cat $file >/dev/null
15801         AFTER=$(roc_hit)
15802         if ! let "AFTER - BEFORE == CPAGES"; then
15803                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15804         else
15805                 log "cache hits:: before: $BEFORE, after: $AFTER"
15806         fi
15807
15808         restore_lustre_params < $p
15809         rm -f $p $file
15810 }
15811 run_test 156 "Verification of tunables"
15812
15813 test_160a() {
15814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15815         remote_mds_nodsh && skip "remote MDS with nodsh"
15816         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15817                 skip "Need MDS version at least 2.2.0"
15818
15819         changelog_register || error "changelog_register failed"
15820         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15821         changelog_users $SINGLEMDS | grep -q $cl_user ||
15822                 error "User $cl_user not found in changelog_users"
15823
15824         mkdir_on_mdt0 $DIR/$tdir
15825
15826         # change something
15827         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15828         changelog_clear 0 || error "changelog_clear failed"
15829         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15830         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15831         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15832         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15833         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15834         rm $DIR/$tdir/pics/desktop.jpg
15835
15836         echo "verifying changelog mask"
15837         changelog_chmask "-MKDIR"
15838         changelog_chmask "-CLOSE"
15839
15840         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15841         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15842
15843         changelog_chmask "+MKDIR"
15844         changelog_chmask "+CLOSE"
15845
15846         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15847         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15848
15849         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15850         CLOSES=$(changelog_dump | grep -c "CLOSE")
15851         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15852         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15853
15854         # verify contents
15855         echo "verifying target fid"
15856         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15857         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15858         [ "$fidc" == "$fidf" ] ||
15859                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15860         echo "verifying parent fid"
15861         # The FID returned from the Changelog may be the directory shard on
15862         # a different MDT, and not the FID returned by path2fid on the parent.
15863         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15864         # since this is what will matter when recreating this file in the tree.
15865         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15866         local pathp=$($LFS fid2path $MOUNT "$fidp")
15867         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15868                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15869
15870         echo "getting records for $cl_user"
15871         changelog_users $SINGLEMDS
15872         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15873         local nclr=3
15874         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15875                 error "changelog_clear failed"
15876         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15877         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15878         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15879                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15880
15881         local min0_rec=$(changelog_users $SINGLEMDS |
15882                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15883         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15884                           awk '{ print $1; exit; }')
15885
15886         changelog_dump | tail -n 5
15887         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15888         [ $first_rec == $((min0_rec + 1)) ] ||
15889                 error "first index should be $min0_rec + 1 not $first_rec"
15890
15891         # LU-3446 changelog index reset on MDT restart
15892         local cur_rec1=$(changelog_users $SINGLEMDS |
15893                          awk '/^current.index:/ { print $NF }')
15894         changelog_clear 0 ||
15895                 error "clear all changelog records for $cl_user failed"
15896         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15897         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15898                 error "Fail to start $SINGLEMDS"
15899         local cur_rec2=$(changelog_users $SINGLEMDS |
15900                          awk '/^current.index:/ { print $NF }')
15901         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15902         [ $cur_rec1 == $cur_rec2 ] ||
15903                 error "current index should be $cur_rec1 not $cur_rec2"
15904
15905         echo "verifying users from this test are deregistered"
15906         changelog_deregister || error "changelog_deregister failed"
15907         changelog_users $SINGLEMDS | grep -q $cl_user &&
15908                 error "User '$cl_user' still in changelog_users"
15909
15910         # lctl get_param -n mdd.*.changelog_users
15911         # current_index: 144
15912         # ID    index (idle seconds)
15913         # cl3   144   (2) mask=<list>
15914         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15915                 # this is the normal case where all users were deregistered
15916                 # make sure no new records are added when no users are present
15917                 local last_rec1=$(changelog_users $SINGLEMDS |
15918                                   awk '/^current.index:/ { print $NF }')
15919                 touch $DIR/$tdir/chloe
15920                 local last_rec2=$(changelog_users $SINGLEMDS |
15921                                   awk '/^current.index:/ { print $NF }')
15922                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15923                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15924         else
15925                 # any changelog users must be leftovers from a previous test
15926                 changelog_users $SINGLEMDS
15927                 echo "other changelog users; can't verify off"
15928         fi
15929 }
15930 run_test 160a "changelog sanity"
15931
15932 test_160b() { # LU-3587
15933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15934         remote_mds_nodsh && skip "remote MDS with nodsh"
15935         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15936                 skip "Need MDS version at least 2.2.0"
15937
15938         changelog_register || error "changelog_register failed"
15939         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15940         changelog_users $SINGLEMDS | grep -q $cl_user ||
15941                 error "User '$cl_user' not found in changelog_users"
15942
15943         local longname1=$(str_repeat a 255)
15944         local longname2=$(str_repeat b 255)
15945
15946         cd $DIR
15947         echo "creating very long named file"
15948         touch $longname1 || error "create of '$longname1' failed"
15949         echo "renaming very long named file"
15950         mv $longname1 $longname2
15951
15952         changelog_dump | grep RENME | tail -n 5
15953         rm -f $longname2
15954 }
15955 run_test 160b "Verify that very long rename doesn't crash in changelog"
15956
15957 test_160c() {
15958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15959         remote_mds_nodsh && skip "remote MDS with nodsh"
15960
15961         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15962                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15963                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15964                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15965
15966         local rc=0
15967
15968         # Registration step
15969         changelog_register || error "changelog_register failed"
15970
15971         rm -rf $DIR/$tdir
15972         mkdir -p $DIR/$tdir
15973         $MCREATE $DIR/$tdir/foo_160c
15974         changelog_chmask "-TRUNC"
15975         $TRUNCATE $DIR/$tdir/foo_160c 200
15976         changelog_chmask "+TRUNC"
15977         $TRUNCATE $DIR/$tdir/foo_160c 199
15978         changelog_dump | tail -n 5
15979         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15980         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15981 }
15982 run_test 160c "verify that changelog log catch the truncate event"
15983
15984 test_160d() {
15985         remote_mds_nodsh && skip "remote MDS with nodsh"
15986         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15988         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15989                 skip "Need MDS version at least 2.7.60"
15990
15991         # Registration step
15992         changelog_register || error "changelog_register failed"
15993
15994         mkdir -p $DIR/$tdir/migrate_dir
15995         changelog_clear 0 || error "changelog_clear failed"
15996
15997         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15998         changelog_dump | tail -n 5
15999         local migrates=$(changelog_dump | grep -c "MIGRT")
16000         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16001 }
16002 run_test 160d "verify that changelog log catch the migrate event"
16003
16004 test_160e() {
16005         remote_mds_nodsh && skip "remote MDS with nodsh"
16006
16007         # Create a user
16008         changelog_register || error "changelog_register failed"
16009
16010         local MDT0=$(facet_svc $SINGLEMDS)
16011         local rc
16012
16013         # No user (expect fail)
16014         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16015         rc=$?
16016         if [ $rc -eq 0 ]; then
16017                 error "Should fail without user"
16018         elif [ $rc -ne 4 ]; then
16019                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16020         fi
16021
16022         # Delete a future user (expect fail)
16023         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16024         rc=$?
16025         if [ $rc -eq 0 ]; then
16026                 error "Deleted non-existant user cl77"
16027         elif [ $rc -ne 2 ]; then
16028                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16029         fi
16030
16031         # Clear to a bad index (1 billion should be safe)
16032         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16033         rc=$?
16034
16035         if [ $rc -eq 0 ]; then
16036                 error "Successfully cleared to invalid CL index"
16037         elif [ $rc -ne 22 ]; then
16038                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16039         fi
16040 }
16041 run_test 160e "changelog negative testing (should return errors)"
16042
16043 test_160f() {
16044         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16045         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16046                 skip "Need MDS version at least 2.10.56"
16047
16048         local mdts=$(comma_list $(mdts_nodes))
16049
16050         # Create a user
16051         changelog_register || error "first changelog_register failed"
16052         changelog_register || error "second changelog_register failed"
16053         local cl_users
16054         declare -A cl_user1
16055         declare -A cl_user2
16056         local user_rec1
16057         local user_rec2
16058         local i
16059
16060         # generate some changelog records to accumulate on each MDT
16061         # use all_char because created files should be evenly distributed
16062         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16063                 error "test_mkdir $tdir failed"
16064         log "$(date +%s): creating first files"
16065         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16066                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16067                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16068         done
16069
16070         # check changelogs have been generated
16071         local start=$SECONDS
16072         local idle_time=$((MDSCOUNT * 5 + 5))
16073         local nbcl=$(changelog_dump | wc -l)
16074         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16075
16076         for param in "changelog_max_idle_time=$idle_time" \
16077                      "changelog_gc=1" \
16078                      "changelog_min_gc_interval=2" \
16079                      "changelog_min_free_cat_entries=3"; do
16080                 local MDT0=$(facet_svc $SINGLEMDS)
16081                 local var="${param%=*}"
16082                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16083
16084                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16085                 do_nodes $mdts $LCTL set_param mdd.*.$param
16086         done
16087
16088         # force cl_user2 to be idle (1st part), but also cancel the
16089         # cl_user1 records so that it is not evicted later in the test.
16090         local sleep1=$((idle_time / 2))
16091         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16092         sleep $sleep1
16093
16094         # simulate changelog catalog almost full
16095         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16096         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16097
16098         for i in $(seq $MDSCOUNT); do
16099                 cl_users=(${CL_USERS[mds$i]})
16100                 cl_user1[mds$i]="${cl_users[0]}"
16101                 cl_user2[mds$i]="${cl_users[1]}"
16102
16103                 [ -n "${cl_user1[mds$i]}" ] ||
16104                         error "mds$i: no user registered"
16105                 [ -n "${cl_user2[mds$i]}" ] ||
16106                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16107
16108                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16109                 [ -n "$user_rec1" ] ||
16110                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16111                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16112                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16113                 [ -n "$user_rec2" ] ||
16114                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16115                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16116                      "$user_rec1 + 2 == $user_rec2"
16117                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16118                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16119                               "$user_rec1 + 2, but is $user_rec2"
16120                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16121                 [ -n "$user_rec2" ] ||
16122                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16123                 [ $user_rec1 == $user_rec2 ] ||
16124                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16125                               "$user_rec1, but is $user_rec2"
16126         done
16127
16128         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16129         local sleep2=$((idle_time - (SECONDS - start) + 1))
16130         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16131         sleep $sleep2
16132
16133         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16134         # cl_user1 should be OK because it recently processed records.
16135         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16136         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16137                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16138                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16139         done
16140
16141         # ensure gc thread is done
16142         for i in $(mdts_nodes); do
16143                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16144                         error "$i: GC-thread not done"
16145         done
16146
16147         local first_rec
16148         for (( i = 1; i <= MDSCOUNT; i++ )); do
16149                 # check cl_user1 still registered
16150                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16151                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16152                 # check cl_user2 unregistered
16153                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16154                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16155
16156                 # check changelogs are present and starting at $user_rec1 + 1
16157                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16158                 [ -n "$user_rec1" ] ||
16159                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16160                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16161                             awk '{ print $1; exit; }')
16162
16163                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16164                 [ $((user_rec1 + 1)) == $first_rec ] ||
16165                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16166         done
16167 }
16168 run_test 160f "changelog garbage collect (timestamped users)"
16169
16170 test_160g() {
16171         remote_mds_nodsh && skip "remote MDS with nodsh"
16172         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16173                 skip "Need MDS version at least 2.14.55"
16174
16175         local mdts=$(comma_list $(mdts_nodes))
16176
16177         # Create a user
16178         changelog_register || error "first changelog_register failed"
16179         changelog_register || error "second changelog_register failed"
16180         local cl_users
16181         declare -A cl_user1
16182         declare -A cl_user2
16183         local user_rec1
16184         local user_rec2
16185         local i
16186
16187         # generate some changelog records to accumulate on each MDT
16188         # use all_char because created files should be evenly distributed
16189         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16190                 error "test_mkdir $tdir failed"
16191         for ((i = 0; i < MDSCOUNT; i++)); do
16192                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16193                         error "create $DIR/$tdir/d$i.1 failed"
16194         done
16195
16196         # check changelogs have been generated
16197         local nbcl=$(changelog_dump | wc -l)
16198         (( $nbcl > 0 )) || error "no changelogs found"
16199
16200         # reduce the max_idle_indexes value to make sure we exceed it
16201         for param in "changelog_max_idle_indexes=2" \
16202                      "changelog_gc=1" \
16203                      "changelog_min_gc_interval=2"; do
16204                 local MDT0=$(facet_svc $SINGLEMDS)
16205                 local var="${param%=*}"
16206                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16207
16208                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16209                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16210                         error "unable to set mdd.*.$param"
16211         done
16212
16213         local start=$SECONDS
16214         for i in $(seq $MDSCOUNT); do
16215                 cl_users=(${CL_USERS[mds$i]})
16216                 cl_user1[mds$i]="${cl_users[0]}"
16217                 cl_user2[mds$i]="${cl_users[1]}"
16218
16219                 [ -n "${cl_user1[mds$i]}" ] ||
16220                         error "mds$i: user1 is not registered"
16221                 [ -n "${cl_user2[mds$i]}" ] ||
16222                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16223
16224                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16225                 [ -n "$user_rec1" ] ||
16226                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16227                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16228                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16229                 [ -n "$user_rec2" ] ||
16230                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16231                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16232                      "$user_rec1 + 2 == $user_rec2"
16233                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16234                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16235                               "expected $user_rec1 + 2, but is $user_rec2"
16236                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16237                 [ -n "$user_rec2" ] ||
16238                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16239                 [ $user_rec1 == $user_rec2 ] ||
16240                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16241                               "expected $user_rec1, but is $user_rec2"
16242         done
16243
16244         # ensure we are past the previous changelog_min_gc_interval set above
16245         local sleep2=$((start + 2 - SECONDS))
16246         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16247         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16248         # cl_user1 should be OK because it recently processed records.
16249         for ((i = 0; i < MDSCOUNT; i++)); do
16250                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16251                         error "create $DIR/$tdir/d$i.3 failed"
16252         done
16253
16254         # ensure gc thread is done
16255         for i in $(mdts_nodes); do
16256                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16257                         error "$i: GC-thread not done"
16258         done
16259
16260         local first_rec
16261         for (( i = 1; i <= MDSCOUNT; i++ )); do
16262                 # check cl_user1 still registered
16263                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16264                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16265                 # check cl_user2 unregistered
16266                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16267                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16268
16269                 # check changelogs are present and starting at $user_rec1 + 1
16270                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16271                 [ -n "$user_rec1" ] ||
16272                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16273                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16274                             awk '{ print $1; exit; }')
16275
16276                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16277                 [ $((user_rec1 + 1)) == $first_rec ] ||
16278                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16279         done
16280 }
16281 run_test 160g "changelog garbage collect on idle records"
16282
16283 test_160h() {
16284         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16285         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16286                 skip "Need MDS version at least 2.10.56"
16287
16288         local mdts=$(comma_list $(mdts_nodes))
16289
16290         # Create a user
16291         changelog_register || error "first changelog_register failed"
16292         changelog_register || error "second changelog_register failed"
16293         local cl_users
16294         declare -A cl_user1
16295         declare -A cl_user2
16296         local user_rec1
16297         local user_rec2
16298         local i
16299
16300         # generate some changelog records to accumulate on each MDT
16301         # use all_char because created files should be evenly distributed
16302         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16303                 error "test_mkdir $tdir failed"
16304         for ((i = 0; i < MDSCOUNT; i++)); do
16305                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16306                         error "create $DIR/$tdir/d$i.1 failed"
16307         done
16308
16309         # check changelogs have been generated
16310         local nbcl=$(changelog_dump | wc -l)
16311         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16312
16313         for param in "changelog_max_idle_time=10" \
16314                      "changelog_gc=1" \
16315                      "changelog_min_gc_interval=2"; do
16316                 local MDT0=$(facet_svc $SINGLEMDS)
16317                 local var="${param%=*}"
16318                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16319
16320                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16321                 do_nodes $mdts $LCTL set_param mdd.*.$param
16322         done
16323
16324         # force cl_user2 to be idle (1st part)
16325         sleep 9
16326
16327         for i in $(seq $MDSCOUNT); do
16328                 cl_users=(${CL_USERS[mds$i]})
16329                 cl_user1[mds$i]="${cl_users[0]}"
16330                 cl_user2[mds$i]="${cl_users[1]}"
16331
16332                 [ -n "${cl_user1[mds$i]}" ] ||
16333                         error "mds$i: no user registered"
16334                 [ -n "${cl_user2[mds$i]}" ] ||
16335                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16336
16337                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16338                 [ -n "$user_rec1" ] ||
16339                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16340                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16341                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16342                 [ -n "$user_rec2" ] ||
16343                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16344                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16345                      "$user_rec1 + 2 == $user_rec2"
16346                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16347                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16348                               "$user_rec1 + 2, but is $user_rec2"
16349                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16350                 [ -n "$user_rec2" ] ||
16351                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16352                 [ $user_rec1 == $user_rec2 ] ||
16353                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16354                               "$user_rec1, but is $user_rec2"
16355         done
16356
16357         # force cl_user2 to be idle (2nd part) and to reach
16358         # changelog_max_idle_time
16359         sleep 2
16360
16361         # force each GC-thread start and block then
16362         # one per MDT/MDD, set fail_val accordingly
16363         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16364         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16365
16366         # generate more changelogs to trigger fail_loc
16367         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16368                 error "create $DIR/$tdir/${tfile}bis failed"
16369
16370         # stop MDT to stop GC-thread, should be done in back-ground as it will
16371         # block waiting for the thread to be released and exit
16372         declare -A stop_pids
16373         for i in $(seq $MDSCOUNT); do
16374                 stop mds$i &
16375                 stop_pids[mds$i]=$!
16376         done
16377
16378         for i in $(mdts_nodes); do
16379                 local facet
16380                 local nb=0
16381                 local facets=$(facets_up_on_host $i)
16382
16383                 for facet in ${facets//,/ }; do
16384                         if [[ $facet == mds* ]]; then
16385                                 nb=$((nb + 1))
16386                         fi
16387                 done
16388                 # ensure each MDS's gc threads are still present and all in "R"
16389                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16390                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16391                         error "$i: expected $nb GC-thread"
16392                 wait_update $i \
16393                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16394                         "R" 20 ||
16395                         error "$i: GC-thread not found in R-state"
16396                 # check umounts of each MDT on MDS have reached kthread_stop()
16397                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16398                         error "$i: expected $nb umount"
16399                 wait_update $i \
16400                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16401                         error "$i: umount not found in D-state"
16402         done
16403
16404         # release all GC-threads
16405         do_nodes $mdts $LCTL set_param fail_loc=0
16406
16407         # wait for MDT stop to complete
16408         for i in $(seq $MDSCOUNT); do
16409                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16410         done
16411
16412         # XXX
16413         # may try to check if any orphan changelog records are present
16414         # via ldiskfs/zfs and llog_reader...
16415
16416         # re-start/mount MDTs
16417         for i in $(seq $MDSCOUNT); do
16418                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16419                         error "Fail to start mds$i"
16420         done
16421
16422         local first_rec
16423         for i in $(seq $MDSCOUNT); do
16424                 # check cl_user1 still registered
16425                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16426                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16427                 # check cl_user2 unregistered
16428                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16429                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16430
16431                 # check changelogs are present and starting at $user_rec1 + 1
16432                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16433                 [ -n "$user_rec1" ] ||
16434                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16435                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16436                             awk '{ print $1; exit; }')
16437
16438                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16439                 [ $((user_rec1 + 1)) == $first_rec ] ||
16440                         error "mds$i: first index should be $user_rec1 + 1, " \
16441                               "but is $first_rec"
16442         done
16443 }
16444 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16445               "during mount"
16446
16447 test_160i() {
16448
16449         local mdts=$(comma_list $(mdts_nodes))
16450
16451         changelog_register || error "first changelog_register failed"
16452
16453         # generate some changelog records to accumulate on each MDT
16454         # use all_char because created files should be evenly distributed
16455         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16456                 error "test_mkdir $tdir failed"
16457         for ((i = 0; i < MDSCOUNT; i++)); do
16458                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16459                         error "create $DIR/$tdir/d$i.1 failed"
16460         done
16461
16462         # check changelogs have been generated
16463         local nbcl=$(changelog_dump | wc -l)
16464         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16465
16466         # simulate race between register and unregister
16467         # XXX as fail_loc is set per-MDS, with DNE configs the race
16468         # simulation will only occur for one MDT per MDS and for the
16469         # others the normal race scenario will take place
16470         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16471         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16472         do_nodes $mdts $LCTL set_param fail_val=1
16473
16474         # unregister 1st user
16475         changelog_deregister &
16476         local pid1=$!
16477         # wait some time for deregister work to reach race rdv
16478         sleep 2
16479         # register 2nd user
16480         changelog_register || error "2nd user register failed"
16481
16482         wait $pid1 || error "1st user deregister failed"
16483
16484         local i
16485         local last_rec
16486         declare -A LAST_REC
16487         for i in $(seq $MDSCOUNT); do
16488                 if changelog_users mds$i | grep "^cl"; then
16489                         # make sure new records are added with one user present
16490                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16491                                           awk '/^current.index:/ { print $NF }')
16492                 else
16493                         error "mds$i has no user registered"
16494                 fi
16495         done
16496
16497         # generate more changelog records to accumulate on each MDT
16498         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16499                 error "create $DIR/$tdir/${tfile}bis failed"
16500
16501         for i in $(seq $MDSCOUNT); do
16502                 last_rec=$(changelog_users $SINGLEMDS |
16503                            awk '/^current.index:/ { print $NF }')
16504                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16505                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16506                         error "changelogs are off on mds$i"
16507         done
16508 }
16509 run_test 160i "changelog user register/unregister race"
16510
16511 test_160j() {
16512         remote_mds_nodsh && skip "remote MDS with nodsh"
16513         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16514                 skip "Need MDS version at least 2.12.56"
16515
16516         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16517         stack_trap "umount $MOUNT2" EXIT
16518
16519         changelog_register || error "first changelog_register failed"
16520         stack_trap "changelog_deregister" EXIT
16521
16522         # generate some changelog
16523         # use all_char because created files should be evenly distributed
16524         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16525                 error "mkdir $tdir failed"
16526         for ((i = 0; i < MDSCOUNT; i++)); do
16527                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16528                         error "create $DIR/$tdir/d$i.1 failed"
16529         done
16530
16531         # open the changelog device
16532         exec 3>/dev/changelog-$FSNAME-MDT0000
16533         stack_trap "exec 3>&-" EXIT
16534         exec 4</dev/changelog-$FSNAME-MDT0000
16535         stack_trap "exec 4<&-" EXIT
16536
16537         # umount the first lustre mount
16538         umount $MOUNT
16539         stack_trap "mount_client $MOUNT" EXIT
16540
16541         # read changelog, which may or may not fail, but should not crash
16542         cat <&4 >/dev/null
16543
16544         # clear changelog
16545         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16546         changelog_users $SINGLEMDS | grep -q $cl_user ||
16547                 error "User $cl_user not found in changelog_users"
16548
16549         printf 'clear:'$cl_user':0' >&3
16550 }
16551 run_test 160j "client can be umounted while its chanangelog is being used"
16552
16553 test_160k() {
16554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16555         remote_mds_nodsh && skip "remote MDS with nodsh"
16556
16557         mkdir -p $DIR/$tdir/1/1
16558
16559         changelog_register || error "changelog_register failed"
16560         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16561
16562         changelog_users $SINGLEMDS | grep -q $cl_user ||
16563                 error "User '$cl_user' not found in changelog_users"
16564 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16565         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16566         rmdir $DIR/$tdir/1/1 & sleep 1
16567         mkdir $DIR/$tdir/2
16568         touch $DIR/$tdir/2/2
16569         rm -rf $DIR/$tdir/2
16570
16571         wait
16572         sleep 4
16573
16574         changelog_dump | grep rmdir || error "rmdir not recorded"
16575 }
16576 run_test 160k "Verify that changelog records are not lost"
16577
16578 # Verifies that a file passed as a parameter has recently had an operation
16579 # performed on it that has generated an MTIME changelog which contains the
16580 # correct parent FID. As files might reside on a different MDT from the
16581 # parent directory in DNE configurations, the FIDs are translated to paths
16582 # before being compared, which should be identical
16583 compare_mtime_changelog() {
16584         local file="${1}"
16585         local mdtidx
16586         local mtime
16587         local cl_fid
16588         local pdir
16589         local dir
16590
16591         mdtidx=$($LFS getstripe --mdt-index $file)
16592         mdtidx=$(printf "%04x" $mdtidx)
16593
16594         # Obtain the parent FID from the MTIME changelog
16595         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16596         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16597
16598         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16599         [ -z "$cl_fid" ] && error "parent FID not present"
16600
16601         # Verify that the path for the parent FID is the same as the path for
16602         # the test directory
16603         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16604
16605         dir=$(dirname $1)
16606
16607         [[ "${pdir%/}" == "$dir" ]] ||
16608                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16609 }
16610
16611 test_160l() {
16612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16613
16614         remote_mds_nodsh && skip "remote MDS with nodsh"
16615         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16616                 skip "Need MDS version at least 2.13.55"
16617
16618         local cl_user
16619
16620         changelog_register || error "changelog_register failed"
16621         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16622
16623         changelog_users $SINGLEMDS | grep -q $cl_user ||
16624                 error "User '$cl_user' not found in changelog_users"
16625
16626         # Clear some types so that MTIME changelogs are generated
16627         changelog_chmask "-CREAT"
16628         changelog_chmask "-CLOSE"
16629
16630         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16631
16632         # Test CL_MTIME during setattr
16633         touch $DIR/$tdir/$tfile
16634         compare_mtime_changelog $DIR/$tdir/$tfile
16635
16636         # Test CL_MTIME during close
16637         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16638         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16639 }
16640 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16641
16642 test_160m() {
16643         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16644         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16645                 skip "Need MDS version at least 2.14.51"
16646         local cl_users
16647         local cl_user1
16648         local cl_user2
16649         local pid1
16650
16651         # Create a user
16652         changelog_register || error "first changelog_register failed"
16653         changelog_register || error "second changelog_register failed"
16654
16655         cl_users=(${CL_USERS[mds1]})
16656         cl_user1="${cl_users[0]}"
16657         cl_user2="${cl_users[1]}"
16658         # generate some changelog records to accumulate on MDT0
16659         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16660         createmany -m $DIR/$tdir/$tfile 50 ||
16661                 error "create $DIR/$tdir/$tfile failed"
16662         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16663         rm -f $DIR/$tdir
16664
16665         # check changelogs have been generated
16666         local nbcl=$(changelog_dump | wc -l)
16667         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16668
16669 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16670         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16671
16672         __changelog_clear mds1 $cl_user1 +10
16673         __changelog_clear mds1 $cl_user2 0 &
16674         pid1=$!
16675         sleep 2
16676         __changelog_clear mds1 $cl_user1 0 ||
16677                 error "fail to cancel record for $cl_user1"
16678         wait $pid1
16679         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16680 }
16681 run_test 160m "Changelog clear race"
16682
16683 test_160n() {
16684         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16685         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16686                 skip "Need MDS version at least 2.14.51"
16687         local cl_users
16688         local cl_user1
16689         local cl_user2
16690         local pid1
16691         local first_rec
16692         local last_rec=0
16693
16694         # Create a user
16695         changelog_register || error "first changelog_register failed"
16696
16697         cl_users=(${CL_USERS[mds1]})
16698         cl_user1="${cl_users[0]}"
16699
16700         # generate some changelog records to accumulate on MDT0
16701         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16702         first_rec=$(changelog_users $SINGLEMDS |
16703                         awk '/^current.index:/ { print $NF }')
16704         while (( last_rec < (( first_rec + 65000)) )); do
16705                 createmany -m $DIR/$tdir/$tfile 10000 ||
16706                         error "create $DIR/$tdir/$tfile failed"
16707
16708                 for i in $(seq 0 10000); do
16709                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16710                                 > /dev/null
16711                 done
16712
16713                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16714                         error "unlinkmany failed unlink"
16715                 last_rec=$(changelog_users $SINGLEMDS |
16716                         awk '/^current.index:/ { print $NF }')
16717                 echo last record $last_rec
16718                 (( last_rec == 0 )) && error "no changelog found"
16719         done
16720
16721 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16722         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16723
16724         __changelog_clear mds1 $cl_user1 0 &
16725         pid1=$!
16726         sleep 2
16727         __changelog_clear mds1 $cl_user1 0 ||
16728                 error "fail to cancel record for $cl_user1"
16729         wait $pid1
16730         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16731 }
16732 run_test 160n "Changelog destroy race"
16733
16734 test_160o() {
16735         local mdt="$(facet_svc $SINGLEMDS)"
16736
16737         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16738         remote_mds_nodsh && skip "remote MDS with nodsh"
16739         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16740                 skip "Need MDS version at least 2.14.52"
16741
16742         changelog_register --user test_160o -m unlnk+close+open ||
16743                 error "changelog_register failed"
16744
16745         do_facet $SINGLEMDS $LCTL --device $mdt \
16746                                 changelog_register -u "Tt3_-#" &&
16747                 error "bad symbols in name should fail"
16748
16749         do_facet $SINGLEMDS $LCTL --device $mdt \
16750                                 changelog_register -u test_160o &&
16751                 error "the same name registration should fail"
16752
16753         do_facet $SINGLEMDS $LCTL --device $mdt \
16754                         changelog_register -u test_160toolongname &&
16755                 error "too long name registration should fail"
16756
16757         changelog_chmask "MARK+HSM"
16758         lctl get_param mdd.*.changelog*mask
16759         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16760         changelog_users $SINGLEMDS | grep -q $cl_user ||
16761                 error "User $cl_user not found in changelog_users"
16762         #verify username
16763         echo $cl_user | grep -q test_160o ||
16764                 error "User $cl_user has no specific name 'test160o'"
16765
16766         # change something
16767         changelog_clear 0 || error "changelog_clear failed"
16768         # generate some changelog records to accumulate on MDT0
16769         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16770         touch $DIR/$tdir/$tfile                 # open 1
16771
16772         OPENS=$(changelog_dump | grep -c "OPEN")
16773         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16774
16775         # must be no MKDIR it wasn't set as user mask
16776         MKDIR=$(changelog_dump | grep -c "MKDIR")
16777         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16778
16779         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16780                                 mdd.$mdt.changelog_current_mask -n)
16781         # register maskless user
16782         changelog_register || error "changelog_register failed"
16783         # effective mask should be not changed because it is not minimal
16784         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16785                                 mdd.$mdt.changelog_current_mask -n)
16786         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16787         # set server mask to minimal value
16788         changelog_chmask "MARK"
16789         # check effective mask again, should be treated as DEFMASK now
16790         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16791                                 mdd.$mdt.changelog_current_mask -n)
16792         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16793
16794         do_facet $SINGLEMDS $LCTL --device $mdt \
16795                                 changelog_deregister -u test_160o ||
16796                 error "cannot deregister by name"
16797 }
16798 run_test 160o "changelog user name and mask"
16799
16800 test_160p() {
16801         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16802         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16803                 skip "Need MDS version at least 2.14.51"
16804         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16805         local cl_users
16806         local cl_user1
16807         local entry_count
16808
16809         # Create a user
16810         changelog_register || error "first changelog_register failed"
16811
16812         cl_users=(${CL_USERS[mds1]})
16813         cl_user1="${cl_users[0]}"
16814
16815         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16816         createmany -m $DIR/$tdir/$tfile 50 ||
16817                 error "create $DIR/$tdir/$tfile failed"
16818         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16819         rm -rf $DIR/$tdir
16820
16821         # check changelogs have been generated
16822         entry_count=$(changelog_dump | wc -l)
16823         ((entry_count != 0)) || error "no changelog entries found"
16824
16825         # remove changelog_users and check that orphan entries are removed
16826         stop mds1
16827         local dev=$(mdsdevname 1)
16828         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16829         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16830         entry_count=$(changelog_dump | wc -l)
16831         ((entry_count == 0)) ||
16832                 error "found $entry_count changelog entries, expected none"
16833 }
16834 run_test 160p "Changelog orphan cleanup with no users"
16835
16836 test_160q() {
16837         local mdt="$(facet_svc $SINGLEMDS)"
16838         local clu
16839
16840         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16841         remote_mds_nodsh && skip "remote MDS with nodsh"
16842         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16843                 skip "Need MDS version at least 2.14.54"
16844
16845         # set server mask to minimal value like server init does
16846         changelog_chmask "MARK"
16847         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16848                 error "changelog_register failed"
16849         # check effective mask again, should be treated as DEFMASK now
16850         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16851                                 mdd.$mdt.changelog_current_mask -n)
16852         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16853                 error "changelog_deregister failed"
16854         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16855 }
16856 run_test 160q "changelog effective mask is DEFMASK if not set"
16857
16858 test_160s() {
16859         remote_mds_nodsh && skip "remote MDS with nodsh"
16860         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16861                 skip "Need MDS version at least 2.14.55"
16862
16863         local mdts=$(comma_list $(mdts_nodes))
16864
16865         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16866         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16867                                        fail_val=$((24 * 3600 * 10))
16868
16869         # Create a user which is 10 days old
16870         changelog_register || error "first changelog_register failed"
16871         local cl_users
16872         declare -A cl_user1
16873         local i
16874
16875         # generate some changelog records to accumulate on each MDT
16876         # use all_char because created files should be evenly distributed
16877         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16878                 error "test_mkdir $tdir failed"
16879         for ((i = 0; i < MDSCOUNT; i++)); do
16880                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16881                         error "create $DIR/$tdir/d$i.1 failed"
16882         done
16883
16884         # check changelogs have been generated
16885         local nbcl=$(changelog_dump | wc -l)
16886         (( nbcl > 0 )) || error "no changelogs found"
16887
16888         # reduce the max_idle_indexes value to make sure we exceed it
16889         for param in "changelog_max_idle_indexes=2097446912" \
16890                      "changelog_max_idle_time=2592000" \
16891                      "changelog_gc=1" \
16892                      "changelog_min_gc_interval=2"; do
16893                 local MDT0=$(facet_svc $SINGLEMDS)
16894                 local var="${param%=*}"
16895                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16896
16897                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16898                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16899                         error "unable to set mdd.*.$param"
16900         done
16901
16902         local start=$SECONDS
16903         for i in $(seq $MDSCOUNT); do
16904                 cl_users=(${CL_USERS[mds$i]})
16905                 cl_user1[mds$i]="${cl_users[0]}"
16906
16907                 [[ -n "${cl_user1[mds$i]}" ]] ||
16908                         error "mds$i: no user registered"
16909         done
16910
16911         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16912         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16913
16914         # ensure we are past the previous changelog_min_gc_interval set above
16915         local sleep2=$((start + 2 - SECONDS))
16916         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16917
16918         # Generate one more changelog to trigger GC
16919         for ((i = 0; i < MDSCOUNT; i++)); do
16920                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16921                         error "create $DIR/$tdir/d$i.3 failed"
16922         done
16923
16924         # ensure gc thread is done
16925         for node in $(mdts_nodes); do
16926                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16927                         error "$node: GC-thread not done"
16928         done
16929
16930         do_nodes $mdts $LCTL set_param fail_loc=0
16931
16932         for (( i = 1; i <= MDSCOUNT; i++ )); do
16933                 # check cl_user1 is purged
16934                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16935                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16936         done
16937         return 0
16938 }
16939 run_test 160s "changelog garbage collect on idle records * time"
16940
16941 test_161a() {
16942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16943
16944         test_mkdir -c1 $DIR/$tdir
16945         cp /etc/hosts $DIR/$tdir/$tfile
16946         test_mkdir -c1 $DIR/$tdir/foo1
16947         test_mkdir -c1 $DIR/$tdir/foo2
16948         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16949         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16950         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16951         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16952         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16953         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16954                 $LFS fid2path $DIR $FID
16955                 error "bad link ea"
16956         fi
16957         # middle
16958         rm $DIR/$tdir/foo2/zachary
16959         # last
16960         rm $DIR/$tdir/foo2/thor
16961         # first
16962         rm $DIR/$tdir/$tfile
16963         # rename
16964         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16965         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16966                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16967         rm $DIR/$tdir/foo2/maggie
16968
16969         # overflow the EA
16970         local longname=$tfile.avg_len_is_thirty_two_
16971         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16972                 error_noexit 'failed to unlink many hardlinks'" EXIT
16973         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16974                 error "failed to hardlink many files"
16975         links=$($LFS fid2path $DIR $FID | wc -l)
16976         echo -n "${links}/1000 links in link EA"
16977         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16978 }
16979 run_test 161a "link ea sanity"
16980
16981 test_161b() {
16982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16983         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16984
16985         local MDTIDX=1
16986         local remote_dir=$DIR/$tdir/remote_dir
16987
16988         mkdir -p $DIR/$tdir
16989         $LFS mkdir -i $MDTIDX $remote_dir ||
16990                 error "create remote directory failed"
16991
16992         cp /etc/hosts $remote_dir/$tfile
16993         mkdir -p $remote_dir/foo1
16994         mkdir -p $remote_dir/foo2
16995         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16996         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16997         ln $remote_dir/$tfile $remote_dir/foo1/luna
16998         ln $remote_dir/$tfile $remote_dir/foo2/thor
16999
17000         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17001                      tr -d ']')
17002         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17003                 $LFS fid2path $DIR $FID
17004                 error "bad link ea"
17005         fi
17006         # middle
17007         rm $remote_dir/foo2/zachary
17008         # last
17009         rm $remote_dir/foo2/thor
17010         # first
17011         rm $remote_dir/$tfile
17012         # rename
17013         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17014         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17015         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17016                 $LFS fid2path $DIR $FID
17017                 error "bad link rename"
17018         fi
17019         rm $remote_dir/foo2/maggie
17020
17021         # overflow the EA
17022         local longname=filename_avg_len_is_thirty_two_
17023         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17024                 error "failed to hardlink many files"
17025         links=$($LFS fid2path $DIR $FID | wc -l)
17026         echo -n "${links}/1000 links in link EA"
17027         [[ ${links} -gt 60 ]] ||
17028                 error "expected at least 60 links in link EA"
17029         unlinkmany $remote_dir/foo2/$longname 1000 ||
17030         error "failed to unlink many hardlinks"
17031 }
17032 run_test 161b "link ea sanity under remote directory"
17033
17034 test_161c() {
17035         remote_mds_nodsh && skip "remote MDS with nodsh"
17036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17037         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17038                 skip "Need MDS version at least 2.1.5"
17039
17040         # define CLF_RENAME_LAST 0x0001
17041         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17042         changelog_register || error "changelog_register failed"
17043
17044         rm -rf $DIR/$tdir
17045         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17046         touch $DIR/$tdir/foo_161c
17047         touch $DIR/$tdir/bar_161c
17048         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17049         changelog_dump | grep RENME | tail -n 5
17050         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17051         changelog_clear 0 || error "changelog_clear failed"
17052         if [ x$flags != "x0x1" ]; then
17053                 error "flag $flags is not 0x1"
17054         fi
17055
17056         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17057         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17058         touch $DIR/$tdir/foo_161c
17059         touch $DIR/$tdir/bar_161c
17060         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17061         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17062         changelog_dump | grep RENME | tail -n 5
17063         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17064         changelog_clear 0 || error "changelog_clear failed"
17065         if [ x$flags != "x0x0" ]; then
17066                 error "flag $flags is not 0x0"
17067         fi
17068         echo "rename overwrite a target having nlink > 1," \
17069                 "changelog record has flags of $flags"
17070
17071         # rename doesn't overwrite a target (changelog flag 0x0)
17072         touch $DIR/$tdir/foo_161c
17073         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17074         changelog_dump | grep RENME | tail -n 5
17075         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17076         changelog_clear 0 || error "changelog_clear failed"
17077         if [ x$flags != "x0x0" ]; then
17078                 error "flag $flags is not 0x0"
17079         fi
17080         echo "rename doesn't overwrite a target," \
17081                 "changelog record has flags of $flags"
17082
17083         # define CLF_UNLINK_LAST 0x0001
17084         # unlink a file having nlink = 1 (changelog flag 0x1)
17085         rm -f $DIR/$tdir/foo2_161c
17086         changelog_dump | grep UNLNK | tail -n 5
17087         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17088         changelog_clear 0 || error "changelog_clear failed"
17089         if [ x$flags != "x0x1" ]; then
17090                 error "flag $flags is not 0x1"
17091         fi
17092         echo "unlink a file having nlink = 1," \
17093                 "changelog record has flags of $flags"
17094
17095         # unlink a file having nlink > 1 (changelog flag 0x0)
17096         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17097         rm -f $DIR/$tdir/foobar_161c
17098         changelog_dump | grep UNLNK | tail -n 5
17099         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17100         changelog_clear 0 || error "changelog_clear failed"
17101         if [ x$flags != "x0x0" ]; then
17102                 error "flag $flags is not 0x0"
17103         fi
17104         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17105 }
17106 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17107
17108 test_161d() {
17109         remote_mds_nodsh && skip "remote MDS with nodsh"
17110         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17111
17112         local pid
17113         local fid
17114
17115         changelog_register || error "changelog_register failed"
17116
17117         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17118         # interfer with $MOUNT/.lustre/fid/ access
17119         mkdir $DIR/$tdir
17120         [[ $? -eq 0 ]] || error "mkdir failed"
17121
17122         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17123         $LCTL set_param fail_loc=0x8000140c
17124         # 5s pause
17125         $LCTL set_param fail_val=5
17126
17127         # create file
17128         echo foofoo > $DIR/$tdir/$tfile &
17129         pid=$!
17130
17131         # wait for create to be delayed
17132         sleep 2
17133
17134         ps -p $pid
17135         [[ $? -eq 0 ]] || error "create should be blocked"
17136
17137         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17138         stack_trap "rm -f $tempfile"
17139         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17140         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17141         # some delay may occur during ChangeLog publishing and file read just
17142         # above, that could allow file write to happen finally
17143         [[ -s $tempfile ]] && echo "file should be empty"
17144
17145         $LCTL set_param fail_loc=0
17146
17147         wait $pid
17148         [[ $? -eq 0 ]] || error "create failed"
17149 }
17150 run_test 161d "create with concurrent .lustre/fid access"
17151
17152 check_path() {
17153         local expected="$1"
17154         shift
17155         local fid="$2"
17156
17157         local path
17158         path=$($LFS fid2path "$@")
17159         local rc=$?
17160
17161         if [ $rc -ne 0 ]; then
17162                 error "path looked up of '$expected' failed: rc=$rc"
17163         elif [ "$path" != "$expected" ]; then
17164                 error "path looked up '$path' instead of '$expected'"
17165         else
17166                 echo "FID '$fid' resolves to path '$path' as expected"
17167         fi
17168 }
17169
17170 test_162a() { # was test_162
17171         test_mkdir -p -c1 $DIR/$tdir/d2
17172         touch $DIR/$tdir/d2/$tfile
17173         touch $DIR/$tdir/d2/x1
17174         touch $DIR/$tdir/d2/x2
17175         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17176         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17177         # regular file
17178         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17179         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17180
17181         # softlink
17182         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17183         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17184         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17185
17186         # softlink to wrong file
17187         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17188         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17189         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17190
17191         # hardlink
17192         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17193         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17194         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17195         # fid2path dir/fsname should both work
17196         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17197         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17198
17199         # hardlink count: check that there are 2 links
17200         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17201         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17202
17203         # hardlink indexing: remove the first link
17204         rm $DIR/$tdir/d2/p/q/r/hlink
17205         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17206 }
17207 run_test 162a "path lookup sanity"
17208
17209 test_162b() {
17210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17211         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17212
17213         mkdir $DIR/$tdir
17214         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17215                                 error "create striped dir failed"
17216
17217         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17218                                         tail -n 1 | awk '{print $2}')
17219         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17220
17221         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17222         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17223
17224         # regular file
17225         for ((i=0;i<5;i++)); do
17226                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17227                         error "get fid for f$i failed"
17228                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17229
17230                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17231                         error "get fid for d$i failed"
17232                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17233         done
17234
17235         return 0
17236 }
17237 run_test 162b "striped directory path lookup sanity"
17238
17239 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17240 test_162c() {
17241         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17242                 skip "Need MDS version at least 2.7.51"
17243
17244         local lpath=$tdir.local
17245         local rpath=$tdir.remote
17246
17247         test_mkdir $DIR/$lpath
17248         test_mkdir $DIR/$rpath
17249
17250         for ((i = 0; i <= 101; i++)); do
17251                 lpath="$lpath/$i"
17252                 mkdir $DIR/$lpath
17253                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17254                         error "get fid for local directory $DIR/$lpath failed"
17255                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17256
17257                 rpath="$rpath/$i"
17258                 test_mkdir $DIR/$rpath
17259                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17260                         error "get fid for remote directory $DIR/$rpath failed"
17261                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17262         done
17263
17264         return 0
17265 }
17266 run_test 162c "fid2path works with paths 100 or more directories deep"
17267
17268 oalr_event_count() {
17269         local event="${1}"
17270         local trace="${2}"
17271
17272         awk -v name="${FSNAME}-OST0000" \
17273             -v event="${event}" \
17274             '$1 == "TRACE" && $2 == event && $3 == name' \
17275             "${trace}" |
17276         wc -l
17277 }
17278
17279 oalr_expect_event_count() {
17280         local event="${1}"
17281         local trace="${2}"
17282         local expect="${3}"
17283         local count
17284
17285         count=$(oalr_event_count "${event}" "${trace}")
17286         if ((count == expect)); then
17287                 return 0
17288         fi
17289
17290         error_noexit "${event} event count was '${count}', expected ${expect}"
17291         cat "${trace}" >&2
17292         exit 1
17293 }
17294
17295 cleanup_165() {
17296         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17297         stop ost1
17298         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17299 }
17300
17301 setup_165() {
17302         sync # Flush previous IOs so we can count log entries.
17303         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17304         stack_trap cleanup_165 EXIT
17305 }
17306
17307 test_165a() {
17308         local trace="/tmp/${tfile}.trace"
17309         local rc
17310         local count
17311
17312         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17313                 skip "OFD access log unsupported"
17314
17315         setup_165
17316         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17317         sleep 5
17318
17319         do_facet ost1 ofd_access_log_reader --list
17320         stop ost1
17321
17322         do_facet ost1 killall -TERM ofd_access_log_reader
17323         wait
17324         rc=$?
17325
17326         if ((rc != 0)); then
17327                 error "ofd_access_log_reader exited with rc = '${rc}'"
17328         fi
17329
17330         # Parse trace file for discovery events:
17331         oalr_expect_event_count alr_log_add "${trace}" 1
17332         oalr_expect_event_count alr_log_eof "${trace}" 1
17333         oalr_expect_event_count alr_log_free "${trace}" 1
17334 }
17335 run_test 165a "ofd access log discovery"
17336
17337 test_165b() {
17338         local trace="/tmp/${tfile}.trace"
17339         local file="${DIR}/${tfile}"
17340         local pfid1
17341         local pfid2
17342         local -a entry
17343         local rc
17344         local count
17345         local size
17346         local flags
17347
17348         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17349                 skip "OFD access log unsupported"
17350
17351         setup_165
17352         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17353         sleep 5
17354
17355         do_facet ost1 ofd_access_log_reader --list
17356
17357         lfs setstripe -c 1 -i 0 "${file}"
17358         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17359                 error "cannot create '${file}'"
17360
17361         sleep 5
17362         do_facet ost1 killall -TERM ofd_access_log_reader
17363         wait
17364         rc=$?
17365
17366         if ((rc != 0)); then
17367                 error "ofd_access_log_reader exited with rc = '${rc}'"
17368         fi
17369
17370         oalr_expect_event_count alr_log_entry "${trace}" 1
17371
17372         pfid1=$($LFS path2fid "${file}")
17373
17374         # 1     2             3   4    5     6   7    8    9     10
17375         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17376         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17377
17378         echo "entry = '${entry[*]}'" >&2
17379
17380         pfid2=${entry[4]}
17381         if [[ "${pfid1}" != "${pfid2}" ]]; then
17382                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17383         fi
17384
17385         size=${entry[8]}
17386         if ((size != 1048576)); then
17387                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17388         fi
17389
17390         flags=${entry[10]}
17391         if [[ "${flags}" != "w" ]]; then
17392                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17393         fi
17394
17395         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17396         sleep 5
17397
17398         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17399                 error "cannot read '${file}'"
17400         sleep 5
17401
17402         do_facet ost1 killall -TERM ofd_access_log_reader
17403         wait
17404         rc=$?
17405
17406         if ((rc != 0)); then
17407                 error "ofd_access_log_reader exited with rc = '${rc}'"
17408         fi
17409
17410         oalr_expect_event_count alr_log_entry "${trace}" 1
17411
17412         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17413         echo "entry = '${entry[*]}'" >&2
17414
17415         pfid2=${entry[4]}
17416         if [[ "${pfid1}" != "${pfid2}" ]]; then
17417                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17418         fi
17419
17420         size=${entry[8]}
17421         if ((size != 524288)); then
17422                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17423         fi
17424
17425         flags=${entry[10]}
17426         if [[ "${flags}" != "r" ]]; then
17427                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17428         fi
17429 }
17430 run_test 165b "ofd access log entries are produced and consumed"
17431
17432 test_165c() {
17433         local trace="/tmp/${tfile}.trace"
17434         local file="${DIR}/${tdir}/${tfile}"
17435
17436         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17437                 skip "OFD access log unsupported"
17438
17439         test_mkdir "${DIR}/${tdir}"
17440
17441         setup_165
17442         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17443         sleep 5
17444
17445         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17446
17447         # 4096 / 64 = 64. Create twice as many entries.
17448         for ((i = 0; i < 128; i++)); do
17449                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17450                         error "cannot create file"
17451         done
17452
17453         sync
17454
17455         do_facet ost1 killall -TERM ofd_access_log_reader
17456         wait
17457         rc=$?
17458         if ((rc != 0)); then
17459                 error "ofd_access_log_reader exited with rc = '${rc}'"
17460         fi
17461
17462         unlinkmany  "${file}-%d" 128
17463 }
17464 run_test 165c "full ofd access logs do not block IOs"
17465
17466 oal_get_read_count() {
17467         local stats="$1"
17468
17469         # STATS lustre-OST0001 alr_read_count 1
17470
17471         do_facet ost1 cat "${stats}" |
17472         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17473              END { print count; }'
17474 }
17475
17476 oal_expect_read_count() {
17477         local stats="$1"
17478         local count
17479         local expect="$2"
17480
17481         # Ask ofd_access_log_reader to write stats.
17482         do_facet ost1 killall -USR1 ofd_access_log_reader
17483
17484         # Allow some time for things to happen.
17485         sleep 1
17486
17487         count=$(oal_get_read_count "${stats}")
17488         if ((count == expect)); then
17489                 return 0
17490         fi
17491
17492         error_noexit "bad read count, got ${count}, expected ${expect}"
17493         do_facet ost1 cat "${stats}" >&2
17494         exit 1
17495 }
17496
17497 test_165d() {
17498         local stats="/tmp/${tfile}.stats"
17499         local file="${DIR}/${tdir}/${tfile}"
17500         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17501
17502         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17503                 skip "OFD access log unsupported"
17504
17505         test_mkdir "${DIR}/${tdir}"
17506
17507         setup_165
17508         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17509         sleep 5
17510
17511         lfs setstripe -c 1 -i 0 "${file}"
17512
17513         do_facet ost1 lctl set_param "${param}=rw"
17514         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17515                 error "cannot create '${file}'"
17516         oal_expect_read_count "${stats}" 1
17517
17518         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17519                 error "cannot read '${file}'"
17520         oal_expect_read_count "${stats}" 2
17521
17522         do_facet ost1 lctl set_param "${param}=r"
17523         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17524                 error "cannot create '${file}'"
17525         oal_expect_read_count "${stats}" 2
17526
17527         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17528                 error "cannot read '${file}'"
17529         oal_expect_read_count "${stats}" 3
17530
17531         do_facet ost1 lctl set_param "${param}=w"
17532         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17533                 error "cannot create '${file}'"
17534         oal_expect_read_count "${stats}" 4
17535
17536         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17537                 error "cannot read '${file}'"
17538         oal_expect_read_count "${stats}" 4
17539
17540         do_facet ost1 lctl set_param "${param}=0"
17541         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17542                 error "cannot create '${file}'"
17543         oal_expect_read_count "${stats}" 4
17544
17545         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17546                 error "cannot read '${file}'"
17547         oal_expect_read_count "${stats}" 4
17548
17549         do_facet ost1 killall -TERM ofd_access_log_reader
17550         wait
17551         rc=$?
17552         if ((rc != 0)); then
17553                 error "ofd_access_log_reader exited with rc = '${rc}'"
17554         fi
17555 }
17556 run_test 165d "ofd_access_log mask works"
17557
17558 test_165e() {
17559         local stats="/tmp/${tfile}.stats"
17560         local file0="${DIR}/${tdir}-0/${tfile}"
17561         local file1="${DIR}/${tdir}-1/${tfile}"
17562
17563         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17564                 skip "OFD access log unsupported"
17565
17566         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17567
17568         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17569         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17570
17571         lfs setstripe -c 1 -i 0 "${file0}"
17572         lfs setstripe -c 1 -i 0 "${file1}"
17573
17574         setup_165
17575         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17576         sleep 5
17577
17578         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17579                 error "cannot create '${file0}'"
17580         sync
17581         oal_expect_read_count "${stats}" 0
17582
17583         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17584                 error "cannot create '${file1}'"
17585         sync
17586         oal_expect_read_count "${stats}" 1
17587
17588         do_facet ost1 killall -TERM ofd_access_log_reader
17589         wait
17590         rc=$?
17591         if ((rc != 0)); then
17592                 error "ofd_access_log_reader exited with rc = '${rc}'"
17593         fi
17594 }
17595 run_test 165e "ofd_access_log MDT index filter works"
17596
17597 test_165f() {
17598         local trace="/tmp/${tfile}.trace"
17599         local rc
17600         local count
17601
17602         setup_165
17603         do_facet ost1 timeout 60 ofd_access_log_reader \
17604                 --exit-on-close --debug=- --trace=- > "${trace}" &
17605         sleep 5
17606         stop ost1
17607
17608         wait
17609         rc=$?
17610
17611         if ((rc != 0)); then
17612                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17613                 cat "${trace}"
17614                 exit 1
17615         fi
17616 }
17617 run_test 165f "ofd_access_log_reader --exit-on-close works"
17618
17619 test_169() {
17620         # do directio so as not to populate the page cache
17621         log "creating a 10 Mb file"
17622         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17623                 error "multiop failed while creating a file"
17624         log "starting reads"
17625         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17626         log "truncating the file"
17627         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17628                 error "multiop failed while truncating the file"
17629         log "killing dd"
17630         kill %+ || true # reads might have finished
17631         echo "wait until dd is finished"
17632         wait
17633         log "removing the temporary file"
17634         rm -rf $DIR/$tfile || error "tmp file removal failed"
17635 }
17636 run_test 169 "parallel read and truncate should not deadlock"
17637
17638 test_170() {
17639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17640
17641         $LCTL clear     # bug 18514
17642         $LCTL debug_daemon start $TMP/${tfile}_log_good
17643         touch $DIR/$tfile
17644         $LCTL debug_daemon stop
17645         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17646                 error "sed failed to read log_good"
17647
17648         $LCTL debug_daemon start $TMP/${tfile}_log_good
17649         rm -rf $DIR/$tfile
17650         $LCTL debug_daemon stop
17651
17652         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17653                error "lctl df log_bad failed"
17654
17655         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17656         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17657
17658         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17659         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17660
17661         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17662                 error "bad_line good_line1 good_line2 are empty"
17663
17664         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17665         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17666         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17667
17668         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17669         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17670         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17671
17672         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17673                 error "bad_line_new good_line_new are empty"
17674
17675         local expected_good=$((good_line1 + good_line2*2))
17676
17677         rm -f $TMP/${tfile}*
17678         # LU-231, short malformed line may not be counted into bad lines
17679         if [ $bad_line -ne $bad_line_new ] &&
17680                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17681                 error "expected $bad_line bad lines, but got $bad_line_new"
17682                 return 1
17683         fi
17684
17685         if [ $expected_good -ne $good_line_new ]; then
17686                 error "expected $expected_good good lines, but got $good_line_new"
17687                 return 2
17688         fi
17689         true
17690 }
17691 run_test 170 "test lctl df to handle corrupted log ====================="
17692
17693 test_171() { # bug20592
17694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17695
17696         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17697         $LCTL set_param fail_loc=0x50e
17698         $LCTL set_param fail_val=3000
17699         multiop_bg_pause $DIR/$tfile O_s || true
17700         local MULTIPID=$!
17701         kill -USR1 $MULTIPID
17702         # cause log dump
17703         sleep 3
17704         wait $MULTIPID
17705         if dmesg | grep "recursive fault"; then
17706                 error "caught a recursive fault"
17707         fi
17708         $LCTL set_param fail_loc=0
17709         true
17710 }
17711 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17712
17713 # it would be good to share it with obdfilter-survey/iokit-libecho code
17714 setup_obdecho_osc () {
17715         local rc=0
17716         local ost_nid=$1
17717         local obdfilter_name=$2
17718         echo "Creating new osc for $obdfilter_name on $ost_nid"
17719         # make sure we can find loopback nid
17720         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17721
17722         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17723                            ${obdfilter_name}_osc_UUID || rc=2; }
17724         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17725                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17726         return $rc
17727 }
17728
17729 cleanup_obdecho_osc () {
17730         local obdfilter_name=$1
17731         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17732         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17733         return 0
17734 }
17735
17736 obdecho_test() {
17737         local OBD=$1
17738         local node=$2
17739         local pages=${3:-64}
17740         local rc=0
17741         local id
17742
17743         local count=10
17744         local obd_size=$(get_obd_size $node $OBD)
17745         local page_size=$(get_page_size $node)
17746         if [[ -n "$obd_size" ]]; then
17747                 local new_count=$((obd_size / (pages * page_size / 1024)))
17748                 [[ $new_count -ge $count ]] || count=$new_count
17749         fi
17750
17751         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17752         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17753                            rc=2; }
17754         if [ $rc -eq 0 ]; then
17755             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17756             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17757         fi
17758         echo "New object id is $id"
17759         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17760                            rc=4; }
17761         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17762                            "test_brw $count w v $pages $id" || rc=4; }
17763         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17764                            rc=4; }
17765         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17766                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17767         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17768                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17769         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17770         return $rc
17771 }
17772
17773 test_180a() {
17774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17775
17776         if ! [ -d /sys/fs/lustre/echo_client ] &&
17777            ! module_loaded obdecho; then
17778                 load_module obdecho/obdecho &&
17779                         stack_trap "rmmod obdecho" EXIT ||
17780                         error "unable to load obdecho on client"
17781         fi
17782
17783         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17784         local host=$($LCTL get_param -n osc.$osc.import |
17785                      awk '/current_connection:/ { print $2 }' )
17786         local target=$($LCTL get_param -n osc.$osc.import |
17787                        awk '/target:/ { print $2 }' )
17788         target=${target%_UUID}
17789
17790         if [ -n "$target" ]; then
17791                 setup_obdecho_osc $host $target &&
17792                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17793                         { error "obdecho setup failed with $?"; return; }
17794
17795                 obdecho_test ${target}_osc client ||
17796                         error "obdecho_test failed on ${target}_osc"
17797         else
17798                 $LCTL get_param osc.$osc.import
17799                 error "there is no osc.$osc.import target"
17800         fi
17801 }
17802 run_test 180a "test obdecho on osc"
17803
17804 test_180b() {
17805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17806         remote_ost_nodsh && skip "remote OST with nodsh"
17807
17808         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17809                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17810                 error "failed to load module obdecho"
17811
17812         local target=$(do_facet ost1 $LCTL dl |
17813                        awk '/obdfilter/ { print $4; exit; }')
17814
17815         if [ -n "$target" ]; then
17816                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17817         else
17818                 do_facet ost1 $LCTL dl
17819                 error "there is no obdfilter target on ost1"
17820         fi
17821 }
17822 run_test 180b "test obdecho directly on obdfilter"
17823
17824 test_180c() { # LU-2598
17825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17826         remote_ost_nodsh && skip "remote OST with nodsh"
17827         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17828                 skip "Need MDS version at least 2.4.0"
17829
17830         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17831                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17832                 error "failed to load module obdecho"
17833
17834         local target=$(do_facet ost1 $LCTL dl |
17835                        awk '/obdfilter/ { print $4; exit; }')
17836
17837         if [ -n "$target" ]; then
17838                 local pages=16384 # 64MB bulk I/O RPC size
17839
17840                 obdecho_test "$target" ost1 "$pages" ||
17841                         error "obdecho_test with pages=$pages failed with $?"
17842         else
17843                 do_facet ost1 $LCTL dl
17844                 error "there is no obdfilter target on ost1"
17845         fi
17846 }
17847 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17848
17849 test_181() { # bug 22177
17850         test_mkdir $DIR/$tdir
17851         # create enough files to index the directory
17852         createmany -o $DIR/$tdir/foobar 4000
17853         # print attributes for debug purpose
17854         lsattr -d .
17855         # open dir
17856         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17857         MULTIPID=$!
17858         # remove the files & current working dir
17859         unlinkmany $DIR/$tdir/foobar 4000
17860         rmdir $DIR/$tdir
17861         kill -USR1 $MULTIPID
17862         wait $MULTIPID
17863         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17864         return 0
17865 }
17866 run_test 181 "Test open-unlinked dir ========================"
17867
17868 test_182() {
17869         local fcount=1000
17870         local tcount=10
17871
17872         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17873
17874         $LCTL set_param mdc.*.rpc_stats=clear
17875
17876         for (( i = 0; i < $tcount; i++ )) ; do
17877                 mkdir $DIR/$tdir/$i
17878         done
17879
17880         for (( i = 0; i < $tcount; i++ )) ; do
17881                 createmany -o $DIR/$tdir/$i/f- $fcount &
17882         done
17883         wait
17884
17885         for (( i = 0; i < $tcount; i++ )) ; do
17886                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17887         done
17888         wait
17889
17890         $LCTL get_param mdc.*.rpc_stats
17891
17892         rm -rf $DIR/$tdir
17893 }
17894 run_test 182 "Test parallel modify metadata operations ================"
17895
17896 test_183() { # LU-2275
17897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17898         remote_mds_nodsh && skip "remote MDS with nodsh"
17899         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17900                 skip "Need MDS version at least 2.3.56"
17901
17902         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17903         echo aaa > $DIR/$tdir/$tfile
17904
17905 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17906         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17907
17908         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17909         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17910
17911         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17912
17913         # Flush negative dentry cache
17914         touch $DIR/$tdir/$tfile
17915
17916         # We are not checking for any leaked references here, they'll
17917         # become evident next time we do cleanup with module unload.
17918         rm -rf $DIR/$tdir
17919 }
17920 run_test 183 "No crash or request leak in case of strange dispositions ========"
17921
17922 # test suite 184 is for LU-2016, LU-2017
17923 test_184a() {
17924         check_swap_layouts_support
17925
17926         dir0=$DIR/$tdir/$testnum
17927         test_mkdir -p -c1 $dir0
17928         ref1=/etc/passwd
17929         ref2=/etc/group
17930         file1=$dir0/f1
17931         file2=$dir0/f2
17932         $LFS setstripe -c1 $file1
17933         cp $ref1 $file1
17934         $LFS setstripe -c2 $file2
17935         cp $ref2 $file2
17936         gen1=$($LFS getstripe -g $file1)
17937         gen2=$($LFS getstripe -g $file2)
17938
17939         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17940         gen=$($LFS getstripe -g $file1)
17941         [[ $gen1 != $gen ]] ||
17942                 error "Layout generation on $file1 does not change"
17943         gen=$($LFS getstripe -g $file2)
17944         [[ $gen2 != $gen ]] ||
17945                 error "Layout generation on $file2 does not change"
17946
17947         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17948         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17949
17950         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17951 }
17952 run_test 184a "Basic layout swap"
17953
17954 test_184b() {
17955         check_swap_layouts_support
17956
17957         dir0=$DIR/$tdir/$testnum
17958         mkdir -p $dir0 || error "creating dir $dir0"
17959         file1=$dir0/f1
17960         file2=$dir0/f2
17961         file3=$dir0/f3
17962         dir1=$dir0/d1
17963         dir2=$dir0/d2
17964         mkdir $dir1 $dir2
17965         $LFS setstripe -c1 $file1
17966         $LFS setstripe -c2 $file2
17967         $LFS setstripe -c1 $file3
17968         chown $RUNAS_ID $file3
17969         gen1=$($LFS getstripe -g $file1)
17970         gen2=$($LFS getstripe -g $file2)
17971
17972         $LFS swap_layouts $dir1 $dir2 &&
17973                 error "swap of directories layouts should fail"
17974         $LFS swap_layouts $dir1 $file1 &&
17975                 error "swap of directory and file layouts should fail"
17976         $RUNAS $LFS swap_layouts $file1 $file2 &&
17977                 error "swap of file we cannot write should fail"
17978         $LFS swap_layouts $file1 $file3 &&
17979                 error "swap of file with different owner should fail"
17980         /bin/true # to clear error code
17981 }
17982 run_test 184b "Forbidden layout swap (will generate errors)"
17983
17984 test_184c() {
17985         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17986         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17987         check_swap_layouts_support
17988         check_swap_layout_no_dom $DIR
17989
17990         local dir0=$DIR/$tdir/$testnum
17991         mkdir -p $dir0 || error "creating dir $dir0"
17992
17993         local ref1=$dir0/ref1
17994         local ref2=$dir0/ref2
17995         local file1=$dir0/file1
17996         local file2=$dir0/file2
17997         # create a file large enough for the concurrent test
17998         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17999         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18000         echo "ref file size: ref1($(stat -c %s $ref1))," \
18001              "ref2($(stat -c %s $ref2))"
18002
18003         cp $ref2 $file2
18004         dd if=$ref1 of=$file1 bs=16k &
18005         local DD_PID=$!
18006
18007         # Make sure dd starts to copy file, but wait at most 5 seconds
18008         local loops=0
18009         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18010
18011         $LFS swap_layouts $file1 $file2
18012         local rc=$?
18013         wait $DD_PID
18014         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18015         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18016
18017         # how many bytes copied before swapping layout
18018         local copied=$(stat -c %s $file2)
18019         local remaining=$(stat -c %s $ref1)
18020         remaining=$((remaining - copied))
18021         echo "Copied $copied bytes before swapping layout..."
18022
18023         cmp -n $copied $file1 $ref2 | grep differ &&
18024                 error "Content mismatch [0, $copied) of ref2 and file1"
18025         cmp -n $copied $file2 $ref1 ||
18026                 error "Content mismatch [0, $copied) of ref1 and file2"
18027         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18028                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18029
18030         # clean up
18031         rm -f $ref1 $ref2 $file1 $file2
18032 }
18033 run_test 184c "Concurrent write and layout swap"
18034
18035 test_184d() {
18036         check_swap_layouts_support
18037         check_swap_layout_no_dom $DIR
18038         [ -z "$(which getfattr 2>/dev/null)" ] &&
18039                 skip_env "no getfattr command"
18040
18041         local file1=$DIR/$tdir/$tfile-1
18042         local file2=$DIR/$tdir/$tfile-2
18043         local file3=$DIR/$tdir/$tfile-3
18044         local lovea1
18045         local lovea2
18046
18047         mkdir -p $DIR/$tdir
18048         touch $file1 || error "create $file1 failed"
18049         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18050                 error "create $file2 failed"
18051         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18052                 error "create $file3 failed"
18053         lovea1=$(get_layout_param $file1)
18054
18055         $LFS swap_layouts $file2 $file3 ||
18056                 error "swap $file2 $file3 layouts failed"
18057         $LFS swap_layouts $file1 $file2 ||
18058                 error "swap $file1 $file2 layouts failed"
18059
18060         lovea2=$(get_layout_param $file2)
18061         echo "$lovea1"
18062         echo "$lovea2"
18063         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18064
18065         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18066         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18067 }
18068 run_test 184d "allow stripeless layouts swap"
18069
18070 test_184e() {
18071         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18072                 skip "Need MDS version at least 2.6.94"
18073         check_swap_layouts_support
18074         check_swap_layout_no_dom $DIR
18075         [ -z "$(which getfattr 2>/dev/null)" ] &&
18076                 skip_env "no getfattr command"
18077
18078         local file1=$DIR/$tdir/$tfile-1
18079         local file2=$DIR/$tdir/$tfile-2
18080         local file3=$DIR/$tdir/$tfile-3
18081         local lovea
18082
18083         mkdir -p $DIR/$tdir
18084         touch $file1 || error "create $file1 failed"
18085         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18086                 error "create $file2 failed"
18087         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18088                 error "create $file3 failed"
18089
18090         $LFS swap_layouts $file1 $file2 ||
18091                 error "swap $file1 $file2 layouts failed"
18092
18093         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18094         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18095
18096         echo 123 > $file1 || error "Should be able to write into $file1"
18097
18098         $LFS swap_layouts $file1 $file3 ||
18099                 error "swap $file1 $file3 layouts failed"
18100
18101         echo 123 > $file1 || error "Should be able to write into $file1"
18102
18103         rm -rf $file1 $file2 $file3
18104 }
18105 run_test 184e "Recreate layout after stripeless layout swaps"
18106
18107 test_184f() {
18108         # Create a file with name longer than sizeof(struct stat) ==
18109         # 144 to see if we can get chars from the file name to appear
18110         # in the returned striping. Note that 'f' == 0x66.
18111         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18112
18113         mkdir -p $DIR/$tdir
18114         mcreate $DIR/$tdir/$file
18115         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18116                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18117         fi
18118 }
18119 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18120
18121 test_185() { # LU-2441
18122         # LU-3553 - no volatile file support in old servers
18123         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18124                 skip "Need MDS version at least 2.3.60"
18125
18126         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18127         touch $DIR/$tdir/spoo
18128         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18129         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18130                 error "cannot create/write a volatile file"
18131         [ "$FILESET" == "" ] &&
18132         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18133                 error "FID is still valid after close"
18134
18135         multiop_bg_pause $DIR/$tdir vVw4096_c
18136         local multi_pid=$!
18137
18138         local OLD_IFS=$IFS
18139         IFS=":"
18140         local fidv=($fid)
18141         IFS=$OLD_IFS
18142         # assume that the next FID for this client is sequential, since stdout
18143         # is unfortunately eaten by multiop_bg_pause
18144         local n=$((${fidv[1]} + 1))
18145         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18146         if [ "$FILESET" == "" ]; then
18147                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18148                         error "FID is missing before close"
18149         fi
18150         kill -USR1 $multi_pid
18151         # 1 second delay, so if mtime change we will see it
18152         sleep 1
18153         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18154         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18155 }
18156 run_test 185 "Volatile file support"
18157
18158 function create_check_volatile() {
18159         local idx=$1
18160         local tgt
18161
18162         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18163         local PID=$!
18164         sleep 1
18165         local FID=$(cat /tmp/${tfile}.fid)
18166         [ "$FID" == "" ] && error "can't get FID for volatile"
18167         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18168         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18169         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18170         kill -USR1 $PID
18171         wait
18172         sleep 1
18173         cancel_lru_locks mdc # flush opencache
18174         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18175         return 0
18176 }
18177
18178 test_185a(){
18179         # LU-12516 - volatile creation via .lustre
18180         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18181                 skip "Need MDS version at least 2.3.55"
18182
18183         create_check_volatile 0
18184         [ $MDSCOUNT -lt 2 ] && return 0
18185
18186         # DNE case
18187         create_check_volatile 1
18188
18189         return 0
18190 }
18191 run_test 185a "Volatile file creation in .lustre/fid/"
18192
18193 test_187a() {
18194         remote_mds_nodsh && skip "remote MDS with nodsh"
18195         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18196                 skip "Need MDS version at least 2.3.0"
18197
18198         local dir0=$DIR/$tdir/$testnum
18199         mkdir -p $dir0 || error "creating dir $dir0"
18200
18201         local file=$dir0/file1
18202         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18203         local dv1=$($LFS data_version $file)
18204         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18205         local dv2=$($LFS data_version $file)
18206         [[ $dv1 != $dv2 ]] ||
18207                 error "data version did not change on write $dv1 == $dv2"
18208
18209         # clean up
18210         rm -f $file1
18211 }
18212 run_test 187a "Test data version change"
18213
18214 test_187b() {
18215         remote_mds_nodsh && skip "remote MDS with nodsh"
18216         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18217                 skip "Need MDS version at least 2.3.0"
18218
18219         local dir0=$DIR/$tdir/$testnum
18220         mkdir -p $dir0 || error "creating dir $dir0"
18221
18222         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18223         [[ ${DV[0]} != ${DV[1]} ]] ||
18224                 error "data version did not change on write"\
18225                       " ${DV[0]} == ${DV[1]}"
18226
18227         # clean up
18228         rm -f $file1
18229 }
18230 run_test 187b "Test data version change on volatile file"
18231
18232 test_200() {
18233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18234         remote_mgs_nodsh && skip "remote MGS with nodsh"
18235         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18236
18237         local POOL=${POOL:-cea1}
18238         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18239         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18240         # Pool OST targets
18241         local first_ost=0
18242         local last_ost=$(($OSTCOUNT - 1))
18243         local ost_step=2
18244         local ost_list=$(seq $first_ost $ost_step $last_ost)
18245         local ost_range="$first_ost $last_ost $ost_step"
18246         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18247         local file_dir=$POOL_ROOT/file_tst
18248         local subdir=$test_path/subdir
18249         local rc=0
18250
18251         while : ; do
18252                 # former test_200a test_200b
18253                 pool_add $POOL                          || { rc=$? ; break; }
18254                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18255                 # former test_200c test_200d
18256                 mkdir -p $test_path
18257                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18258                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18259                 mkdir -p $subdir
18260                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18261                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18262                                                         || { rc=$? ; break; }
18263                 # former test_200e test_200f
18264                 local files=$((OSTCOUNT*3))
18265                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18266                                                         || { rc=$? ; break; }
18267                 pool_create_files $POOL $file_dir $files "$ost_list" \
18268                                                         || { rc=$? ; break; }
18269                 # former test_200g test_200h
18270                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18271                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18272
18273                 # former test_201a test_201b test_201c
18274                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18275
18276                 local f=$test_path/$tfile
18277                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18278                 pool_remove $POOL $f                    || { rc=$? ; break; }
18279                 break
18280         done
18281
18282         destroy_test_pools
18283
18284         return $rc
18285 }
18286 run_test 200 "OST pools"
18287
18288 # usage: default_attr <count | size | offset>
18289 default_attr() {
18290         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18291 }
18292
18293 # usage: check_default_stripe_attr
18294 check_default_stripe_attr() {
18295         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18296         case $1 in
18297         --stripe-count|-c)
18298                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18299         --stripe-size|-S)
18300                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18301         --stripe-index|-i)
18302                 EXPECTED=-1;;
18303         *)
18304                 error "unknown getstripe attr '$1'"
18305         esac
18306
18307         [ $ACTUAL == $EXPECTED ] ||
18308                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18309 }
18310
18311 test_204a() {
18312         test_mkdir $DIR/$tdir
18313         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18314
18315         check_default_stripe_attr --stripe-count
18316         check_default_stripe_attr --stripe-size
18317         check_default_stripe_attr --stripe-index
18318 }
18319 run_test 204a "Print default stripe attributes"
18320
18321 test_204b() {
18322         test_mkdir $DIR/$tdir
18323         $LFS setstripe --stripe-count 1 $DIR/$tdir
18324
18325         check_default_stripe_attr --stripe-size
18326         check_default_stripe_attr --stripe-index
18327 }
18328 run_test 204b "Print default stripe size and offset"
18329
18330 test_204c() {
18331         test_mkdir $DIR/$tdir
18332         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18333
18334         check_default_stripe_attr --stripe-count
18335         check_default_stripe_attr --stripe-index
18336 }
18337 run_test 204c "Print default stripe count and offset"
18338
18339 test_204d() {
18340         test_mkdir $DIR/$tdir
18341         $LFS setstripe --stripe-index 0 $DIR/$tdir
18342
18343         check_default_stripe_attr --stripe-count
18344         check_default_stripe_attr --stripe-size
18345 }
18346 run_test 204d "Print default stripe count and size"
18347
18348 test_204e() {
18349         test_mkdir $DIR/$tdir
18350         $LFS setstripe -d $DIR/$tdir
18351
18352         check_default_stripe_attr --stripe-count --raw
18353         check_default_stripe_attr --stripe-size --raw
18354         check_default_stripe_attr --stripe-index --raw
18355 }
18356 run_test 204e "Print raw stripe attributes"
18357
18358 test_204f() {
18359         test_mkdir $DIR/$tdir
18360         $LFS setstripe --stripe-count 1 $DIR/$tdir
18361
18362         check_default_stripe_attr --stripe-size --raw
18363         check_default_stripe_attr --stripe-index --raw
18364 }
18365 run_test 204f "Print raw stripe size and offset"
18366
18367 test_204g() {
18368         test_mkdir $DIR/$tdir
18369         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18370
18371         check_default_stripe_attr --stripe-count --raw
18372         check_default_stripe_attr --stripe-index --raw
18373 }
18374 run_test 204g "Print raw stripe count and offset"
18375
18376 test_204h() {
18377         test_mkdir $DIR/$tdir
18378         $LFS setstripe --stripe-index 0 $DIR/$tdir
18379
18380         check_default_stripe_attr --stripe-count --raw
18381         check_default_stripe_attr --stripe-size --raw
18382 }
18383 run_test 204h "Print raw stripe count and size"
18384
18385 # Figure out which job scheduler is being used, if any,
18386 # or use a fake one
18387 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18388         JOBENV=SLURM_JOB_ID
18389 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18390         JOBENV=LSB_JOBID
18391 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18392         JOBENV=PBS_JOBID
18393 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18394         JOBENV=LOADL_STEP_ID
18395 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18396         JOBENV=JOB_ID
18397 else
18398         $LCTL list_param jobid_name > /dev/null 2>&1
18399         if [ $? -eq 0 ]; then
18400                 JOBENV=nodelocal
18401         else
18402                 JOBENV=FAKE_JOBID
18403         fi
18404 fi
18405 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18406
18407 verify_jobstats() {
18408         local cmd=($1)
18409         shift
18410         local facets="$@"
18411
18412 # we don't really need to clear the stats for this test to work, since each
18413 # command has a unique jobid, but it makes debugging easier if needed.
18414 #       for facet in $facets; do
18415 #               local dev=$(convert_facet2label $facet)
18416 #               # clear old jobstats
18417 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18418 #       done
18419
18420         # use a new JobID for each test, or we might see an old one
18421         [ "$JOBENV" = "FAKE_JOBID" ] &&
18422                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18423
18424         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18425
18426         [ "$JOBENV" = "nodelocal" ] && {
18427                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18428                 $LCTL set_param jobid_name=$FAKE_JOBID
18429                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18430         }
18431
18432         log "Test: ${cmd[*]}"
18433         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18434
18435         if [ $JOBENV = "FAKE_JOBID" ]; then
18436                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18437         else
18438                 ${cmd[*]}
18439         fi
18440
18441         # all files are created on OST0000
18442         for facet in $facets; do
18443                 local stats="*.$(convert_facet2label $facet).job_stats"
18444
18445                 # strip out libtool wrappers for in-tree executables
18446                 if (( $(do_facet $facet lctl get_param $stats |
18447                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18448                         do_facet $facet lctl get_param $stats
18449                         error "No jobstats for $JOBVAL found on $facet::$stats"
18450                 fi
18451         done
18452 }
18453
18454 jobstats_set() {
18455         local new_jobenv=$1
18456
18457         set_persistent_param_and_check client "jobid_var" \
18458                 "$FSNAME.sys.jobid_var" $new_jobenv
18459 }
18460
18461 test_205a() { # Job stats
18462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18463         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18464                 skip "Need MDS version with at least 2.7.1"
18465         remote_mgs_nodsh && skip "remote MGS with nodsh"
18466         remote_mds_nodsh && skip "remote MDS with nodsh"
18467         remote_ost_nodsh && skip "remote OST with nodsh"
18468         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18469                 skip "Server doesn't support jobstats"
18470         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18471
18472         local old_jobenv=$($LCTL get_param -n jobid_var)
18473         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18474
18475         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18476                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18477         else
18478                 stack_trap "do_facet mgs $PERM_CMD \
18479                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18480         fi
18481         changelog_register
18482
18483         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18484                                 mdt.*.job_cleanup_interval | head -n 1)
18485         local new_interval=5
18486         do_facet $SINGLEMDS \
18487                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18488         stack_trap "do_facet $SINGLEMDS \
18489                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18490         local start=$SECONDS
18491
18492         local cmd
18493         # mkdir
18494         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18495         verify_jobstats "$cmd" "$SINGLEMDS"
18496         # rmdir
18497         cmd="rmdir $DIR/$tdir"
18498         verify_jobstats "$cmd" "$SINGLEMDS"
18499         # mkdir on secondary MDT
18500         if [ $MDSCOUNT -gt 1 ]; then
18501                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18502                 verify_jobstats "$cmd" "mds2"
18503         fi
18504         # mknod
18505         cmd="mknod $DIR/$tfile c 1 3"
18506         verify_jobstats "$cmd" "$SINGLEMDS"
18507         # unlink
18508         cmd="rm -f $DIR/$tfile"
18509         verify_jobstats "$cmd" "$SINGLEMDS"
18510         # create all files on OST0000 so verify_jobstats can find OST stats
18511         # open & close
18512         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18513         verify_jobstats "$cmd" "$SINGLEMDS"
18514         # setattr
18515         cmd="touch $DIR/$tfile"
18516         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18517         # write
18518         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18519         verify_jobstats "$cmd" "ost1"
18520         # read
18521         cancel_lru_locks osc
18522         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18523         verify_jobstats "$cmd" "ost1"
18524         # truncate
18525         cmd="$TRUNCATE $DIR/$tfile 0"
18526         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18527         # rename
18528         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18529         verify_jobstats "$cmd" "$SINGLEMDS"
18530         # jobstats expiry - sleep until old stats should be expired
18531         local left=$((new_interval + 5 - (SECONDS - start)))
18532         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18533                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18534                         "0" $left
18535         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18536         verify_jobstats "$cmd" "$SINGLEMDS"
18537         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18538             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18539
18540         # Ensure that jobid are present in changelog (if supported by MDS)
18541         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18542                 changelog_dump | tail -10
18543                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18544                 [ $jobids -eq 9 ] ||
18545                         error "Wrong changelog jobid count $jobids != 9"
18546
18547                 # LU-5862
18548                 JOBENV="disable"
18549                 jobstats_set $JOBENV
18550                 touch $DIR/$tfile
18551                 changelog_dump | grep $tfile
18552                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18553                 [ $jobids -eq 0 ] ||
18554                         error "Unexpected jobids when jobid_var=$JOBENV"
18555         fi
18556
18557         # test '%j' access to environment variable - if supported
18558         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18559                 JOBENV="JOBCOMPLEX"
18560                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18561
18562                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18563         fi
18564
18565         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18566                 JOBENV="JOBCOMPLEX"
18567                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18568
18569                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18570         fi
18571
18572         # test '%j' access to per-session jobid - if supported
18573         if lctl list_param jobid_this_session > /dev/null 2>&1
18574         then
18575                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18576                 lctl set_param jobid_this_session=$USER
18577
18578                 JOBENV="JOBCOMPLEX"
18579                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18580
18581                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18582         fi
18583 }
18584 run_test 205a "Verify job stats"
18585
18586 # LU-13117, LU-13597
18587 test_205b() {
18588         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18589                 skip "Need MDS version at least 2.13.54.91"
18590
18591         job_stats="mdt.*.job_stats"
18592         $LCTL set_param $job_stats=clear
18593         # Setting jobid_var to USER might not be supported
18594         $LCTL set_param jobid_var=USER || true
18595         $LCTL set_param jobid_name="%e.%u"
18596         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18597         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18598                 grep "job_id:.*foolish" &&
18599                         error "Unexpected jobid found"
18600         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18601                 grep "open:.*min.*max.*sum" ||
18602                         error "wrong job_stats format found"
18603 }
18604 run_test 205b "Verify job stats jobid and output format"
18605
18606 # LU-13733
18607 test_205c() {
18608         $LCTL set_param llite.*.stats=0
18609         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18610         $LCTL get_param llite.*.stats
18611         $LCTL get_param llite.*.stats | grep \
18612                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18613                         error "wrong client stats format found"
18614 }
18615 run_test 205c "Verify client stats format"
18616
18617 # LU-1480, LU-1773 and LU-1657
18618 test_206() {
18619         mkdir -p $DIR/$tdir
18620         $LFS setstripe -c -1 $DIR/$tdir
18621 #define OBD_FAIL_LOV_INIT 0x1403
18622         $LCTL set_param fail_loc=0xa0001403
18623         $LCTL set_param fail_val=1
18624         touch $DIR/$tdir/$tfile || true
18625 }
18626 run_test 206 "fail lov_init_raid0() doesn't lbug"
18627
18628 test_207a() {
18629         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18630         local fsz=`stat -c %s $DIR/$tfile`
18631         cancel_lru_locks mdc
18632
18633         # do not return layout in getattr intent
18634 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18635         $LCTL set_param fail_loc=0x170
18636         local sz=`stat -c %s $DIR/$tfile`
18637
18638         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18639
18640         rm -rf $DIR/$tfile
18641 }
18642 run_test 207a "can refresh layout at glimpse"
18643
18644 test_207b() {
18645         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18646         local cksum=`md5sum $DIR/$tfile`
18647         local fsz=`stat -c %s $DIR/$tfile`
18648         cancel_lru_locks mdc
18649         cancel_lru_locks osc
18650
18651         # do not return layout in getattr intent
18652 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18653         $LCTL set_param fail_loc=0x171
18654
18655         # it will refresh layout after the file is opened but before read issues
18656         echo checksum is "$cksum"
18657         echo "$cksum" |md5sum -c --quiet || error "file differs"
18658
18659         rm -rf $DIR/$tfile
18660 }
18661 run_test 207b "can refresh layout at open"
18662
18663 test_208() {
18664         # FIXME: in this test suite, only RD lease is used. This is okay
18665         # for now as only exclusive open is supported. After generic lease
18666         # is done, this test suite should be revised. - Jinshan
18667
18668         remote_mds_nodsh && skip "remote MDS with nodsh"
18669         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18670                 skip "Need MDS version at least 2.4.52"
18671
18672         echo "==== test 1: verify get lease work"
18673         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18674
18675         echo "==== test 2: verify lease can be broken by upcoming open"
18676         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18677         local PID=$!
18678         sleep 2
18679
18680         $MULTIOP $DIR/$tfile oO_RDWR:c
18681         kill -USR1 $PID && wait $PID || error "break lease error"
18682
18683         echo "==== test 3: verify lease can't be granted if an open already exists"
18684         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18685         local PID=$!
18686         sleep 2
18687
18688         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18689         kill -USR1 $PID && wait $PID || error "open file error"
18690
18691         echo "==== test 4: lease can sustain over recovery"
18692         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18693         PID=$!
18694         sleep 2
18695
18696         fail mds1
18697
18698         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18699
18700         echo "==== test 5: lease broken can't be regained by replay"
18701         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18702         PID=$!
18703         sleep 2
18704
18705         # open file to break lease and then recovery
18706         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18707         fail mds1
18708
18709         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18710
18711         rm -f $DIR/$tfile
18712 }
18713 run_test 208 "Exclusive open"
18714
18715 test_209() {
18716         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18717                 skip_env "must have disp_stripe"
18718
18719         touch $DIR/$tfile
18720         sync; sleep 5; sync;
18721
18722         echo 3 > /proc/sys/vm/drop_caches
18723         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18724                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18725         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18726
18727         # open/close 500 times
18728         for i in $(seq 500); do
18729                 cat $DIR/$tfile
18730         done
18731
18732         echo 3 > /proc/sys/vm/drop_caches
18733         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18734                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18735         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18736
18737         echo "before: $req_before, after: $req_after"
18738         [ $((req_after - req_before)) -ge 300 ] &&
18739                 error "open/close requests are not freed"
18740         return 0
18741 }
18742 run_test 209 "read-only open/close requests should be freed promptly"
18743
18744 test_210() {
18745         local pid
18746
18747         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18748         pid=$!
18749         sleep 1
18750
18751         $LFS getstripe $DIR/$tfile
18752         kill -USR1 $pid
18753         wait $pid || error "multiop failed"
18754
18755         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18756         pid=$!
18757         sleep 1
18758
18759         $LFS getstripe $DIR/$tfile
18760         kill -USR1 $pid
18761         wait $pid || error "multiop failed"
18762 }
18763 run_test 210 "lfs getstripe does not break leases"
18764
18765 test_212() {
18766         size=`date +%s`
18767         size=$((size % 8192 + 1))
18768         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18769         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18770         rm -f $DIR/f212 $DIR/f212.xyz
18771 }
18772 run_test 212 "Sendfile test ============================================"
18773
18774 test_213() {
18775         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18776         cancel_lru_locks osc
18777         lctl set_param fail_loc=0x8000040f
18778         # generate a read lock
18779         cat $DIR/$tfile > /dev/null
18780         # write to the file, it will try to cancel the above read lock.
18781         cat /etc/hosts >> $DIR/$tfile
18782 }
18783 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18784
18785 test_214() { # for bug 20133
18786         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18787         for (( i=0; i < 340; i++ )) ; do
18788                 touch $DIR/$tdir/d214c/a$i
18789         done
18790
18791         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18792         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18793         ls $DIR/d214c || error "ls $DIR/d214c failed"
18794         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18795         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18796 }
18797 run_test 214 "hash-indexed directory test - bug 20133"
18798
18799 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18800 create_lnet_proc_files() {
18801         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18802 }
18803
18804 # counterpart of create_lnet_proc_files
18805 remove_lnet_proc_files() {
18806         rm -f $TMP/lnet_$1.sys
18807 }
18808
18809 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18810 # 3rd arg as regexp for body
18811 check_lnet_proc_stats() {
18812         local l=$(cat "$TMP/lnet_$1" |wc -l)
18813         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18814
18815         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18816 }
18817
18818 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18819 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18820 # optional and can be regexp for 2nd line (lnet.routes case)
18821 check_lnet_proc_entry() {
18822         local blp=2          # blp stands for 'position of 1st line of body'
18823         [ -z "$5" ] || blp=3 # lnet.routes case
18824
18825         local l=$(cat "$TMP/lnet_$1" |wc -l)
18826         # subtracting one from $blp because the body can be empty
18827         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18828
18829         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18830                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18831
18832         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18833                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18834
18835         # bail out if any unexpected line happened
18836         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18837         [ "$?" != 0 ] || error "$2 misformatted"
18838 }
18839
18840 test_215() { # for bugs 18102, 21079, 21517
18841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18842
18843         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18844         local P='[1-9][0-9]*'           # positive numeric
18845         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18846         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18847         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18848         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18849
18850         local L1 # regexp for 1st line
18851         local L2 # regexp for 2nd line (optional)
18852         local BR # regexp for the rest (body)
18853
18854         # lnet.stats should look as 11 space-separated non-negative numerics
18855         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18856         create_lnet_proc_files "stats"
18857         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18858         remove_lnet_proc_files "stats"
18859
18860         # lnet.routes should look like this:
18861         # Routing disabled/enabled
18862         # net hops priority state router
18863         # where net is a string like tcp0, hops > 0, priority >= 0,
18864         # state is up/down,
18865         # router is a string like 192.168.1.1@tcp2
18866         L1="^Routing (disabled|enabled)$"
18867         L2="^net +hops +priority +state +router$"
18868         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18869         create_lnet_proc_files "routes"
18870         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18871         remove_lnet_proc_files "routes"
18872
18873         # lnet.routers should look like this:
18874         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18875         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18876         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18877         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18878         L1="^ref +rtr_ref +alive +router$"
18879         BR="^$P +$P +(up|down) +$NID$"
18880         create_lnet_proc_files "routers"
18881         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18882         remove_lnet_proc_files "routers"
18883
18884         # lnet.peers should look like this:
18885         # nid refs state last max rtr min tx min queue
18886         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18887         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18888         # numeric (0 or >0 or <0), queue >= 0.
18889         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18890         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18891         create_lnet_proc_files "peers"
18892         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18893         remove_lnet_proc_files "peers"
18894
18895         # lnet.buffers  should look like this:
18896         # pages count credits min
18897         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18898         L1="^pages +count +credits +min$"
18899         BR="^ +$N +$N +$I +$I$"
18900         create_lnet_proc_files "buffers"
18901         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18902         remove_lnet_proc_files "buffers"
18903
18904         # lnet.nis should look like this:
18905         # nid status alive refs peer rtr max tx min
18906         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18907         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18908         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18909         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18910         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18911         create_lnet_proc_files "nis"
18912         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18913         remove_lnet_proc_files "nis"
18914
18915         # can we successfully write to lnet.stats?
18916         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18917 }
18918 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18919
18920 test_216() { # bug 20317
18921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18922         remote_ost_nodsh && skip "remote OST with nodsh"
18923
18924         local node
18925         local facets=$(get_facets OST)
18926         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18927
18928         save_lustre_params client "osc.*.contention_seconds" > $p
18929         save_lustre_params $facets \
18930                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18931         save_lustre_params $facets \
18932                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18933         save_lustre_params $facets \
18934                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18935         clear_stats osc.*.osc_stats
18936
18937         # agressive lockless i/o settings
18938         do_nodes $(comma_list $(osts_nodes)) \
18939                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18940                         ldlm.namespaces.filter-*.contended_locks=0 \
18941                         ldlm.namespaces.filter-*.contention_seconds=60"
18942         lctl set_param -n osc.*.contention_seconds=60
18943
18944         $DIRECTIO write $DIR/$tfile 0 10 4096
18945         $CHECKSTAT -s 40960 $DIR/$tfile
18946
18947         # disable lockless i/o
18948         do_nodes $(comma_list $(osts_nodes)) \
18949                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18950                         ldlm.namespaces.filter-*.contended_locks=32 \
18951                         ldlm.namespaces.filter-*.contention_seconds=0"
18952         lctl set_param -n osc.*.contention_seconds=0
18953         clear_stats osc.*.osc_stats
18954
18955         dd if=/dev/zero of=$DIR/$tfile count=0
18956         $CHECKSTAT -s 0 $DIR/$tfile
18957
18958         restore_lustre_params <$p
18959         rm -f $p
18960         rm $DIR/$tfile
18961 }
18962 run_test 216 "check lockless direct write updates file size and kms correctly"
18963
18964 test_217() { # bug 22430
18965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18966
18967         local node
18968         local nid
18969
18970         for node in $(nodes_list); do
18971                 nid=$(host_nids_address $node $NETTYPE)
18972                 if [[ $nid = *-* ]] ; then
18973                         echo "lctl ping $(h2nettype $nid)"
18974                         lctl ping $(h2nettype $nid)
18975                 else
18976                         echo "skipping $node (no hyphen detected)"
18977                 fi
18978         done
18979 }
18980 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18981
18982 test_218() {
18983        # do directio so as not to populate the page cache
18984        log "creating a 10 Mb file"
18985        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18986        log "starting reads"
18987        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18988        log "truncating the file"
18989        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18990        log "killing dd"
18991        kill %+ || true # reads might have finished
18992        echo "wait until dd is finished"
18993        wait
18994        log "removing the temporary file"
18995        rm -rf $DIR/$tfile || error "tmp file removal failed"
18996 }
18997 run_test 218 "parallel read and truncate should not deadlock"
18998
18999 test_219() {
19000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19001
19002         # write one partial page
19003         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19004         # set no grant so vvp_io_commit_write will do sync write
19005         $LCTL set_param fail_loc=0x411
19006         # write a full page at the end of file
19007         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19008
19009         $LCTL set_param fail_loc=0
19010         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19011         $LCTL set_param fail_loc=0x411
19012         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19013
19014         # LU-4201
19015         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19016         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19017 }
19018 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19019
19020 test_220() { #LU-325
19021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19022         remote_ost_nodsh && skip "remote OST with nodsh"
19023         remote_mds_nodsh && skip "remote MDS with nodsh"
19024         remote_mgs_nodsh && skip "remote MGS with nodsh"
19025
19026         local OSTIDX=0
19027
19028         # create on MDT0000 so the last_id and next_id are correct
19029         mkdir_on_mdt0 $DIR/$tdir
19030         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19031         OST=${OST%_UUID}
19032
19033         # on the mdt's osc
19034         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19035         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19036                         osp.$mdtosc_proc1.prealloc_last_id)
19037         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19038                         osp.$mdtosc_proc1.prealloc_next_id)
19039
19040         $LFS df -i
19041
19042         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19043         #define OBD_FAIL_OST_ENOINO              0x229
19044         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19045         create_pool $FSNAME.$TESTNAME || return 1
19046         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19047
19048         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19049
19050         MDSOBJS=$((last_id - next_id))
19051         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19052
19053         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19054         echo "OST still has $count kbytes free"
19055
19056         echo "create $MDSOBJS files @next_id..."
19057         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19058
19059         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19060                         osp.$mdtosc_proc1.prealloc_last_id)
19061         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19062                         osp.$mdtosc_proc1.prealloc_next_id)
19063
19064         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19065         $LFS df -i
19066
19067         echo "cleanup..."
19068
19069         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19070         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19071
19072         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19073                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19074         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19075                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19076         echo "unlink $MDSOBJS files @$next_id..."
19077         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19078 }
19079 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19080
19081 test_221() {
19082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19083
19084         dd if=`which date` of=$MOUNT/date oflag=sync
19085         chmod +x $MOUNT/date
19086
19087         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19088         $LCTL set_param fail_loc=0x80001401
19089
19090         $MOUNT/date > /dev/null
19091         rm -f $MOUNT/date
19092 }
19093 run_test 221 "make sure fault and truncate race to not cause OOM"
19094
19095 test_222a () {
19096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19097
19098         rm -rf $DIR/$tdir
19099         test_mkdir $DIR/$tdir
19100         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19101         createmany -o $DIR/$tdir/$tfile 10
19102         cancel_lru_locks mdc
19103         cancel_lru_locks osc
19104         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19105         $LCTL set_param fail_loc=0x31a
19106         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19107         $LCTL set_param fail_loc=0
19108         rm -r $DIR/$tdir
19109 }
19110 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19111
19112 test_222b () {
19113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19114
19115         rm -rf $DIR/$tdir
19116         test_mkdir $DIR/$tdir
19117         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19118         createmany -o $DIR/$tdir/$tfile 10
19119         cancel_lru_locks mdc
19120         cancel_lru_locks osc
19121         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19122         $LCTL set_param fail_loc=0x31a
19123         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19124         $LCTL set_param fail_loc=0
19125 }
19126 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19127
19128 test_223 () {
19129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19130
19131         rm -rf $DIR/$tdir
19132         test_mkdir $DIR/$tdir
19133         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19134         createmany -o $DIR/$tdir/$tfile 10
19135         cancel_lru_locks mdc
19136         cancel_lru_locks osc
19137         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19138         $LCTL set_param fail_loc=0x31b
19139         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19140         $LCTL set_param fail_loc=0
19141         rm -r $DIR/$tdir
19142 }
19143 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19144
19145 test_224a() { # LU-1039, MRP-303
19146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19147         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19148         $LCTL set_param fail_loc=0x508
19149         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19150         $LCTL set_param fail_loc=0
19151         df $DIR
19152 }
19153 run_test 224a "Don't panic on bulk IO failure"
19154
19155 test_224bd_sub() { # LU-1039, MRP-303
19156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19157         local timeout=$1
19158
19159         shift
19160         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19161
19162         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19163
19164         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19165         cancel_lru_locks osc
19166         set_checksums 0
19167         stack_trap "set_checksums $ORIG_CSUM" EXIT
19168         local at_max_saved=0
19169
19170         # adaptive timeouts may prevent seeing the issue
19171         if at_is_enabled; then
19172                 at_max_saved=$(at_max_get mds)
19173                 at_max_set 0 mds client
19174                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19175         fi
19176
19177         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19178         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19179         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19180
19181         do_facet ost1 $LCTL set_param fail_loc=0
19182         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19183         df $DIR
19184 }
19185
19186 test_224b() {
19187         test_224bd_sub 3 error "dd failed"
19188 }
19189 run_test 224b "Don't panic on bulk IO failure"
19190
19191 test_224c() { # LU-6441
19192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19193         remote_mds_nodsh && skip "remote MDS with nodsh"
19194
19195         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19196         save_writethrough $p
19197         set_cache writethrough on
19198
19199         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19200         local at_max=$($LCTL get_param -n at_max)
19201         local timeout=$($LCTL get_param -n timeout)
19202         local test_at="at_max"
19203         local param_at="$FSNAME.sys.at_max"
19204         local test_timeout="timeout"
19205         local param_timeout="$FSNAME.sys.timeout"
19206
19207         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19208
19209         set_persistent_param_and_check client "$test_at" "$param_at" 0
19210         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19211
19212         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19213         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19214         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19215         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19216         sync
19217         do_facet ost1 "$LCTL set_param fail_loc=0"
19218
19219         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19220         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19221                 $timeout
19222
19223         $LCTL set_param -n $pages_per_rpc
19224         restore_lustre_params < $p
19225         rm -f $p
19226 }
19227 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19228
19229 test_224d() { # LU-11169
19230         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19231 }
19232 run_test 224d "Don't corrupt data on bulk IO timeout"
19233
19234 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19235 test_225a () {
19236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19237         if [ -z ${MDSSURVEY} ]; then
19238                 skip_env "mds-survey not found"
19239         fi
19240         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19241                 skip "Need MDS version at least 2.2.51"
19242
19243         local mds=$(facet_host $SINGLEMDS)
19244         local target=$(do_nodes $mds 'lctl dl' |
19245                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19246
19247         local cmd1="file_count=1000 thrhi=4"
19248         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19249         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19250         local cmd="$cmd1 $cmd2 $cmd3"
19251
19252         rm -f ${TMP}/mds_survey*
19253         echo + $cmd
19254         eval $cmd || error "mds-survey with zero-stripe failed"
19255         cat ${TMP}/mds_survey*
19256         rm -f ${TMP}/mds_survey*
19257 }
19258 run_test 225a "Metadata survey sanity with zero-stripe"
19259
19260 test_225b () {
19261         if [ -z ${MDSSURVEY} ]; then
19262                 skip_env "mds-survey not found"
19263         fi
19264         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19265                 skip "Need MDS version at least 2.2.51"
19266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19267         remote_mds_nodsh && skip "remote MDS with nodsh"
19268         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19269                 skip_env "Need to mount OST to test"
19270         fi
19271
19272         local mds=$(facet_host $SINGLEMDS)
19273         local target=$(do_nodes $mds 'lctl dl' |
19274                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19275
19276         local cmd1="file_count=1000 thrhi=4"
19277         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19278         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19279         local cmd="$cmd1 $cmd2 $cmd3"
19280
19281         rm -f ${TMP}/mds_survey*
19282         echo + $cmd
19283         eval $cmd || error "mds-survey with stripe_count failed"
19284         cat ${TMP}/mds_survey*
19285         rm -f ${TMP}/mds_survey*
19286 }
19287 run_test 225b "Metadata survey sanity with stripe_count = 1"
19288
19289 mcreate_path2fid () {
19290         local mode=$1
19291         local major=$2
19292         local minor=$3
19293         local name=$4
19294         local desc=$5
19295         local path=$DIR/$tdir/$name
19296         local fid
19297         local rc
19298         local fid_path
19299
19300         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19301                 error "cannot create $desc"
19302
19303         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19304         rc=$?
19305         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19306
19307         fid_path=$($LFS fid2path $MOUNT $fid)
19308         rc=$?
19309         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19310
19311         [ "$path" == "$fid_path" ] ||
19312                 error "fid2path returned $fid_path, expected $path"
19313
19314         echo "pass with $path and $fid"
19315 }
19316
19317 test_226a () {
19318         rm -rf $DIR/$tdir
19319         mkdir -p $DIR/$tdir
19320
19321         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19322         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19323         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19324         mcreate_path2fid 0040666 0 0 dir "directory"
19325         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19326         mcreate_path2fid 0100666 0 0 file "regular file"
19327         mcreate_path2fid 0120666 0 0 link "symbolic link"
19328         mcreate_path2fid 0140666 0 0 sock "socket"
19329 }
19330 run_test 226a "call path2fid and fid2path on files of all type"
19331
19332 test_226b () {
19333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19334
19335         local MDTIDX=1
19336
19337         rm -rf $DIR/$tdir
19338         mkdir -p $DIR/$tdir
19339         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19340                 error "create remote directory failed"
19341         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19342         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19343                                 "character special file (null)"
19344         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19345                                 "character special file (no device)"
19346         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19347         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19348                                 "block special file (loop)"
19349         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19350         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19351         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19352 }
19353 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19354
19355 test_226c () {
19356         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19357         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19358                 skip "Need MDS version at least 2.13.55"
19359
19360         local submnt=/mnt/submnt
19361         local srcfile=/etc/passwd
19362         local dstfile=$submnt/passwd
19363         local path
19364         local fid
19365
19366         rm -rf $DIR/$tdir
19367         rm -rf $submnt
19368         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19369                 error "create remote directory failed"
19370         mkdir -p $submnt || error "create $submnt failed"
19371         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19372                 error "mount $submnt failed"
19373         stack_trap "umount $submnt" EXIT
19374
19375         cp $srcfile $dstfile
19376         fid=$($LFS path2fid $dstfile)
19377         path=$($LFS fid2path $submnt "$fid")
19378         [ "$path" = "$dstfile" ] ||
19379                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19380 }
19381 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19382
19383 # LU-1299 Executing or running ldd on a truncated executable does not
19384 # cause an out-of-memory condition.
19385 test_227() {
19386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19387         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19388
19389         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19390         chmod +x $MOUNT/date
19391
19392         $MOUNT/date > /dev/null
19393         ldd $MOUNT/date > /dev/null
19394         rm -f $MOUNT/date
19395 }
19396 run_test 227 "running truncated executable does not cause OOM"
19397
19398 # LU-1512 try to reuse idle OI blocks
19399 test_228a() {
19400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19401         remote_mds_nodsh && skip "remote MDS with nodsh"
19402         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19403
19404         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19405         local myDIR=$DIR/$tdir
19406
19407         mkdir -p $myDIR
19408         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19409         $LCTL set_param fail_loc=0x80001002
19410         createmany -o $myDIR/t- 10000
19411         $LCTL set_param fail_loc=0
19412         # The guard is current the largest FID holder
19413         touch $myDIR/guard
19414         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19415                     tr -d '[')
19416         local IDX=$(($SEQ % 64))
19417
19418         do_facet $SINGLEMDS sync
19419         # Make sure journal flushed.
19420         sleep 6
19421         local blk1=$(do_facet $SINGLEMDS \
19422                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19423                      grep Blockcount | awk '{print $4}')
19424
19425         # Remove old files, some OI blocks will become idle.
19426         unlinkmany $myDIR/t- 10000
19427         # Create new files, idle OI blocks should be reused.
19428         createmany -o $myDIR/t- 2000
19429         do_facet $SINGLEMDS sync
19430         # Make sure journal flushed.
19431         sleep 6
19432         local blk2=$(do_facet $SINGLEMDS \
19433                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19434                      grep Blockcount | awk '{print $4}')
19435
19436         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19437 }
19438 run_test 228a "try to reuse idle OI blocks"
19439
19440 test_228b() {
19441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19442         remote_mds_nodsh && skip "remote MDS with nodsh"
19443         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19444
19445         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19446         local myDIR=$DIR/$tdir
19447
19448         mkdir -p $myDIR
19449         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19450         $LCTL set_param fail_loc=0x80001002
19451         createmany -o $myDIR/t- 10000
19452         $LCTL set_param fail_loc=0
19453         # The guard is current the largest FID holder
19454         touch $myDIR/guard
19455         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19456                     tr -d '[')
19457         local IDX=$(($SEQ % 64))
19458
19459         do_facet $SINGLEMDS sync
19460         # Make sure journal flushed.
19461         sleep 6
19462         local blk1=$(do_facet $SINGLEMDS \
19463                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19464                      grep Blockcount | awk '{print $4}')
19465
19466         # Remove old files, some OI blocks will become idle.
19467         unlinkmany $myDIR/t- 10000
19468
19469         # stop the MDT
19470         stop $SINGLEMDS || error "Fail to stop MDT."
19471         # remount the MDT
19472         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
19473
19474         df $MOUNT || error "Fail to df."
19475         # Create new files, idle OI blocks should be reused.
19476         createmany -o $myDIR/t- 2000
19477         do_facet $SINGLEMDS sync
19478         # Make sure journal flushed.
19479         sleep 6
19480         local blk2=$(do_facet $SINGLEMDS \
19481                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19482                      grep Blockcount | awk '{print $4}')
19483
19484         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19485 }
19486 run_test 228b "idle OI blocks can be reused after MDT restart"
19487
19488 #LU-1881
19489 test_228c() {
19490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19491         remote_mds_nodsh && skip "remote MDS with nodsh"
19492         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19493
19494         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19495         local myDIR=$DIR/$tdir
19496
19497         mkdir -p $myDIR
19498         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19499         $LCTL set_param fail_loc=0x80001002
19500         # 20000 files can guarantee there are index nodes in the OI file
19501         createmany -o $myDIR/t- 20000
19502         $LCTL set_param fail_loc=0
19503         # The guard is current the largest FID holder
19504         touch $myDIR/guard
19505         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19506                     tr -d '[')
19507         local IDX=$(($SEQ % 64))
19508
19509         do_facet $SINGLEMDS sync
19510         # Make sure journal flushed.
19511         sleep 6
19512         local blk1=$(do_facet $SINGLEMDS \
19513                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19514                      grep Blockcount | awk '{print $4}')
19515
19516         # Remove old files, some OI blocks will become idle.
19517         unlinkmany $myDIR/t- 20000
19518         rm -f $myDIR/guard
19519         # The OI file should become empty now
19520
19521         # Create new files, idle OI blocks should be reused.
19522         createmany -o $myDIR/t- 2000
19523         do_facet $SINGLEMDS sync
19524         # Make sure journal flushed.
19525         sleep 6
19526         local blk2=$(do_facet $SINGLEMDS \
19527                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19528                      grep Blockcount | awk '{print $4}')
19529
19530         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19531 }
19532 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19533
19534 test_229() { # LU-2482, LU-3448
19535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19536         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19537         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19538                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19539
19540         rm -f $DIR/$tfile
19541
19542         # Create a file with a released layout and stripe count 2.
19543         $MULTIOP $DIR/$tfile H2c ||
19544                 error "failed to create file with released layout"
19545
19546         $LFS getstripe -v $DIR/$tfile
19547
19548         local pattern=$($LFS getstripe -L $DIR/$tfile)
19549         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19550
19551         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19552                 error "getstripe"
19553         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19554         stat $DIR/$tfile || error "failed to stat released file"
19555
19556         chown $RUNAS_ID $DIR/$tfile ||
19557                 error "chown $RUNAS_ID $DIR/$tfile failed"
19558
19559         chgrp $RUNAS_ID $DIR/$tfile ||
19560                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19561
19562         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19563         rm $DIR/$tfile || error "failed to remove released file"
19564 }
19565 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19566
19567 test_230a() {
19568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19569         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19570         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19571                 skip "Need MDS version at least 2.11.52"
19572
19573         local MDTIDX=1
19574
19575         test_mkdir $DIR/$tdir
19576         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19577         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19578         [ $mdt_idx -ne 0 ] &&
19579                 error "create local directory on wrong MDT $mdt_idx"
19580
19581         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19582                         error "create remote directory failed"
19583         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19584         [ $mdt_idx -ne $MDTIDX ] &&
19585                 error "create remote directory on wrong MDT $mdt_idx"
19586
19587         createmany -o $DIR/$tdir/test_230/t- 10 ||
19588                 error "create files on remote directory failed"
19589         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19590         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19591         rm -r $DIR/$tdir || error "unlink remote directory failed"
19592 }
19593 run_test 230a "Create remote directory and files under the remote directory"
19594
19595 test_230b() {
19596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19597         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19598         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19599                 skip "Need MDS version at least 2.11.52"
19600
19601         local MDTIDX=1
19602         local mdt_index
19603         local i
19604         local file
19605         local pid
19606         local stripe_count
19607         local migrate_dir=$DIR/$tdir/migrate_dir
19608         local other_dir=$DIR/$tdir/other_dir
19609
19610         test_mkdir $DIR/$tdir
19611         test_mkdir -i0 -c1 $migrate_dir
19612         test_mkdir -i0 -c1 $other_dir
19613         for ((i=0; i<10; i++)); do
19614                 mkdir -p $migrate_dir/dir_${i}
19615                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19616                         error "create files under remote dir failed $i"
19617         done
19618
19619         cp /etc/passwd $migrate_dir/$tfile
19620         cp /etc/passwd $other_dir/$tfile
19621         chattr +SAD $migrate_dir
19622         chattr +SAD $migrate_dir/$tfile
19623
19624         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19625         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19626         local old_dir_mode=$(stat -c%f $migrate_dir)
19627         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19628
19629         mkdir -p $migrate_dir/dir_default_stripe2
19630         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19631         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19632
19633         mkdir -p $other_dir
19634         ln $migrate_dir/$tfile $other_dir/luna
19635         ln $migrate_dir/$tfile $migrate_dir/sofia
19636         ln $other_dir/$tfile $migrate_dir/david
19637         ln -s $migrate_dir/$tfile $other_dir/zachary
19638         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19639         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19640
19641         local len
19642         local lnktgt
19643
19644         # inline symlink
19645         for len in 58 59 60; do
19646                 lnktgt=$(str_repeat 'l' $len)
19647                 touch $migrate_dir/$lnktgt
19648                 ln -s $lnktgt $migrate_dir/${len}char_ln
19649         done
19650
19651         # PATH_MAX
19652         for len in 4094 4095; do
19653                 lnktgt=$(str_repeat 'l' $len)
19654                 ln -s $lnktgt $migrate_dir/${len}char_ln
19655         done
19656
19657         # NAME_MAX
19658         for len in 254 255; do
19659                 touch $migrate_dir/$(str_repeat 'l' $len)
19660         done
19661
19662         $LFS migrate -m $MDTIDX $migrate_dir ||
19663                 error "fails on migrating remote dir to MDT1"
19664
19665         echo "migratate to MDT1, then checking.."
19666         for ((i = 0; i < 10; i++)); do
19667                 for file in $(find $migrate_dir/dir_${i}); do
19668                         mdt_index=$($LFS getstripe -m $file)
19669                         # broken symlink getstripe will fail
19670                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19671                                 error "$file is not on MDT${MDTIDX}"
19672                 done
19673         done
19674
19675         # the multiple link file should still in MDT0
19676         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19677         [ $mdt_index == 0 ] ||
19678                 error "$file is not on MDT${MDTIDX}"
19679
19680         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19681         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19682                 error " expect $old_dir_flag get $new_dir_flag"
19683
19684         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19685         [ "$old_file_flag" = "$new_file_flag" ] ||
19686                 error " expect $old_file_flag get $new_file_flag"
19687
19688         local new_dir_mode=$(stat -c%f $migrate_dir)
19689         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19690                 error "expect mode $old_dir_mode get $new_dir_mode"
19691
19692         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19693         [ "$old_file_mode" = "$new_file_mode" ] ||
19694                 error "expect mode $old_file_mode get $new_file_mode"
19695
19696         diff /etc/passwd $migrate_dir/$tfile ||
19697                 error "$tfile different after migration"
19698
19699         diff /etc/passwd $other_dir/luna ||
19700                 error "luna different after migration"
19701
19702         diff /etc/passwd $migrate_dir/sofia ||
19703                 error "sofia different after migration"
19704
19705         diff /etc/passwd $migrate_dir/david ||
19706                 error "david different after migration"
19707
19708         diff /etc/passwd $other_dir/zachary ||
19709                 error "zachary different after migration"
19710
19711         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19712                 error "${tfile}_ln different after migration"
19713
19714         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19715                 error "${tfile}_ln_other different after migration"
19716
19717         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19718         [ $stripe_count = 2 ] ||
19719                 error "dir strpe_count $d != 2 after migration."
19720
19721         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19722         [ $stripe_count = 2 ] ||
19723                 error "file strpe_count $d != 2 after migration."
19724
19725         #migrate back to MDT0
19726         MDTIDX=0
19727
19728         $LFS migrate -m $MDTIDX $migrate_dir ||
19729                 error "fails on migrating remote dir to MDT0"
19730
19731         echo "migrate back to MDT0, checking.."
19732         for file in $(find $migrate_dir); do
19733                 mdt_index=$($LFS getstripe -m $file)
19734                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19735                         error "$file is not on MDT${MDTIDX}"
19736         done
19737
19738         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19739         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19740                 error " expect $old_dir_flag get $new_dir_flag"
19741
19742         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19743         [ "$old_file_flag" = "$new_file_flag" ] ||
19744                 error " expect $old_file_flag get $new_file_flag"
19745
19746         local new_dir_mode=$(stat -c%f $migrate_dir)
19747         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19748                 error "expect mode $old_dir_mode get $new_dir_mode"
19749
19750         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19751         [ "$old_file_mode" = "$new_file_mode" ] ||
19752                 error "expect mode $old_file_mode get $new_file_mode"
19753
19754         diff /etc/passwd ${migrate_dir}/$tfile ||
19755                 error "$tfile different after migration"
19756
19757         diff /etc/passwd ${other_dir}/luna ||
19758                 error "luna different after migration"
19759
19760         diff /etc/passwd ${migrate_dir}/sofia ||
19761                 error "sofia different after migration"
19762
19763         diff /etc/passwd ${other_dir}/zachary ||
19764                 error "zachary different after migration"
19765
19766         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19767                 error "${tfile}_ln different after migration"
19768
19769         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19770                 error "${tfile}_ln_other different after migration"
19771
19772         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19773         [ $stripe_count = 2 ] ||
19774                 error "dir strpe_count $d != 2 after migration."
19775
19776         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19777         [ $stripe_count = 2 ] ||
19778                 error "file strpe_count $d != 2 after migration."
19779
19780         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19781 }
19782 run_test 230b "migrate directory"
19783
19784 test_230c() {
19785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19786         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19787         remote_mds_nodsh && skip "remote MDS with nodsh"
19788         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19789                 skip "Need MDS version at least 2.11.52"
19790
19791         local MDTIDX=1
19792         local total=3
19793         local mdt_index
19794         local file
19795         local migrate_dir=$DIR/$tdir/migrate_dir
19796
19797         #If migrating directory fails in the middle, all entries of
19798         #the directory is still accessiable.
19799         test_mkdir $DIR/$tdir
19800         test_mkdir -i0 -c1 $migrate_dir
19801         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19802         stat $migrate_dir
19803         createmany -o $migrate_dir/f $total ||
19804                 error "create files under ${migrate_dir} failed"
19805
19806         # fail after migrating top dir, and this will fail only once, so the
19807         # first sub file migration will fail (currently f3), others succeed.
19808         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19809         do_facet mds1 lctl set_param fail_loc=0x1801
19810         local t=$(ls $migrate_dir | wc -l)
19811         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19812                 error "migrate should fail"
19813         local u=$(ls $migrate_dir | wc -l)
19814         [ "$u" == "$t" ] || error "$u != $t during migration"
19815
19816         # add new dir/file should succeed
19817         mkdir $migrate_dir/dir ||
19818                 error "mkdir failed under migrating directory"
19819         touch $migrate_dir/file ||
19820                 error "create file failed under migrating directory"
19821
19822         # add file with existing name should fail
19823         for file in $migrate_dir/f*; do
19824                 stat $file > /dev/null || error "stat $file failed"
19825                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19826                         error "open(O_CREAT|O_EXCL) $file should fail"
19827                 $MULTIOP $file m && error "create $file should fail"
19828                 touch $DIR/$tdir/remote_dir/$tfile ||
19829                         error "touch $tfile failed"
19830                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19831                         error "link $file should fail"
19832                 mdt_index=$($LFS getstripe -m $file)
19833                 if [ $mdt_index == 0 ]; then
19834                         # file failed to migrate is not allowed to rename to
19835                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19836                                 error "rename to $file should fail"
19837                 else
19838                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19839                                 error "rename to $file failed"
19840                 fi
19841                 echo hello >> $file || error "write $file failed"
19842         done
19843
19844         # resume migration with different options should fail
19845         $LFS migrate -m 0 $migrate_dir &&
19846                 error "migrate -m 0 $migrate_dir should fail"
19847
19848         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19849                 error "migrate -c 2 $migrate_dir should fail"
19850
19851         # resume migration should succeed
19852         $LFS migrate -m $MDTIDX $migrate_dir ||
19853                 error "migrate $migrate_dir failed"
19854
19855         echo "Finish migration, then checking.."
19856         for file in $(find $migrate_dir); do
19857                 mdt_index=$($LFS getstripe -m $file)
19858                 [ $mdt_index == $MDTIDX ] ||
19859                         error "$file is not on MDT${MDTIDX}"
19860         done
19861
19862         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19863 }
19864 run_test 230c "check directory accessiblity if migration failed"
19865
19866 test_230d() {
19867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19868         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19869         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19870                 skip "Need MDS version at least 2.11.52"
19871         # LU-11235
19872         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19873
19874         local migrate_dir=$DIR/$tdir/migrate_dir
19875         local old_index
19876         local new_index
19877         local old_count
19878         local new_count
19879         local new_hash
19880         local mdt_index
19881         local i
19882         local j
19883
19884         old_index=$((RANDOM % MDSCOUNT))
19885         old_count=$((MDSCOUNT - old_index))
19886         new_index=$((RANDOM % MDSCOUNT))
19887         new_count=$((MDSCOUNT - new_index))
19888         new_hash=1 # for all_char
19889
19890         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19891         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19892
19893         test_mkdir $DIR/$tdir
19894         test_mkdir -i $old_index -c $old_count $migrate_dir
19895
19896         for ((i=0; i<100; i++)); do
19897                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19898                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19899                         error "create files under remote dir failed $i"
19900         done
19901
19902         echo -n "Migrate from MDT$old_index "
19903         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19904         echo -n "to MDT$new_index"
19905         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19906         echo
19907
19908         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19909         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19910                 error "migrate remote dir error"
19911
19912         echo "Finish migration, then checking.."
19913         for file in $(find $migrate_dir -maxdepth 1); do
19914                 mdt_index=$($LFS getstripe -m $file)
19915                 if [ $mdt_index -lt $new_index ] ||
19916                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19917                         error "$file is on MDT$mdt_index"
19918                 fi
19919         done
19920
19921         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19922 }
19923 run_test 230d "check migrate big directory"
19924
19925 test_230e() {
19926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19927         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19928         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19929                 skip "Need MDS version at least 2.11.52"
19930
19931         local i
19932         local j
19933         local a_fid
19934         local b_fid
19935
19936         mkdir_on_mdt0 $DIR/$tdir
19937         mkdir $DIR/$tdir/migrate_dir
19938         mkdir $DIR/$tdir/other_dir
19939         touch $DIR/$tdir/migrate_dir/a
19940         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19941         ls $DIR/$tdir/other_dir
19942
19943         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19944                 error "migrate dir fails"
19945
19946         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19947         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19948
19949         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19950         [ $mdt_index == 0 ] || error "a is not on MDT0"
19951
19952         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19953                 error "migrate dir fails"
19954
19955         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19956         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19957
19958         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19959         [ $mdt_index == 1 ] || error "a is not on MDT1"
19960
19961         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19962         [ $mdt_index == 1 ] || error "b is not on MDT1"
19963
19964         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19965         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19966
19967         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19968
19969         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19970 }
19971 run_test 230e "migrate mulitple local link files"
19972
19973 test_230f() {
19974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19975         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19976         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19977                 skip "Need MDS version at least 2.11.52"
19978
19979         local a_fid
19980         local ln_fid
19981
19982         mkdir -p $DIR/$tdir
19983         mkdir $DIR/$tdir/migrate_dir
19984         $LFS mkdir -i1 $DIR/$tdir/other_dir
19985         touch $DIR/$tdir/migrate_dir/a
19986         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19987         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19988         ls $DIR/$tdir/other_dir
19989
19990         # a should be migrated to MDT1, since no other links on MDT0
19991         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19992                 error "#1 migrate dir fails"
19993         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19994         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19995         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19996         [ $mdt_index == 1 ] || error "a is not on MDT1"
19997
19998         # a should stay on MDT1, because it is a mulitple link file
19999         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20000                 error "#2 migrate dir fails"
20001         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20002         [ $mdt_index == 1 ] || error "a is not on MDT1"
20003
20004         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20005                 error "#3 migrate dir fails"
20006
20007         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20008         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20009         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20010
20011         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20012         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20013
20014         # a should be migrated to MDT0, since no other links on MDT1
20015         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20016                 error "#4 migrate dir fails"
20017         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20018         [ $mdt_index == 0 ] || error "a is not on MDT0"
20019
20020         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20021 }
20022 run_test 230f "migrate mulitple remote link files"
20023
20024 test_230g() {
20025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20026         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20027         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20028                 skip "Need MDS version at least 2.11.52"
20029
20030         mkdir -p $DIR/$tdir/migrate_dir
20031
20032         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20033                 error "migrating dir to non-exist MDT succeeds"
20034         true
20035 }
20036 run_test 230g "migrate dir to non-exist MDT"
20037
20038 test_230h() {
20039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20040         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20041         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20042                 skip "Need MDS version at least 2.11.52"
20043
20044         local mdt_index
20045
20046         mkdir -p $DIR/$tdir/migrate_dir
20047
20048         $LFS migrate -m1 $DIR &&
20049                 error "migrating mountpoint1 should fail"
20050
20051         $LFS migrate -m1 $DIR/$tdir/.. &&
20052                 error "migrating mountpoint2 should fail"
20053
20054         # same as mv
20055         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20056                 error "migrating $tdir/migrate_dir/.. should fail"
20057
20058         true
20059 }
20060 run_test 230h "migrate .. and root"
20061
20062 test_230i() {
20063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20064         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20065         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20066                 skip "Need MDS version at least 2.11.52"
20067
20068         mkdir -p $DIR/$tdir/migrate_dir
20069
20070         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20071                 error "migration fails with a tailing slash"
20072
20073         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20074                 error "migration fails with two tailing slashes"
20075 }
20076 run_test 230i "lfs migrate -m tolerates trailing slashes"
20077
20078 test_230j() {
20079         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20080         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20081                 skip "Need MDS version at least 2.11.52"
20082
20083         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20084         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20085                 error "create $tfile failed"
20086         cat /etc/passwd > $DIR/$tdir/$tfile
20087
20088         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20089
20090         cmp /etc/passwd $DIR/$tdir/$tfile ||
20091                 error "DoM file mismatch after migration"
20092 }
20093 run_test 230j "DoM file data not changed after dir migration"
20094
20095 test_230k() {
20096         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20097         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20098                 skip "Need MDS version at least 2.11.56"
20099
20100         local total=20
20101         local files_on_starting_mdt=0
20102
20103         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20104         $LFS getdirstripe $DIR/$tdir
20105         for i in $(seq $total); do
20106                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20107                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20108                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20109         done
20110
20111         echo "$files_on_starting_mdt files on MDT0"
20112
20113         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20114         $LFS getdirstripe $DIR/$tdir
20115
20116         files_on_starting_mdt=0
20117         for i in $(seq $total); do
20118                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20119                         error "file $tfile.$i mismatch after migration"
20120                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20121                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20122         done
20123
20124         echo "$files_on_starting_mdt files on MDT1 after migration"
20125         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20126
20127         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20128         $LFS getdirstripe $DIR/$tdir
20129
20130         files_on_starting_mdt=0
20131         for i in $(seq $total); do
20132                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20133                         error "file $tfile.$i mismatch after 2nd migration"
20134                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20135                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20136         done
20137
20138         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20139         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20140
20141         true
20142 }
20143 run_test 230k "file data not changed after dir migration"
20144
20145 test_230l() {
20146         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20147         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20148                 skip "Need MDS version at least 2.11.56"
20149
20150         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20151         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20152                 error "create files under remote dir failed $i"
20153         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20154 }
20155 run_test 230l "readdir between MDTs won't crash"
20156
20157 test_230m() {
20158         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20159         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20160                 skip "Need MDS version at least 2.11.56"
20161
20162         local MDTIDX=1
20163         local mig_dir=$DIR/$tdir/migrate_dir
20164         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20165         local shortstr="b"
20166         local val
20167
20168         echo "Creating files and dirs with xattrs"
20169         test_mkdir $DIR/$tdir
20170         test_mkdir -i0 -c1 $mig_dir
20171         mkdir $mig_dir/dir
20172         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20173                 error "cannot set xattr attr1 on dir"
20174         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20175                 error "cannot set xattr attr2 on dir"
20176         touch $mig_dir/dir/f0
20177         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20178                 error "cannot set xattr attr1 on file"
20179         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20180                 error "cannot set xattr attr2 on file"
20181         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20182         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20183         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20184         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20185         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20186         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20187         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20188         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20189         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20190
20191         echo "Migrating to MDT1"
20192         $LFS migrate -m $MDTIDX $mig_dir ||
20193                 error "fails on migrating dir to MDT1"
20194
20195         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20196         echo "Checking xattrs"
20197         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20198         [ "$val" = $longstr ] ||
20199                 error "expecting xattr1 $longstr on dir, found $val"
20200         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20201         [ "$val" = $shortstr ] ||
20202                 error "expecting xattr2 $shortstr on dir, found $val"
20203         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20204         [ "$val" = $longstr ] ||
20205                 error "expecting xattr1 $longstr on file, found $val"
20206         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20207         [ "$val" = $shortstr ] ||
20208                 error "expecting xattr2 $shortstr on file, found $val"
20209 }
20210 run_test 230m "xattrs not changed after dir migration"
20211
20212 test_230n() {
20213         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20214         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20215                 skip "Need MDS version at least 2.13.53"
20216
20217         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20218         cat /etc/hosts > $DIR/$tdir/$tfile
20219         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20220         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20221
20222         cmp /etc/hosts $DIR/$tdir/$tfile ||
20223                 error "File data mismatch after migration"
20224 }
20225 run_test 230n "Dir migration with mirrored file"
20226
20227 test_230o() {
20228         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20229         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20230                 skip "Need MDS version at least 2.13.52"
20231
20232         local mdts=$(comma_list $(mdts_nodes))
20233         local timeout=100
20234         local restripe_status
20235         local delta
20236         local i
20237
20238         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20239
20240         # in case "crush" hash type is not set
20241         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20242
20243         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20244                            mdt.*MDT0000.enable_dir_restripe)
20245         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20246         stack_trap "do_nodes $mdts $LCTL set_param \
20247                     mdt.*.enable_dir_restripe=$restripe_status"
20248
20249         mkdir $DIR/$tdir
20250         createmany -m $DIR/$tdir/f 100 ||
20251                 error "create files under remote dir failed $i"
20252         createmany -d $DIR/$tdir/d 100 ||
20253                 error "create dirs under remote dir failed $i"
20254
20255         for i in $(seq 2 $MDSCOUNT); do
20256                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20257                 $LFS setdirstripe -c $i $DIR/$tdir ||
20258                         error "split -c $i $tdir failed"
20259                 wait_update $HOSTNAME \
20260                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20261                         error "dir split not finished"
20262                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20263                         awk '/migrate/ {sum += $2} END { print sum }')
20264                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20265                 # delta is around total_files/stripe_count
20266                 (( $delta < 200 / (i - 1) + 4 )) ||
20267                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20268         done
20269 }
20270 run_test 230o "dir split"
20271
20272 test_230p() {
20273         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20274         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20275                 skip "Need MDS version at least 2.13.52"
20276
20277         local mdts=$(comma_list $(mdts_nodes))
20278         local timeout=100
20279         local restripe_status
20280         local delta
20281         local c
20282
20283         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20284
20285         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20286
20287         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20288                            mdt.*MDT0000.enable_dir_restripe)
20289         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20290         stack_trap "do_nodes $mdts $LCTL set_param \
20291                     mdt.*.enable_dir_restripe=$restripe_status"
20292
20293         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20294         createmany -m $DIR/$tdir/f 100 ||
20295                 error "create files under remote dir failed"
20296         createmany -d $DIR/$tdir/d 100 ||
20297                 error "create dirs under remote dir failed"
20298
20299         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20300                 local mdt_hash="crush"
20301
20302                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20303                 $LFS setdirstripe -c $c $DIR/$tdir ||
20304                         error "split -c $c $tdir failed"
20305                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20306                         mdt_hash="$mdt_hash,fixed"
20307                 elif [ $c -eq 1 ]; then
20308                         mdt_hash="none"
20309                 fi
20310                 wait_update $HOSTNAME \
20311                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20312                         error "dir merge not finished"
20313                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20314                         awk '/migrate/ {sum += $2} END { print sum }')
20315                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20316                 # delta is around total_files/stripe_count
20317                 (( delta < 200 / c + 4 )) ||
20318                         error "$delta files migrated >= $((200 / c + 4))"
20319         done
20320 }
20321 run_test 230p "dir merge"
20322
20323 test_230q() {
20324         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20325         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20326                 skip "Need MDS version at least 2.13.52"
20327
20328         local mdts=$(comma_list $(mdts_nodes))
20329         local saved_threshold=$(do_facet mds1 \
20330                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20331         local saved_delta=$(do_facet mds1 \
20332                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20333         local threshold=100
20334         local delta=2
20335         local total=0
20336         local stripe_count=0
20337         local stripe_index
20338         local nr_files
20339         local create
20340
20341         # test with fewer files on ZFS
20342         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20343
20344         stack_trap "do_nodes $mdts $LCTL set_param \
20345                     mdt.*.dir_split_count=$saved_threshold"
20346         stack_trap "do_nodes $mdts $LCTL set_param \
20347                     mdt.*.dir_split_delta=$saved_delta"
20348         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20349         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20350         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20351         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20352         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20353         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20354
20355         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20356         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20357
20358         create=$((threshold * 3 / 2))
20359         while [ $stripe_count -lt $MDSCOUNT ]; do
20360                 createmany -m $DIR/$tdir/f $total $create ||
20361                         error "create sub files failed"
20362                 stat $DIR/$tdir > /dev/null
20363                 total=$((total + create))
20364                 stripe_count=$((stripe_count + delta))
20365                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20366
20367                 wait_update $HOSTNAME \
20368                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20369                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20370
20371                 wait_update $HOSTNAME \
20372                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20373                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20374
20375                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20376                 echo "$nr_files/$total files on MDT$stripe_index after split"
20377                 # allow 10% margin of imbalance with crush hash
20378                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20379                         error "$nr_files files on MDT$stripe_index after split"
20380
20381                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20382                 [ $nr_files -eq $total ] ||
20383                         error "total sub files $nr_files != $total"
20384         done
20385
20386         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20387
20388         echo "fixed layout directory won't auto split"
20389         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20390         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20391                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20392         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20393                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20394 }
20395 run_test 230q "dir auto split"
20396
20397 test_230r() {
20398         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20399         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20400         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20401                 skip "Need MDS version at least 2.13.54"
20402
20403         # maximum amount of local locks:
20404         # parent striped dir - 2 locks
20405         # new stripe in parent to migrate to - 1 lock
20406         # source and target - 2 locks
20407         # Total 5 locks for regular file
20408         mkdir -p $DIR/$tdir
20409         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20410         touch $DIR/$tdir/dir1/eee
20411
20412         # create 4 hardlink for 4 more locks
20413         # Total: 9 locks > RS_MAX_LOCKS (8)
20414         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20415         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20416         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20417         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20418         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20419         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20420         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20421         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20422
20423         cancel_lru_locks mdc
20424
20425         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20426                 error "migrate dir fails"
20427
20428         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20429 }
20430 run_test 230r "migrate with too many local locks"
20431
20432 test_230s() {
20433         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
20434                 skip "Need MDS version at least 2.13.57"
20435
20436         local mdts=$(comma_list $(mdts_nodes))
20437         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20438                                 mdt.*MDT0000.enable_dir_restripe)
20439
20440         stack_trap "do_nodes $mdts $LCTL set_param \
20441                     mdt.*.enable_dir_restripe=$restripe_status"
20442
20443         local st
20444         for st in 0 1; do
20445                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20446                 test_mkdir $DIR/$tdir
20447                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20448                         error "$LFS mkdir doesn't return -EEXIST if target exists"
20449                 rmdir $DIR/$tdir
20450         done
20451 }
20452 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20453
20454 test_230t()
20455 {
20456         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20457         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20458                 skip "Need MDS version at least 2.14.50"
20459
20460         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20461         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20462         $LFS project -p 1 -s $DIR/$tdir ||
20463                 error "set $tdir project id failed"
20464         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20465                 error "set subdir project id failed"
20466         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20467 }
20468 run_test 230t "migrate directory with project ID set"
20469
20470 test_230u()
20471 {
20472         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20473         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20474                 skip "Need MDS version at least 2.14.53"
20475
20476         local count
20477
20478         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20479         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20480         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20481         for i in $(seq 0 $((MDSCOUNT - 1))); do
20482                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20483                 echo "$count dirs migrated to MDT$i"
20484         done
20485         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20486         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20487 }
20488 run_test 230u "migrate directory by QOS"
20489
20490 test_230v()
20491 {
20492         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20493         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20494                 skip "Need MDS version at least 2.14.53"
20495
20496         local count
20497
20498         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20499         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20500         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20501         for i in $(seq 0 $((MDSCOUNT - 1))); do
20502                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20503                 echo "$count subdirs migrated to MDT$i"
20504                 (( i == 3 )) && (( count > 0 )) &&
20505                         error "subdir shouldn't be migrated to MDT3"
20506         done
20507         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20508         (( count == 3 )) || error "dirs migrated to $count MDTs"
20509 }
20510 run_test 230v "subdir migrated to the MDT where its parent is located"
20511
20512 test_230w() {
20513         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20514         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20515                 skip "Need MDS version at least 2.14.53"
20516
20517         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20518
20519         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20520                 error "migrate failed"
20521
20522         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20523                 error "$tdir stripe count mismatch"
20524
20525         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20526                 error "$tdir/sub is striped"
20527 }
20528 run_test 230w "non-recursive mode dir migration"
20529
20530 test_231a()
20531 {
20532         # For simplicity this test assumes that max_pages_per_rpc
20533         # is the same across all OSCs
20534         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20535         local bulk_size=$((max_pages * PAGE_SIZE))
20536         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20537                                        head -n 1)
20538
20539         mkdir -p $DIR/$tdir
20540         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20541                 error "failed to set stripe with -S ${brw_size}M option"
20542
20543         # clear the OSC stats
20544         $LCTL set_param osc.*.stats=0 &>/dev/null
20545         stop_writeback
20546
20547         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20548         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20549                 oflag=direct &>/dev/null || error "dd failed"
20550
20551         sync; sleep 1; sync # just to be safe
20552         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20553         if [ x$nrpcs != "x1" ]; then
20554                 $LCTL get_param osc.*.stats
20555                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20556         fi
20557
20558         start_writeback
20559         # Drop the OSC cache, otherwise we will read from it
20560         cancel_lru_locks osc
20561
20562         # clear the OSC stats
20563         $LCTL set_param osc.*.stats=0 &>/dev/null
20564
20565         # Client reads $bulk_size.
20566         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20567                 iflag=direct &>/dev/null || error "dd failed"
20568
20569         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20570         if [ x$nrpcs != "x1" ]; then
20571                 $LCTL get_param osc.*.stats
20572                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20573         fi
20574 }
20575 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20576
20577 test_231b() {
20578         mkdir -p $DIR/$tdir
20579         local i
20580         for i in {0..1023}; do
20581                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20582                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20583                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20584         done
20585         sync
20586 }
20587 run_test 231b "must not assert on fully utilized OST request buffer"
20588
20589 test_232a() {
20590         mkdir -p $DIR/$tdir
20591         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20592
20593         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20594         do_facet ost1 $LCTL set_param fail_loc=0x31c
20595
20596         # ignore dd failure
20597         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20598
20599         do_facet ost1 $LCTL set_param fail_loc=0
20600         umount_client $MOUNT || error "umount failed"
20601         mount_client $MOUNT || error "mount failed"
20602         stop ost1 || error "cannot stop ost1"
20603         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20604 }
20605 run_test 232a "failed lock should not block umount"
20606
20607 test_232b() {
20608         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20609                 skip "Need MDS version at least 2.10.58"
20610
20611         mkdir -p $DIR/$tdir
20612         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20613         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20614         sync
20615         cancel_lru_locks osc
20616
20617         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20618         do_facet ost1 $LCTL set_param fail_loc=0x31c
20619
20620         # ignore failure
20621         $LFS data_version $DIR/$tdir/$tfile || true
20622
20623         do_facet ost1 $LCTL set_param fail_loc=0
20624         umount_client $MOUNT || error "umount failed"
20625         mount_client $MOUNT || error "mount failed"
20626         stop ost1 || error "cannot stop ost1"
20627         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20628 }
20629 run_test 232b "failed data version lock should not block umount"
20630
20631 test_233a() {
20632         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20633                 skip "Need MDS version at least 2.3.64"
20634         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20635
20636         local fid=$($LFS path2fid $MOUNT)
20637
20638         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20639                 error "cannot access $MOUNT using its FID '$fid'"
20640 }
20641 run_test 233a "checking that OBF of the FS root succeeds"
20642
20643 test_233b() {
20644         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20645                 skip "Need MDS version at least 2.5.90"
20646         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20647
20648         local fid=$($LFS path2fid $MOUNT/.lustre)
20649
20650         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20651                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20652
20653         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20654         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20655                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20656 }
20657 run_test 233b "checking that OBF of the FS .lustre succeeds"
20658
20659 test_234() {
20660         local p="$TMP/sanityN-$TESTNAME.parameters"
20661         save_lustre_params client "llite.*.xattr_cache" > $p
20662         lctl set_param llite.*.xattr_cache 1 ||
20663                 skip_env "xattr cache is not supported"
20664
20665         mkdir -p $DIR/$tdir || error "mkdir failed"
20666         touch $DIR/$tdir/$tfile || error "touch failed"
20667         # OBD_FAIL_LLITE_XATTR_ENOMEM
20668         $LCTL set_param fail_loc=0x1405
20669         getfattr -n user.attr $DIR/$tdir/$tfile &&
20670                 error "getfattr should have failed with ENOMEM"
20671         $LCTL set_param fail_loc=0x0
20672         rm -rf $DIR/$tdir
20673
20674         restore_lustre_params < $p
20675         rm -f $p
20676 }
20677 run_test 234 "xattr cache should not crash on ENOMEM"
20678
20679 test_235() {
20680         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20681                 skip "Need MDS version at least 2.4.52"
20682
20683         flock_deadlock $DIR/$tfile
20684         local RC=$?
20685         case $RC in
20686                 0)
20687                 ;;
20688                 124) error "process hangs on a deadlock"
20689                 ;;
20690                 *) error "error executing flock_deadlock $DIR/$tfile"
20691                 ;;
20692         esac
20693 }
20694 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20695
20696 #LU-2935
20697 test_236() {
20698         check_swap_layouts_support
20699
20700         local ref1=/etc/passwd
20701         local ref2=/etc/group
20702         local file1=$DIR/$tdir/f1
20703         local file2=$DIR/$tdir/f2
20704
20705         test_mkdir -c1 $DIR/$tdir
20706         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20707         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20708         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20709         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20710         local fd=$(free_fd)
20711         local cmd="exec $fd<>$file2"
20712         eval $cmd
20713         rm $file2
20714         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20715                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20716         cmd="exec $fd>&-"
20717         eval $cmd
20718         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20719
20720         #cleanup
20721         rm -rf $DIR/$tdir
20722 }
20723 run_test 236 "Layout swap on open unlinked file"
20724
20725 # LU-4659 linkea consistency
20726 test_238() {
20727         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20728                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20729                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20730                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20731
20732         touch $DIR/$tfile
20733         ln $DIR/$tfile $DIR/$tfile.lnk
20734         touch $DIR/$tfile.new
20735         mv $DIR/$tfile.new $DIR/$tfile
20736         local fid1=$($LFS path2fid $DIR/$tfile)
20737         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20738         local path1=$($LFS fid2path $FSNAME "$fid1")
20739         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20740         local path2=$($LFS fid2path $FSNAME "$fid2")
20741         [ $tfile.lnk == $path2 ] ||
20742                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20743         rm -f $DIR/$tfile*
20744 }
20745 run_test 238 "Verify linkea consistency"
20746
20747 test_239A() { # was test_239
20748         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20749                 skip "Need MDS version at least 2.5.60"
20750
20751         local list=$(comma_list $(mdts_nodes))
20752
20753         mkdir -p $DIR/$tdir
20754         createmany -o $DIR/$tdir/f- 5000
20755         unlinkmany $DIR/$tdir/f- 5000
20756         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20757                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20758         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20759                         osp.*MDT*.sync_in_flight" | calc_sum)
20760         [ "$changes" -eq 0 ] || error "$changes not synced"
20761 }
20762 run_test 239A "osp_sync test"
20763
20764 test_239a() { #LU-5297
20765         remote_mds_nodsh && skip "remote MDS with nodsh"
20766
20767         touch $DIR/$tfile
20768         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20769         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20770         chgrp $RUNAS_GID $DIR/$tfile
20771         wait_delete_completed
20772 }
20773 run_test 239a "process invalid osp sync record correctly"
20774
20775 test_239b() { #LU-5297
20776         remote_mds_nodsh && skip "remote MDS with nodsh"
20777
20778         touch $DIR/$tfile1
20779         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20780         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20781         chgrp $RUNAS_GID $DIR/$tfile1
20782         wait_delete_completed
20783         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20784         touch $DIR/$tfile2
20785         chgrp $RUNAS_GID $DIR/$tfile2
20786         wait_delete_completed
20787 }
20788 run_test 239b "process osp sync record with ENOMEM error correctly"
20789
20790 test_240() {
20791         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20792         remote_mds_nodsh && skip "remote MDS with nodsh"
20793
20794         mkdir -p $DIR/$tdir
20795
20796         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20797                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20798         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20799                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20800
20801         umount_client $MOUNT || error "umount failed"
20802         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20803         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20804         mount_client $MOUNT || error "failed to mount client"
20805
20806         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20807         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20808 }
20809 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20810
20811 test_241_bio() {
20812         local count=$1
20813         local bsize=$2
20814
20815         for LOOP in $(seq $count); do
20816                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20817                 cancel_lru_locks $OSC || true
20818         done
20819 }
20820
20821 test_241_dio() {
20822         local count=$1
20823         local bsize=$2
20824
20825         for LOOP in $(seq $1); do
20826                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20827                         2>/dev/null
20828         done
20829 }
20830
20831 test_241a() { # was test_241
20832         local bsize=$PAGE_SIZE
20833
20834         (( bsize < 40960 )) && bsize=40960
20835         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20836         ls -la $DIR/$tfile
20837         cancel_lru_locks $OSC
20838         test_241_bio 1000 $bsize &
20839         PID=$!
20840         test_241_dio 1000 $bsize
20841         wait $PID
20842 }
20843 run_test 241a "bio vs dio"
20844
20845 test_241b() {
20846         local bsize=$PAGE_SIZE
20847
20848         (( bsize < 40960 )) && bsize=40960
20849         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20850         ls -la $DIR/$tfile
20851         test_241_dio 1000 $bsize &
20852         PID=$!
20853         test_241_dio 1000 $bsize
20854         wait $PID
20855 }
20856 run_test 241b "dio vs dio"
20857
20858 test_242() {
20859         remote_mds_nodsh && skip "remote MDS with nodsh"
20860
20861         mkdir_on_mdt0 $DIR/$tdir
20862         touch $DIR/$tdir/$tfile
20863
20864         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20865         do_facet mds1 lctl set_param fail_loc=0x105
20866         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20867
20868         do_facet mds1 lctl set_param fail_loc=0
20869         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20870 }
20871 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20872
20873 test_243()
20874 {
20875         test_mkdir $DIR/$tdir
20876         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20877 }
20878 run_test 243 "various group lock tests"
20879
20880 test_244a()
20881 {
20882         test_mkdir $DIR/$tdir
20883         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20884         sendfile_grouplock $DIR/$tdir/$tfile || \
20885                 error "sendfile+grouplock failed"
20886         rm -rf $DIR/$tdir
20887 }
20888 run_test 244a "sendfile with group lock tests"
20889
20890 test_244b()
20891 {
20892         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20893
20894         local threads=50
20895         local size=$((1024*1024))
20896
20897         test_mkdir $DIR/$tdir
20898         for i in $(seq 1 $threads); do
20899                 local file=$DIR/$tdir/file_$((i / 10))
20900                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20901                 local pids[$i]=$!
20902         done
20903         for i in $(seq 1 $threads); do
20904                 wait ${pids[$i]}
20905         done
20906 }
20907 run_test 244b "multi-threaded write with group lock"
20908
20909 test_245() {
20910         local flagname="multi_mod_rpcs"
20911         local connect_data_name="max_mod_rpcs"
20912         local out
20913
20914         # check if multiple modify RPCs flag is set
20915         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20916                 grep "connect_flags:")
20917         echo "$out"
20918
20919         echo "$out" | grep -qw $flagname
20920         if [ $? -ne 0 ]; then
20921                 echo "connect flag $flagname is not set"
20922                 return
20923         fi
20924
20925         # check if multiple modify RPCs data is set
20926         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20927         echo "$out"
20928
20929         echo "$out" | grep -qw $connect_data_name ||
20930                 error "import should have connect data $connect_data_name"
20931 }
20932 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20933
20934 cleanup_247() {
20935         local submount=$1
20936
20937         trap 0
20938         umount_client $submount
20939         rmdir $submount
20940 }
20941
20942 test_247a() {
20943         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20944                 grep -q subtree ||
20945                 skip_env "Fileset feature is not supported"
20946
20947         local submount=${MOUNT}_$tdir
20948
20949         mkdir $MOUNT/$tdir
20950         mkdir -p $submount || error "mkdir $submount failed"
20951         FILESET="$FILESET/$tdir" mount_client $submount ||
20952                 error "mount $submount failed"
20953         trap "cleanup_247 $submount" EXIT
20954         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20955         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20956                 error "read $MOUNT/$tdir/$tfile failed"
20957         cleanup_247 $submount
20958 }
20959 run_test 247a "mount subdir as fileset"
20960
20961 test_247b() {
20962         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20963                 skip_env "Fileset feature is not supported"
20964
20965         local submount=${MOUNT}_$tdir
20966
20967         rm -rf $MOUNT/$tdir
20968         mkdir -p $submount || error "mkdir $submount failed"
20969         SKIP_FILESET=1
20970         FILESET="$FILESET/$tdir" mount_client $submount &&
20971                 error "mount $submount should fail"
20972         rmdir $submount
20973 }
20974 run_test 247b "mount subdir that dose not exist"
20975
20976 test_247c() {
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         mkdir -p $MOUNT/$tdir/dir1
20983         mkdir -p $submount || error "mkdir $submount failed"
20984         trap "cleanup_247 $submount" EXIT
20985         FILESET="$FILESET/$tdir" mount_client $submount ||
20986                 error "mount $submount failed"
20987         local fid=$($LFS path2fid $MOUNT/)
20988         $LFS fid2path $submount $fid && error "fid2path should fail"
20989         cleanup_247 $submount
20990 }
20991 run_test 247c "running fid2path outside subdirectory root"
20992
20993 test_247d() {
20994         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20995                 skip "Fileset feature is not supported"
20996
20997         local submount=${MOUNT}_$tdir
20998
20999         mkdir -p $MOUNT/$tdir/dir1
21000         mkdir -p $submount || error "mkdir $submount failed"
21001         FILESET="$FILESET/$tdir" mount_client $submount ||
21002                 error "mount $submount failed"
21003         trap "cleanup_247 $submount" EXIT
21004
21005         local td=$submount/dir1
21006         local fid=$($LFS path2fid $td)
21007         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21008
21009         # check that we get the same pathname back
21010         local rootpath
21011         local found
21012         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21013                 echo "$rootpath $fid"
21014                 found=$($LFS fid2path $rootpath "$fid")
21015                 [ -n "found" ] || error "fid2path should succeed"
21016                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21017         done
21018         # check wrong root path format
21019         rootpath=$submount"_wrong"
21020         found=$($LFS fid2path $rootpath "$fid")
21021         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21022
21023         cleanup_247 $submount
21024 }
21025 run_test 247d "running fid2path inside subdirectory root"
21026
21027 # LU-8037
21028 test_247e() {
21029         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21030                 grep -q subtree ||
21031                 skip "Fileset feature is not supported"
21032
21033         local submount=${MOUNT}_$tdir
21034
21035         mkdir $MOUNT/$tdir
21036         mkdir -p $submount || error "mkdir $submount failed"
21037         FILESET="$FILESET/.." mount_client $submount &&
21038                 error "mount $submount should fail"
21039         rmdir $submount
21040 }
21041 run_test 247e "mount .. as fileset"
21042
21043 test_247f() {
21044         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21045         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21046                 skip "Need at least version 2.13.52"
21047         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21048                 skip "Need at least version 2.14.50"
21049         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21050                 grep -q subtree ||
21051                 skip "Fileset feature is not supported"
21052
21053         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21054         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21055                 error "mkdir remote failed"
21056         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21057                 error "mkdir remote/subdir failed"
21058         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21059                 error "mkdir striped failed"
21060         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21061
21062         local submount=${MOUNT}_$tdir
21063
21064         mkdir -p $submount || error "mkdir $submount failed"
21065         stack_trap "rmdir $submount"
21066
21067         local dir
21068         local stat
21069         local fileset=$FILESET
21070         local mdts=$(comma_list $(mdts_nodes))
21071
21072         stat=$(do_facet mds1 $LCTL get_param -n \
21073                 mdt.*MDT0000.enable_remote_subdir_mount)
21074         stack_trap "do_nodes $mdts $LCTL set_param \
21075                 mdt.*.enable_remote_subdir_mount=$stat"
21076
21077         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21078         stack_trap "umount_client $submount"
21079         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21080                 error "mount remote dir $dir should fail"
21081
21082         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21083                 $tdir/striped/. ; do
21084                 FILESET="$fileset/$dir" mount_client $submount ||
21085                         error "mount $dir failed"
21086                 umount_client $submount
21087         done
21088
21089         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21090         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21091                 error "mount $tdir/remote failed"
21092 }
21093 run_test 247f "mount striped or remote directory as fileset"
21094
21095 test_247g() {
21096         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21097         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21098                 skip "Need at least version 2.14.50"
21099
21100         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21101                 error "mkdir $tdir failed"
21102         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21103
21104         local submount=${MOUNT}_$tdir
21105
21106         mkdir -p $submount || error "mkdir $submount failed"
21107         stack_trap "rmdir $submount"
21108
21109         FILESET="$fileset/$tdir" mount_client $submount ||
21110                 error "mount $dir failed"
21111         stack_trap "umount $submount"
21112
21113         local mdts=$(comma_list $(mdts_nodes))
21114
21115         local nrpcs
21116
21117         stat $submount > /dev/null
21118         cancel_lru_locks $MDC
21119         stat $submount > /dev/null
21120         stat $submount/$tfile > /dev/null
21121         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21122         stat $submount/$tfile > /dev/null
21123         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21124                 awk '/getattr/ {sum += $2} END {print sum}')
21125
21126         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21127 }
21128 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21129
21130 test_248a() {
21131         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21132         [ -z "$fast_read_sav" ] && skip "no fast read support"
21133
21134         # create a large file for fast read verification
21135         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21136
21137         # make sure the file is created correctly
21138         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21139                 { rm -f $DIR/$tfile; skip "file creation error"; }
21140
21141         echo "Test 1: verify that fast read is 4 times faster on cache read"
21142
21143         # small read with fast read enabled
21144         $LCTL set_param -n llite.*.fast_read=1
21145         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21146                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21147                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21148         # small read with fast read disabled
21149         $LCTL set_param -n llite.*.fast_read=0
21150         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21151                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21152                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21153
21154         # verify that fast read is 4 times faster for cache read
21155         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21156                 error_not_in_vm "fast read was not 4 times faster: " \
21157                            "$t_fast vs $t_slow"
21158
21159         echo "Test 2: verify the performance between big and small read"
21160         $LCTL set_param -n llite.*.fast_read=1
21161
21162         # 1k non-cache read
21163         cancel_lru_locks osc
21164         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21165                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21166                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21167
21168         # 1M non-cache read
21169         cancel_lru_locks osc
21170         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21171                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21172                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21173
21174         # verify that big IO is not 4 times faster than small IO
21175         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21176                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21177
21178         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21179         rm -f $DIR/$tfile
21180 }
21181 run_test 248a "fast read verification"
21182
21183 test_248b() {
21184         # Default short_io_bytes=16384, try both smaller and larger sizes.
21185         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21186         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21187         echo "bs=53248 count=113 normal buffered write"
21188         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21189                 error "dd of initial data file failed"
21190         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21191
21192         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21193         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21194                 error "dd with sync normal writes failed"
21195         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21196
21197         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21198         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21199                 error "dd with sync small writes failed"
21200         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21201
21202         cancel_lru_locks osc
21203
21204         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21205         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21206         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21207         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21208                 iflag=direct || error "dd with O_DIRECT small read failed"
21209         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21210         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21211                 error "compare $TMP/$tfile.1 failed"
21212
21213         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21214         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21215
21216         # just to see what the maximum tunable value is, and test parsing
21217         echo "test invalid parameter 2MB"
21218         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21219                 error "too-large short_io_bytes allowed"
21220         echo "test maximum parameter 512KB"
21221         # if we can set a larger short_io_bytes, run test regardless of version
21222         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21223                 # older clients may not allow setting it this large, that's OK
21224                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21225                         skip "Need at least client version 2.13.50"
21226                 error "medium short_io_bytes failed"
21227         fi
21228         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21229         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21230
21231         echo "test large parameter 64KB"
21232         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21233         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21234
21235         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21236         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21237                 error "dd with sync large writes failed"
21238         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21239
21240         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21241         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21242         num=$((113 * 4096 / PAGE_SIZE))
21243         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21244         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21245                 error "dd with O_DIRECT large writes failed"
21246         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21247                 error "compare $DIR/$tfile.3 failed"
21248
21249         cancel_lru_locks osc
21250
21251         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21252         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21253                 error "dd with O_DIRECT large read failed"
21254         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21255                 error "compare $TMP/$tfile.2 failed"
21256
21257         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21258         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21259                 error "dd with O_DIRECT large read failed"
21260         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21261                 error "compare $TMP/$tfile.3 failed"
21262 }
21263 run_test 248b "test short_io read and write for both small and large sizes"
21264
21265 test_249() { # LU-7890
21266         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21267                 skip "Need at least version 2.8.54"
21268
21269         rm -f $DIR/$tfile
21270         $LFS setstripe -c 1 $DIR/$tfile
21271         # Offset 2T == 4k * 512M
21272         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21273                 error "dd to 2T offset failed"
21274 }
21275 run_test 249 "Write above 2T file size"
21276
21277 test_250() {
21278         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21279          && skip "no 16TB file size limit on ZFS"
21280
21281         $LFS setstripe -c 1 $DIR/$tfile
21282         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21283         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21284         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21285         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21286                 conv=notrunc,fsync && error "append succeeded"
21287         return 0
21288 }
21289 run_test 250 "Write above 16T limit"
21290
21291 test_251() {
21292         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21293
21294         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21295         #Skip once - writing the first stripe will succeed
21296         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21297         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21298                 error "short write happened"
21299
21300         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21301         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21302                 error "short read happened"
21303
21304         rm -f $DIR/$tfile
21305 }
21306 run_test 251 "Handling short read and write correctly"
21307
21308 test_252() {
21309         remote_mds_nodsh && skip "remote MDS with nodsh"
21310         remote_ost_nodsh && skip "remote OST with nodsh"
21311         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21312                 skip_env "ldiskfs only test"
21313         fi
21314
21315         local tgt
21316         local dev
21317         local out
21318         local uuid
21319         local num
21320         local gen
21321
21322         # check lr_reader on OST0000
21323         tgt=ost1
21324         dev=$(facet_device $tgt)
21325         out=$(do_facet $tgt $LR_READER $dev)
21326         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21327         echo "$out"
21328         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21329         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21330                 error "Invalid uuid returned by $LR_READER on target $tgt"
21331         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21332
21333         # check lr_reader -c on MDT0000
21334         tgt=mds1
21335         dev=$(facet_device $tgt)
21336         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21337                 skip "$LR_READER does not support additional options"
21338         fi
21339         out=$(do_facet $tgt $LR_READER -c $dev)
21340         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21341         echo "$out"
21342         num=$(echo "$out" | grep -c "mdtlov")
21343         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21344                 error "Invalid number of mdtlov clients returned by $LR_READER"
21345         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21346
21347         # check lr_reader -cr on MDT0000
21348         out=$(do_facet $tgt $LR_READER -cr $dev)
21349         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21350         echo "$out"
21351         echo "$out" | grep -q "^reply_data:$" ||
21352                 error "$LR_READER should have returned 'reply_data' section"
21353         num=$(echo "$out" | grep -c "client_generation")
21354         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21355 }
21356 run_test 252 "check lr_reader tool"
21357
21358 test_253() {
21359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21360         remote_mds_nodsh && skip "remote MDS with nodsh"
21361         remote_mgs_nodsh && skip "remote MGS with nodsh"
21362
21363         local ostidx=0
21364         local rc=0
21365         local ost_name=$(ostname_from_index $ostidx)
21366
21367         # on the mdt's osc
21368         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21369         do_facet $SINGLEMDS $LCTL get_param -n \
21370                 osp.$mdtosc_proc1.reserved_mb_high ||
21371                 skip  "remote MDS does not support reserved_mb_high"
21372
21373         rm -rf $DIR/$tdir
21374         wait_mds_ost_sync
21375         wait_delete_completed
21376         mkdir $DIR/$tdir
21377
21378         pool_add $TESTNAME || error "Pool creation failed"
21379         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21380
21381         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21382                 error "Setstripe failed"
21383
21384         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21385
21386         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21387                     grep "watermarks")
21388         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21389
21390         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21391                         osp.$mdtosc_proc1.prealloc_status)
21392         echo "prealloc_status $oa_status"
21393
21394         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21395                 error "File creation should fail"
21396
21397         #object allocation was stopped, but we still able to append files
21398         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21399                 oflag=append || error "Append failed"
21400
21401         rm -f $DIR/$tdir/$tfile.0
21402
21403         # For this test, we want to delete the files we created to go out of
21404         # space but leave the watermark, so we remain nearly out of space
21405         ost_watermarks_enospc_delete_files $tfile $ostidx
21406
21407         wait_delete_completed
21408
21409         sleep_maxage
21410
21411         for i in $(seq 10 12); do
21412                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21413                         2>/dev/null || error "File creation failed after rm"
21414         done
21415
21416         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21417                         osp.$mdtosc_proc1.prealloc_status)
21418         echo "prealloc_status $oa_status"
21419
21420         if (( oa_status != 0 )); then
21421                 error "Object allocation still disable after rm"
21422         fi
21423 }
21424 run_test 253 "Check object allocation limit"
21425
21426 test_254() {
21427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21428         remote_mds_nodsh && skip "remote MDS with nodsh"
21429
21430         local mdt=$(facet_svc $SINGLEMDS)
21431
21432         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21433                 skip "MDS does not support changelog_size"
21434
21435         local cl_user
21436
21437         changelog_register || error "changelog_register failed"
21438
21439         changelog_clear 0 || error "changelog_clear failed"
21440
21441         local size1=$(do_facet $SINGLEMDS \
21442                       $LCTL get_param -n mdd.$mdt.changelog_size)
21443         echo "Changelog size $size1"
21444
21445         rm -rf $DIR/$tdir
21446         $LFS mkdir -i 0 $DIR/$tdir
21447         # change something
21448         mkdir -p $DIR/$tdir/pics/2008/zachy
21449         touch $DIR/$tdir/pics/2008/zachy/timestamp
21450         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21451         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21452         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21453         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21454         rm $DIR/$tdir/pics/desktop.jpg
21455
21456         local size2=$(do_facet $SINGLEMDS \
21457                       $LCTL get_param -n mdd.$mdt.changelog_size)
21458         echo "Changelog size after work $size2"
21459
21460         (( $size2 > $size1 )) ||
21461                 error "new Changelog size=$size2 less than old size=$size1"
21462 }
21463 run_test 254 "Check changelog size"
21464
21465 ladvise_no_type()
21466 {
21467         local type=$1
21468         local file=$2
21469
21470         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21471                 awk -F: '{print $2}' | grep $type > /dev/null
21472         if [ $? -ne 0 ]; then
21473                 return 0
21474         fi
21475         return 1
21476 }
21477
21478 ladvise_no_ioctl()
21479 {
21480         local file=$1
21481
21482         lfs ladvise -a willread $file > /dev/null 2>&1
21483         if [ $? -eq 0 ]; then
21484                 return 1
21485         fi
21486
21487         lfs ladvise -a willread $file 2>&1 |
21488                 grep "Inappropriate ioctl for device" > /dev/null
21489         if [ $? -eq 0 ]; then
21490                 return 0
21491         fi
21492         return 1
21493 }
21494
21495 percent() {
21496         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21497 }
21498
21499 # run a random read IO workload
21500 # usage: random_read_iops <filename> <filesize> <iosize>
21501 random_read_iops() {
21502         local file=$1
21503         local fsize=$2
21504         local iosize=${3:-4096}
21505
21506         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21507                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21508 }
21509
21510 drop_file_oss_cache() {
21511         local file="$1"
21512         local nodes="$2"
21513
21514         $LFS ladvise -a dontneed $file 2>/dev/null ||
21515                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21516 }
21517
21518 ladvise_willread_performance()
21519 {
21520         local repeat=10
21521         local average_origin=0
21522         local average_cache=0
21523         local average_ladvise=0
21524
21525         for ((i = 1; i <= $repeat; i++)); do
21526                 echo "Iter $i/$repeat: reading without willread hint"
21527                 cancel_lru_locks osc
21528                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21529                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21530                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21531                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21532
21533                 cancel_lru_locks osc
21534                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21535                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21536                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21537
21538                 cancel_lru_locks osc
21539                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21540                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21541                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21542                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21543                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21544         done
21545         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21546         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21547         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21548
21549         speedup_cache=$(percent $average_cache $average_origin)
21550         speedup_ladvise=$(percent $average_ladvise $average_origin)
21551
21552         echo "Average uncached read: $average_origin"
21553         echo "Average speedup with OSS cached read: " \
21554                 "$average_cache = +$speedup_cache%"
21555         echo "Average speedup with ladvise willread: " \
21556                 "$average_ladvise = +$speedup_ladvise%"
21557
21558         local lowest_speedup=20
21559         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
21560                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
21561                         "got $average_cache%. Skipping ladvise willread check."
21562                 return 0
21563         fi
21564
21565         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21566         # it is still good to run until then to exercise 'ladvise willread'
21567         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21568                 [ "$ost1_FSTYPE" = "zfs" ] &&
21569                 echo "osd-zfs does not support dontneed or drop_caches" &&
21570                 return 0
21571
21572         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21573         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
21574                 error_not_in_vm "Speedup with willread is less than " \
21575                         "$lowest_speedup%, got $average_ladvise%"
21576 }
21577
21578 test_255a() {
21579         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21580                 skip "lustre < 2.8.54 does not support ladvise "
21581         remote_ost_nodsh && skip "remote OST with nodsh"
21582
21583         stack_trap "rm -f $DIR/$tfile"
21584         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21585
21586         ladvise_no_type willread $DIR/$tfile &&
21587                 skip "willread ladvise is not supported"
21588
21589         ladvise_no_ioctl $DIR/$tfile &&
21590                 skip "ladvise ioctl is not supported"
21591
21592         local size_mb=100
21593         local size=$((size_mb * 1048576))
21594         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21595                 error "dd to $DIR/$tfile failed"
21596
21597         lfs ladvise -a willread $DIR/$tfile ||
21598                 error "Ladvise failed with no range argument"
21599
21600         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21601                 error "Ladvise failed with no -l or -e argument"
21602
21603         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21604                 error "Ladvise failed with only -e argument"
21605
21606         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21607                 error "Ladvise failed with only -l argument"
21608
21609         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21610                 error "End offset should not be smaller than start offset"
21611
21612         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21613                 error "End offset should not be equal to start offset"
21614
21615         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21616                 error "Ladvise failed with overflowing -s argument"
21617
21618         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21619                 error "Ladvise failed with overflowing -e argument"
21620
21621         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21622                 error "Ladvise failed with overflowing -l argument"
21623
21624         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21625                 error "Ladvise succeeded with conflicting -l and -e arguments"
21626
21627         echo "Synchronous ladvise should wait"
21628         local delay=4
21629 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21630         do_nodes $(comma_list $(osts_nodes)) \
21631                 $LCTL set_param fail_val=$delay fail_loc=0x237
21632
21633         local start_ts=$SECONDS
21634         lfs ladvise -a willread $DIR/$tfile ||
21635                 error "Ladvise failed with no range argument"
21636         local end_ts=$SECONDS
21637         local inteval_ts=$((end_ts - start_ts))
21638
21639         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21640                 error "Synchronous advice didn't wait reply"
21641         fi
21642
21643         echo "Asynchronous ladvise shouldn't wait"
21644         local start_ts=$SECONDS
21645         lfs ladvise -a willread -b $DIR/$tfile ||
21646                 error "Ladvise failed with no range argument"
21647         local end_ts=$SECONDS
21648         local inteval_ts=$((end_ts - start_ts))
21649
21650         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21651                 error "Asynchronous advice blocked"
21652         fi
21653
21654         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21655         ladvise_willread_performance
21656 }
21657 run_test 255a "check 'lfs ladvise -a willread'"
21658
21659 facet_meminfo() {
21660         local facet=$1
21661         local info=$2
21662
21663         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21664 }
21665
21666 test_255b() {
21667         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21668                 skip "lustre < 2.8.54 does not support ladvise "
21669         remote_ost_nodsh && skip "remote OST with nodsh"
21670
21671         stack_trap "rm -f $DIR/$tfile"
21672         lfs setstripe -c 1 -i 0 $DIR/$tfile
21673
21674         ladvise_no_type dontneed $DIR/$tfile &&
21675                 skip "dontneed ladvise is not supported"
21676
21677         ladvise_no_ioctl $DIR/$tfile &&
21678                 skip "ladvise ioctl is not supported"
21679
21680         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21681                 [ "$ost1_FSTYPE" = "zfs" ] &&
21682                 skip "zfs-osd does not support 'ladvise dontneed'"
21683
21684         local size_mb=100
21685         local size=$((size_mb * 1048576))
21686         # In order to prevent disturbance of other processes, only check 3/4
21687         # of the memory usage
21688         local kibibytes=$((size_mb * 1024 * 3 / 4))
21689
21690         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21691                 error "dd to $DIR/$tfile failed"
21692
21693         #force write to complete before dropping OST cache & checking memory
21694         sync
21695
21696         local total=$(facet_meminfo ost1 MemTotal)
21697         echo "Total memory: $total KiB"
21698
21699         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21700         local before_read=$(facet_meminfo ost1 Cached)
21701         echo "Cache used before read: $before_read KiB"
21702
21703         lfs ladvise -a willread $DIR/$tfile ||
21704                 error "Ladvise willread failed"
21705         local after_read=$(facet_meminfo ost1 Cached)
21706         echo "Cache used after read: $after_read KiB"
21707
21708         lfs ladvise -a dontneed $DIR/$tfile ||
21709                 error "Ladvise dontneed again failed"
21710         local no_read=$(facet_meminfo ost1 Cached)
21711         echo "Cache used after dontneed ladvise: $no_read KiB"
21712
21713         if [ $total -lt $((before_read + kibibytes)) ]; then
21714                 echo "Memory is too small, abort checking"
21715                 return 0
21716         fi
21717
21718         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21719                 error "Ladvise willread should use more memory" \
21720                         "than $kibibytes KiB"
21721         fi
21722
21723         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21724                 error "Ladvise dontneed should release more memory" \
21725                         "than $kibibytes KiB"
21726         fi
21727 }
21728 run_test 255b "check 'lfs ladvise -a dontneed'"
21729
21730 test_255c() {
21731         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21732                 skip "lustre < 2.10.50 does not support lockahead"
21733
21734         local ost1_imp=$(get_osc_import_name client ost1)
21735         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21736                          cut -d'.' -f2)
21737         local count
21738         local new_count
21739         local difference
21740         local i
21741         local rc
21742
21743         test_mkdir -p $DIR/$tdir
21744         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21745
21746         #test 10 returns only success/failure
21747         i=10
21748         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21749         rc=$?
21750         if [ $rc -eq 255 ]; then
21751                 error "Ladvise test${i} failed, ${rc}"
21752         fi
21753
21754         #test 11 counts lock enqueue requests, all others count new locks
21755         i=11
21756         count=$(do_facet ost1 \
21757                 $LCTL get_param -n ost.OSS.ost.stats)
21758         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21759
21760         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21761         rc=$?
21762         if [ $rc -eq 255 ]; then
21763                 error "Ladvise test${i} failed, ${rc}"
21764         fi
21765
21766         new_count=$(do_facet ost1 \
21767                 $LCTL get_param -n ost.OSS.ost.stats)
21768         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21769                    awk '{ print $2 }')
21770
21771         difference="$((new_count - count))"
21772         if [ $difference -ne $rc ]; then
21773                 error "Ladvise test${i}, bad enqueue count, returned " \
21774                       "${rc}, actual ${difference}"
21775         fi
21776
21777         for i in $(seq 12 21); do
21778                 # If we do not do this, we run the risk of having too many
21779                 # locks and starting lock cancellation while we are checking
21780                 # lock counts.
21781                 cancel_lru_locks osc
21782
21783                 count=$($LCTL get_param -n \
21784                        ldlm.namespaces.$imp_name.lock_unused_count)
21785
21786                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21787                 rc=$?
21788                 if [ $rc -eq 255 ]; then
21789                         error "Ladvise test ${i} failed, ${rc}"
21790                 fi
21791
21792                 new_count=$($LCTL get_param -n \
21793                        ldlm.namespaces.$imp_name.lock_unused_count)
21794                 difference="$((new_count - count))"
21795
21796                 # Test 15 output is divided by 100 to map down to valid return
21797                 if [ $i -eq 15 ]; then
21798                         rc="$((rc * 100))"
21799                 fi
21800
21801                 if [ $difference -ne $rc ]; then
21802                         error "Ladvise test ${i}, bad lock count, returned " \
21803                               "${rc}, actual ${difference}"
21804                 fi
21805         done
21806
21807         #test 22 returns only success/failure
21808         i=22
21809         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21810         rc=$?
21811         if [ $rc -eq 255 ]; then
21812                 error "Ladvise test${i} failed, ${rc}"
21813         fi
21814 }
21815 run_test 255c "suite of ladvise lockahead tests"
21816
21817 test_256() {
21818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21819         remote_mds_nodsh && skip "remote MDS with nodsh"
21820         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21821         changelog_users $SINGLEMDS | grep "^cl" &&
21822                 skip "active changelog user"
21823
21824         local cl_user
21825         local cat_sl
21826         local mdt_dev
21827
21828         mdt_dev=$(mdsdevname 1)
21829         echo $mdt_dev
21830
21831         changelog_register || error "changelog_register failed"
21832
21833         rm -rf $DIR/$tdir
21834         mkdir_on_mdt0 $DIR/$tdir
21835
21836         changelog_clear 0 || error "changelog_clear failed"
21837
21838         # change something
21839         touch $DIR/$tdir/{1..10}
21840
21841         # stop the MDT
21842         stop $SINGLEMDS || error "Fail to stop MDT"
21843
21844         # remount the MDT
21845
21846         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21847
21848         #after mount new plainllog is used
21849         touch $DIR/$tdir/{11..19}
21850         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21851         stack_trap "rm -f $tmpfile"
21852         cat_sl=$(do_facet $SINGLEMDS "sync; \
21853                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21854                  llog_reader $tmpfile | grep -c type=1064553b")
21855         do_facet $SINGLEMDS llog_reader $tmpfile
21856
21857         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21858
21859         changelog_clear 0 || error "changelog_clear failed"
21860
21861         cat_sl=$(do_facet $SINGLEMDS "sync; \
21862                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21863                  llog_reader $tmpfile | grep -c type=1064553b")
21864
21865         if (( cat_sl == 2 )); then
21866                 error "Empty plain llog was not deleted from changelog catalog"
21867         elif (( cat_sl != 1 )); then
21868                 error "Active plain llog shouldn't be deleted from catalog"
21869         fi
21870 }
21871 run_test 256 "Check llog delete for empty and not full state"
21872
21873 test_257() {
21874         remote_mds_nodsh && skip "remote MDS with nodsh"
21875         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21876                 skip "Need MDS version at least 2.8.55"
21877
21878         test_mkdir $DIR/$tdir
21879
21880         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21881                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21882         stat $DIR/$tdir
21883
21884 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21885         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21886         local facet=mds$((mdtidx + 1))
21887         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21888         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21889
21890         stop $facet || error "stop MDS failed"
21891         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21892                 error "start MDS fail"
21893         wait_recovery_complete $facet
21894 }
21895 run_test 257 "xattr locks are not lost"
21896
21897 # Verify we take the i_mutex when security requires it
21898 test_258a() {
21899 #define OBD_FAIL_IMUTEX_SEC 0x141c
21900         $LCTL set_param fail_loc=0x141c
21901         touch $DIR/$tfile
21902         chmod u+s $DIR/$tfile
21903         chmod a+rwx $DIR/$tfile
21904         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21905         RC=$?
21906         if [ $RC -ne 0 ]; then
21907                 error "error, failed to take i_mutex, rc=$?"
21908         fi
21909         rm -f $DIR/$tfile
21910 }
21911 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21912
21913 # Verify we do NOT take the i_mutex in the normal case
21914 test_258b() {
21915 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21916         $LCTL set_param fail_loc=0x141d
21917         touch $DIR/$tfile
21918         chmod a+rwx $DIR
21919         chmod a+rw $DIR/$tfile
21920         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21921         RC=$?
21922         if [ $RC -ne 0 ]; then
21923                 error "error, took i_mutex unnecessarily, rc=$?"
21924         fi
21925         rm -f $DIR/$tfile
21926
21927 }
21928 run_test 258b "verify i_mutex security behavior"
21929
21930 test_259() {
21931         local file=$DIR/$tfile
21932         local before
21933         local after
21934
21935         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21936
21937         stack_trap "rm -f $file" EXIT
21938
21939         wait_delete_completed
21940         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21941         echo "before: $before"
21942
21943         $LFS setstripe -i 0 -c 1 $file
21944         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21945         sync_all_data
21946         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21947         echo "after write: $after"
21948
21949 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21950         do_facet ost1 $LCTL set_param fail_loc=0x2301
21951         $TRUNCATE $file 0
21952         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21953         echo "after truncate: $after"
21954
21955         stop ost1
21956         do_facet ost1 $LCTL set_param fail_loc=0
21957         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21958         sleep 2
21959         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21960         echo "after restart: $after"
21961         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21962                 error "missing truncate?"
21963
21964         return 0
21965 }
21966 run_test 259 "crash at delayed truncate"
21967
21968 test_260() {
21969 #define OBD_FAIL_MDC_CLOSE               0x806
21970         $LCTL set_param fail_loc=0x80000806
21971         touch $DIR/$tfile
21972
21973 }
21974 run_test 260 "Check mdc_close fail"
21975
21976 ### Data-on-MDT sanity tests ###
21977 test_270a() {
21978         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21979                 skip "Need MDS version at least 2.10.55 for DoM"
21980
21981         # create DoM file
21982         local dom=$DIR/$tdir/dom_file
21983         local tmp=$DIR/$tdir/tmp_file
21984
21985         mkdir_on_mdt0 $DIR/$tdir
21986
21987         # basic checks for DoM component creation
21988         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21989                 error "Can set MDT layout to non-first entry"
21990
21991         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21992                 error "Can define multiple entries as MDT layout"
21993
21994         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21995
21996         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21997         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21998         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21999
22000         local mdtidx=$($LFS getstripe -m $dom)
22001         local mdtname=MDT$(printf %04x $mdtidx)
22002         local facet=mds$((mdtidx + 1))
22003         local space_check=1
22004
22005         # Skip free space checks with ZFS
22006         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22007
22008         # write
22009         sync
22010         local size_tmp=$((65536 * 3))
22011         local mdtfree1=$(do_facet $facet \
22012                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22013
22014         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22015         # check also direct IO along write
22016         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22017         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22018         sync
22019         cmp $tmp $dom || error "file data is different"
22020         [ $(stat -c%s $dom) == $size_tmp ] ||
22021                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22022         if [ $space_check == 1 ]; then
22023                 local mdtfree2=$(do_facet $facet \
22024                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22025
22026                 # increase in usage from by $size_tmp
22027                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22028                         error "MDT free space wrong after write: " \
22029                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22030         fi
22031
22032         # truncate
22033         local size_dom=10000
22034
22035         $TRUNCATE $dom $size_dom
22036         [ $(stat -c%s $dom) == $size_dom ] ||
22037                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22038         if [ $space_check == 1 ]; then
22039                 mdtfree1=$(do_facet $facet \
22040                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22041                 # decrease in usage from $size_tmp to new $size_dom
22042                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22043                   $(((size_tmp - size_dom) / 1024)) ] ||
22044                         error "MDT free space is wrong after truncate: " \
22045                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22046         fi
22047
22048         # append
22049         cat $tmp >> $dom
22050         sync
22051         size_dom=$((size_dom + size_tmp))
22052         [ $(stat -c%s $dom) == $size_dom ] ||
22053                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22054         if [ $space_check == 1 ]; then
22055                 mdtfree2=$(do_facet $facet \
22056                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22057                 # increase in usage by $size_tmp from previous
22058                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22059                         error "MDT free space is wrong after append: " \
22060                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22061         fi
22062
22063         # delete
22064         rm $dom
22065         if [ $space_check == 1 ]; then
22066                 mdtfree1=$(do_facet $facet \
22067                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22068                 # decrease in usage by $size_dom from previous
22069                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22070                         error "MDT free space is wrong after removal: " \
22071                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22072         fi
22073
22074         # combined striping
22075         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22076                 error "Can't create DoM + OST striping"
22077
22078         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22079         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22080         # check also direct IO along write
22081         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22082         sync
22083         cmp $tmp $dom || error "file data is different"
22084         [ $(stat -c%s $dom) == $size_tmp ] ||
22085                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22086         rm $dom $tmp
22087
22088         return 0
22089 }
22090 run_test 270a "DoM: basic functionality tests"
22091
22092 test_270b() {
22093         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22094                 skip "Need MDS version at least 2.10.55"
22095
22096         local dom=$DIR/$tdir/dom_file
22097         local max_size=1048576
22098
22099         mkdir -p $DIR/$tdir
22100         $LFS setstripe -E $max_size -L mdt $dom
22101
22102         # truncate over the limit
22103         $TRUNCATE $dom $(($max_size + 1)) &&
22104                 error "successful truncate over the maximum size"
22105         # write over the limit
22106         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22107                 error "successful write over the maximum size"
22108         # append over the limit
22109         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22110         echo "12345" >> $dom && error "successful append over the maximum size"
22111         rm $dom
22112
22113         return 0
22114 }
22115 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22116
22117 test_270c() {
22118         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22119                 skip "Need MDS version at least 2.10.55"
22120
22121         mkdir -p $DIR/$tdir
22122         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22123
22124         # check files inherit DoM EA
22125         touch $DIR/$tdir/first
22126         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22127                 error "bad pattern"
22128         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22129                 error "bad stripe count"
22130         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22131                 error "bad stripe size"
22132
22133         # check directory inherits DoM EA and uses it as default
22134         mkdir $DIR/$tdir/subdir
22135         touch $DIR/$tdir/subdir/second
22136         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22137                 error "bad pattern in sub-directory"
22138         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22139                 error "bad stripe count in sub-directory"
22140         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22141                 error "bad stripe size in sub-directory"
22142         return 0
22143 }
22144 run_test 270c "DoM: DoM EA inheritance tests"
22145
22146 test_270d() {
22147         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22148                 skip "Need MDS version at least 2.10.55"
22149
22150         mkdir -p $DIR/$tdir
22151         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22152
22153         # inherit default DoM striping
22154         mkdir $DIR/$tdir/subdir
22155         touch $DIR/$tdir/subdir/f1
22156
22157         # change default directory striping
22158         $LFS setstripe -c 1 $DIR/$tdir/subdir
22159         touch $DIR/$tdir/subdir/f2
22160         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22161                 error "wrong default striping in file 2"
22162         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22163                 error "bad pattern in file 2"
22164         return 0
22165 }
22166 run_test 270d "DoM: change striping from DoM to RAID0"
22167
22168 test_270e() {
22169         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22170                 skip "Need MDS version at least 2.10.55"
22171
22172         mkdir -p $DIR/$tdir/dom
22173         mkdir -p $DIR/$tdir/norm
22174         DOMFILES=20
22175         NORMFILES=10
22176         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22177         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22178
22179         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22180         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22181
22182         # find DoM files by layout
22183         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22184         [ $NUM -eq  $DOMFILES ] ||
22185                 error "lfs find -L: found $NUM, expected $DOMFILES"
22186         echo "Test 1: lfs find 20 DOM files by layout: OK"
22187
22188         # there should be 1 dir with default DOM striping
22189         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22190         [ $NUM -eq  1 ] ||
22191                 error "lfs find -L: found $NUM, expected 1 dir"
22192         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22193
22194         # find DoM files by stripe size
22195         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22196         [ $NUM -eq  $DOMFILES ] ||
22197                 error "lfs find -S: found $NUM, expected $DOMFILES"
22198         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22199
22200         # find files by stripe offset except DoM files
22201         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22202         [ $NUM -eq  $NORMFILES ] ||
22203                 error "lfs find -i: found $NUM, expected $NORMFILES"
22204         echo "Test 5: lfs find no DOM files by stripe index: OK"
22205         return 0
22206 }
22207 run_test 270e "DoM: lfs find with DoM files test"
22208
22209 test_270f() {
22210         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22211                 skip "Need MDS version at least 2.10.55"
22212
22213         local mdtname=${FSNAME}-MDT0000-mdtlov
22214         local dom=$DIR/$tdir/dom_file
22215         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22216                                                 lod.$mdtname.dom_stripesize)
22217         local dom_limit=131072
22218
22219         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22220         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22221                                                 lod.$mdtname.dom_stripesize)
22222         [ ${dom_limit} -eq ${dom_current} ] ||
22223                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22224
22225         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22226         $LFS setstripe -d $DIR/$tdir
22227         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22228                 error "Can't set directory default striping"
22229
22230         # exceed maximum stripe size
22231         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22232                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22233         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22234                 error "Able to create DoM component size more than LOD limit"
22235
22236         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22237         dom_current=$(do_facet mds1 $LCTL get_param -n \
22238                                                 lod.$mdtname.dom_stripesize)
22239         [ 0 -eq ${dom_current} ] ||
22240                 error "Can't set zero DoM stripe limit"
22241         rm $dom
22242
22243         # attempt to create DoM file on server with disabled DoM should
22244         # remove DoM entry from layout and be succeed
22245         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22246                 error "Can't create DoM file (DoM is disabled)"
22247         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22248                 error "File has DoM component while DoM is disabled"
22249         rm $dom
22250
22251         # attempt to create DoM file with only DoM stripe should return error
22252         $LFS setstripe -E $dom_limit -L mdt $dom &&
22253                 error "Able to create DoM-only file while DoM is disabled"
22254
22255         # too low values to be aligned with smallest stripe size 64K
22256         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22257         dom_current=$(do_facet mds1 $LCTL get_param -n \
22258                                                 lod.$mdtname.dom_stripesize)
22259         [ 30000 -eq ${dom_current} ] &&
22260                 error "Can set too small DoM stripe limit"
22261
22262         # 64K is a minimal stripe size in Lustre, expect limit of that size
22263         [ 65536 -eq ${dom_current} ] ||
22264                 error "Limit is not set to 64K but ${dom_current}"
22265
22266         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22267         dom_current=$(do_facet mds1 $LCTL get_param -n \
22268                                                 lod.$mdtname.dom_stripesize)
22269         echo $dom_current
22270         [ 2147483648 -eq ${dom_current} ] &&
22271                 error "Can set too large DoM stripe limit"
22272
22273         do_facet mds1 $LCTL set_param -n \
22274                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22275         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22276                 error "Can't create DoM component size after limit change"
22277         do_facet mds1 $LCTL set_param -n \
22278                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22279         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22280                 error "Can't create DoM file after limit decrease"
22281         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22282                 error "Can create big DoM component after limit decrease"
22283         touch ${dom}_def ||
22284                 error "Can't create file with old default layout"
22285
22286         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22287         return 0
22288 }
22289 run_test 270f "DoM: maximum DoM stripe size checks"
22290
22291 test_270g() {
22292         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22293                 skip "Need MDS version at least 2.13.52"
22294         local dom=$DIR/$tdir/$tfile
22295
22296         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22297         local lodname=${FSNAME}-MDT0000-mdtlov
22298
22299         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22300         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22301         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22302         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22303
22304         local dom_limit=1024
22305         local dom_threshold="50%"
22306
22307         $LFS setstripe -d $DIR/$tdir
22308         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22309                 error "Can't set directory default striping"
22310
22311         do_facet mds1 $LCTL set_param -n \
22312                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22313         # set 0 threshold and create DOM file to change tunable stripesize
22314         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22315         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22316                 error "Failed to create $dom file"
22317         # now tunable dom_cur_stripesize should reach maximum
22318         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22319                                         lod.${lodname}.dom_stripesize_cur_kb)
22320         [[ $dom_current == $dom_limit ]] ||
22321                 error "Current DOM stripesize is not maximum"
22322         rm $dom
22323
22324         # set threshold for further tests
22325         do_facet mds1 $LCTL set_param -n \
22326                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22327         echo "DOM threshold is $dom_threshold free space"
22328         local dom_def
22329         local dom_set
22330         # Spoof bfree to exceed threshold
22331         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22332         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22333         for spfree in 40 20 0 15 30 55; do
22334                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22335                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22336                         error "Failed to create $dom file"
22337                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22338                                         lod.${lodname}.dom_stripesize_cur_kb)
22339                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22340                 [[ $dom_def != $dom_current ]] ||
22341                         error "Default stripe size was not changed"
22342                 if [[ $spfree > 0 ]] ; then
22343                         dom_set=$($LFS getstripe -S $dom)
22344                         [[ $dom_set == $((dom_def * 1024)) ]] ||
22345                                 error "DOM component size is still old"
22346                 else
22347                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22348                                 error "DoM component is set with no free space"
22349                 fi
22350                 rm $dom
22351                 dom_current=$dom_def
22352         done
22353 }
22354 run_test 270g "DoM: default DoM stripe size depends on free space"
22355
22356 test_270h() {
22357         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22358                 skip "Need MDS version at least 2.13.53"
22359
22360         local mdtname=${FSNAME}-MDT0000-mdtlov
22361         local dom=$DIR/$tdir/$tfile
22362         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22363
22364         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22365         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22366
22367         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22368         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22369                 error "can't create OST file"
22370         # mirrored file with DOM entry in the second mirror
22371         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22372                 error "can't create mirror with DoM component"
22373
22374         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22375
22376         # DOM component in the middle and has other enries in the same mirror,
22377         # should succeed but lost DoM component
22378         $LFS setstripe --copy=${dom}_1 $dom ||
22379                 error "Can't create file from OST|DOM mirror layout"
22380         # check new file has no DoM layout after all
22381         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22382                 error "File has DoM component while DoM is disabled"
22383 }
22384 run_test 270h "DoM: DoM stripe removal when disabled on server"
22385
22386 test_270i() {
22387         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22388                 skip "Need MDS version at least 2.14.54"
22389
22390         mkdir $DIR/$tdir
22391         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22392                 error "setstripe should fail" || true
22393 }
22394 run_test 270i "DoM: setting invalid DoM striping should fail"
22395
22396 test_271a() {
22397         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22398                 skip "Need MDS version at least 2.10.55"
22399
22400         local dom=$DIR/$tdir/dom
22401
22402         mkdir -p $DIR/$tdir
22403
22404         $LFS setstripe -E 1024K -L mdt $dom
22405
22406         lctl set_param -n mdc.*.stats=clear
22407         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22408         cat $dom > /dev/null
22409         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22410         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22411         ls $dom
22412         rm -f $dom
22413 }
22414 run_test 271a "DoM: data is cached for read after write"
22415
22416 test_271b() {
22417         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22418                 skip "Need MDS version at least 2.10.55"
22419
22420         local dom=$DIR/$tdir/dom
22421
22422         mkdir -p $DIR/$tdir
22423
22424         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22425
22426         lctl set_param -n mdc.*.stats=clear
22427         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22428         cancel_lru_locks mdc
22429         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22430         # second stat to check size is cached on client
22431         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22432         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22433         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22434         rm -f $dom
22435 }
22436 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22437
22438 test_271ba() {
22439         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22440                 skip "Need MDS version at least 2.10.55"
22441
22442         local dom=$DIR/$tdir/dom
22443
22444         mkdir -p $DIR/$tdir
22445
22446         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22447
22448         lctl set_param -n mdc.*.stats=clear
22449         lctl set_param -n osc.*.stats=clear
22450         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22451         cancel_lru_locks mdc
22452         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22453         # second stat to check size is cached on client
22454         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22455         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22456         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22457         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22458         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22459         rm -f $dom
22460 }
22461 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22462
22463
22464 get_mdc_stats() {
22465         local mdtidx=$1
22466         local param=$2
22467         local mdt=MDT$(printf %04x $mdtidx)
22468
22469         if [ -z $param ]; then
22470                 lctl get_param -n mdc.*$mdt*.stats
22471         else
22472                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22473         fi
22474 }
22475
22476 test_271c() {
22477         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22478                 skip "Need MDS version at least 2.10.55"
22479
22480         local dom=$DIR/$tdir/dom
22481
22482         mkdir -p $DIR/$tdir
22483
22484         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22485
22486         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22487         local facet=mds$((mdtidx + 1))
22488
22489         cancel_lru_locks mdc
22490         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22491         createmany -o $dom 1000
22492         lctl set_param -n mdc.*.stats=clear
22493         smalliomany -w $dom 1000 200
22494         get_mdc_stats $mdtidx
22495         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22496         # Each file has 1 open, 1 IO enqueues, total 2000
22497         # but now we have also +1 getxattr for security.capability, total 3000
22498         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22499         unlinkmany $dom 1000
22500
22501         cancel_lru_locks mdc
22502         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22503         createmany -o $dom 1000
22504         lctl set_param -n mdc.*.stats=clear
22505         smalliomany -w $dom 1000 200
22506         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22507         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22508         # for OPEN and IO lock.
22509         [ $((enq - enq_2)) -ge 1000 ] ||
22510                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22511         unlinkmany $dom 1000
22512         return 0
22513 }
22514 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22515
22516 cleanup_271def_tests() {
22517         trap 0
22518         rm -f $1
22519 }
22520
22521 test_271d() {
22522         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22523                 skip "Need MDS version at least 2.10.57"
22524
22525         local dom=$DIR/$tdir/dom
22526         local tmp=$TMP/$tfile
22527         trap "cleanup_271def_tests $tmp" EXIT
22528
22529         mkdir -p $DIR/$tdir
22530
22531         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22532
22533         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22534
22535         cancel_lru_locks mdc
22536         dd if=/dev/urandom of=$tmp bs=1000 count=1
22537         dd if=$tmp of=$dom bs=1000 count=1
22538         cancel_lru_locks mdc
22539
22540         cat /etc/hosts >> $tmp
22541         lctl set_param -n mdc.*.stats=clear
22542
22543         # append data to the same file it should update local page
22544         echo "Append to the same page"
22545         cat /etc/hosts >> $dom
22546         local num=$(get_mdc_stats $mdtidx ost_read)
22547         local ra=$(get_mdc_stats $mdtidx req_active)
22548         local rw=$(get_mdc_stats $mdtidx req_waittime)
22549
22550         [ -z $num ] || error "$num READ RPC occured"
22551         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22552         echo "... DONE"
22553
22554         # compare content
22555         cmp $tmp $dom || error "file miscompare"
22556
22557         cancel_lru_locks mdc
22558         lctl set_param -n mdc.*.stats=clear
22559
22560         echo "Open and read file"
22561         cat $dom > /dev/null
22562         local num=$(get_mdc_stats $mdtidx ost_read)
22563         local ra=$(get_mdc_stats $mdtidx req_active)
22564         local rw=$(get_mdc_stats $mdtidx req_waittime)
22565
22566         [ -z $num ] || error "$num READ RPC occured"
22567         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22568         echo "... DONE"
22569
22570         # compare content
22571         cmp $tmp $dom || error "file miscompare"
22572
22573         return 0
22574 }
22575 run_test 271d "DoM: read on open (1K file in reply buffer)"
22576
22577 test_271f() {
22578         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22579                 skip "Need MDS version at least 2.10.57"
22580
22581         local dom=$DIR/$tdir/dom
22582         local tmp=$TMP/$tfile
22583         trap "cleanup_271def_tests $tmp" EXIT
22584
22585         mkdir -p $DIR/$tdir
22586
22587         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22588
22589         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22590
22591         cancel_lru_locks mdc
22592         dd if=/dev/urandom of=$tmp bs=265000 count=1
22593         dd if=$tmp of=$dom bs=265000 count=1
22594         cancel_lru_locks mdc
22595         cat /etc/hosts >> $tmp
22596         lctl set_param -n mdc.*.stats=clear
22597
22598         echo "Append to the same page"
22599         cat /etc/hosts >> $dom
22600         local num=$(get_mdc_stats $mdtidx ost_read)
22601         local ra=$(get_mdc_stats $mdtidx req_active)
22602         local rw=$(get_mdc_stats $mdtidx req_waittime)
22603
22604         [ -z $num ] || error "$num READ RPC occured"
22605         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22606         echo "... DONE"
22607
22608         # compare content
22609         cmp $tmp $dom || error "file miscompare"
22610
22611         cancel_lru_locks mdc
22612         lctl set_param -n mdc.*.stats=clear
22613
22614         echo "Open and read file"
22615         cat $dom > /dev/null
22616         local num=$(get_mdc_stats $mdtidx ost_read)
22617         local ra=$(get_mdc_stats $mdtidx req_active)
22618         local rw=$(get_mdc_stats $mdtidx req_waittime)
22619
22620         [ -z $num ] && num=0
22621         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22622         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22623         echo "... DONE"
22624
22625         # compare content
22626         cmp $tmp $dom || error "file miscompare"
22627
22628         return 0
22629 }
22630 run_test 271f "DoM: read on open (200K file and read tail)"
22631
22632 test_271g() {
22633         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22634                 skip "Skipping due to old client or server version"
22635
22636         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22637         # to get layout
22638         $CHECKSTAT -t file $DIR1/$tfile
22639
22640         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22641         MULTIOP_PID=$!
22642         sleep 1
22643         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22644         $LCTL set_param fail_loc=0x80000314
22645         rm $DIR1/$tfile || error "Unlink fails"
22646         RC=$?
22647         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22648         [ $RC -eq 0 ] || error "Failed write to stale object"
22649 }
22650 run_test 271g "Discard DoM data vs client flush race"
22651
22652 test_272a() {
22653         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22654                 skip "Need MDS version at least 2.11.50"
22655
22656         local dom=$DIR/$tdir/dom
22657         mkdir -p $DIR/$tdir
22658
22659         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22660         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22661                 error "failed to write data into $dom"
22662         local old_md5=$(md5sum $dom)
22663
22664         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22665                 error "failed to migrate to the same DoM component"
22666
22667         local new_md5=$(md5sum $dom)
22668
22669         [ "$old_md5" == "$new_md5" ] ||
22670                 error "md5sum differ: $old_md5, $new_md5"
22671
22672         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22673                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22674 }
22675 run_test 272a "DoM migration: new layout with the same DOM component"
22676
22677 test_272b() {
22678         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22679                 skip "Need MDS version at least 2.11.50"
22680
22681         local dom=$DIR/$tdir/dom
22682         mkdir -p $DIR/$tdir
22683         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22684
22685         local mdtidx=$($LFS getstripe -m $dom)
22686         local mdtname=MDT$(printf %04x $mdtidx)
22687         local facet=mds$((mdtidx + 1))
22688
22689         local mdtfree1=$(do_facet $facet \
22690                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22691         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22692                 error "failed to write data into $dom"
22693         local old_md5=$(md5sum $dom)
22694         cancel_lru_locks mdc
22695         local mdtfree1=$(do_facet $facet \
22696                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22697
22698         $LFS migrate -c2 $dom ||
22699                 error "failed to migrate to the new composite layout"
22700         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22701                 error "MDT stripe was not removed"
22702
22703         cancel_lru_locks mdc
22704         local new_md5=$(md5sum $dom)
22705         [ "$old_md5" == "$new_md5" ] ||
22706                 error "$old_md5 != $new_md5"
22707
22708         # Skip free space checks with ZFS
22709         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22710                 local mdtfree2=$(do_facet $facet \
22711                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22712                 [ $mdtfree2 -gt $mdtfree1 ] ||
22713                         error "MDT space is not freed after migration"
22714         fi
22715         return 0
22716 }
22717 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22718
22719 test_272c() {
22720         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22721                 skip "Need MDS version at least 2.11.50"
22722
22723         local dom=$DIR/$tdir/$tfile
22724         mkdir -p $DIR/$tdir
22725         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22726
22727         local mdtidx=$($LFS getstripe -m $dom)
22728         local mdtname=MDT$(printf %04x $mdtidx)
22729         local facet=mds$((mdtidx + 1))
22730
22731         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22732                 error "failed to write data into $dom"
22733         local old_md5=$(md5sum $dom)
22734         cancel_lru_locks mdc
22735         local mdtfree1=$(do_facet $facet \
22736                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22737
22738         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22739                 error "failed to migrate to the new composite layout"
22740         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22741                 error "MDT stripe was not removed"
22742
22743         cancel_lru_locks mdc
22744         local new_md5=$(md5sum $dom)
22745         [ "$old_md5" == "$new_md5" ] ||
22746                 error "$old_md5 != $new_md5"
22747
22748         # Skip free space checks with ZFS
22749         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22750                 local mdtfree2=$(do_facet $facet \
22751                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22752                 [ $mdtfree2 -gt $mdtfree1 ] ||
22753                         error "MDS space is not freed after migration"
22754         fi
22755         return 0
22756 }
22757 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22758
22759 test_272d() {
22760         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22761                 skip "Need MDS version at least 2.12.55"
22762
22763         local dom=$DIR/$tdir/$tfile
22764         mkdir -p $DIR/$tdir
22765         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22766
22767         local mdtidx=$($LFS getstripe -m $dom)
22768         local mdtname=MDT$(printf %04x $mdtidx)
22769         local facet=mds$((mdtidx + 1))
22770
22771         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22772                 error "failed to write data into $dom"
22773         local old_md5=$(md5sum $dom)
22774         cancel_lru_locks mdc
22775         local mdtfree1=$(do_facet $facet \
22776                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22777
22778         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22779                 error "failed mirroring to the new composite layout"
22780         $LFS mirror resync $dom ||
22781                 error "failed mirror resync"
22782         $LFS mirror split --mirror-id 1 -d $dom ||
22783                 error "failed mirror split"
22784
22785         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22786                 error "MDT stripe was not removed"
22787
22788         cancel_lru_locks mdc
22789         local new_md5=$(md5sum $dom)
22790         [ "$old_md5" == "$new_md5" ] ||
22791                 error "$old_md5 != $new_md5"
22792
22793         # Skip free space checks with ZFS
22794         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22795                 local mdtfree2=$(do_facet $facet \
22796                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22797                 [ $mdtfree2 -gt $mdtfree1 ] ||
22798                         error "MDS space is not freed after DOM mirror deletion"
22799         fi
22800         return 0
22801 }
22802 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22803
22804 test_272e() {
22805         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22806                 skip "Need MDS version at least 2.12.55"
22807
22808         local dom=$DIR/$tdir/$tfile
22809         mkdir -p $DIR/$tdir
22810         $LFS setstripe -c 2 $dom
22811
22812         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22813                 error "failed to write data into $dom"
22814         local old_md5=$(md5sum $dom)
22815         cancel_lru_locks
22816
22817         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22818                 error "failed mirroring to the DOM layout"
22819         $LFS mirror resync $dom ||
22820                 error "failed mirror resync"
22821         $LFS mirror split --mirror-id 1 -d $dom ||
22822                 error "failed mirror split"
22823
22824         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22825                 error "MDT stripe wasn't set"
22826
22827         cancel_lru_locks
22828         local new_md5=$(md5sum $dom)
22829         [ "$old_md5" == "$new_md5" ] ||
22830                 error "$old_md5 != $new_md5"
22831
22832         return 0
22833 }
22834 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22835
22836 test_272f() {
22837         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22838                 skip "Need MDS version at least 2.12.55"
22839
22840         local dom=$DIR/$tdir/$tfile
22841         mkdir -p $DIR/$tdir
22842         $LFS setstripe -c 2 $dom
22843
22844         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22845                 error "failed to write data into $dom"
22846         local old_md5=$(md5sum $dom)
22847         cancel_lru_locks
22848
22849         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22850                 error "failed migrating to the DOM file"
22851
22852         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22853                 error "MDT stripe wasn't set"
22854
22855         cancel_lru_locks
22856         local new_md5=$(md5sum $dom)
22857         [ "$old_md5" != "$new_md5" ] &&
22858                 error "$old_md5 != $new_md5"
22859
22860         return 0
22861 }
22862 run_test 272f "DoM migration: OST-striped file to DOM file"
22863
22864 test_273a() {
22865         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22866                 skip "Need MDS version at least 2.11.50"
22867
22868         # Layout swap cannot be done if either file has DOM component,
22869         # this will never be supported, migration should be used instead
22870
22871         local dom=$DIR/$tdir/$tfile
22872         mkdir -p $DIR/$tdir
22873
22874         $LFS setstripe -c2 ${dom}_plain
22875         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22876         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22877                 error "can swap layout with DoM component"
22878         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22879                 error "can swap layout with DoM component"
22880
22881         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22882         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22883                 error "can swap layout with DoM component"
22884         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22885                 error "can swap layout with DoM component"
22886         return 0
22887 }
22888 run_test 273a "DoM: layout swapping should fail with DOM"
22889
22890 test_273b() {
22891         mkdir -p $DIR/$tdir
22892         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22893
22894 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22895         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22896
22897         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22898 }
22899 run_test 273b "DoM: race writeback and object destroy"
22900
22901 test_275() {
22902         remote_ost_nodsh && skip "remote OST with nodsh"
22903         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22904                 skip "Need OST version >= 2.10.57"
22905
22906         local file=$DIR/$tfile
22907         local oss
22908
22909         oss=$(comma_list $(osts_nodes))
22910
22911         dd if=/dev/urandom of=$file bs=1M count=2 ||
22912                 error "failed to create a file"
22913         cancel_lru_locks osc
22914
22915         #lock 1
22916         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22917                 error "failed to read a file"
22918
22919 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22920         $LCTL set_param fail_loc=0x8000031f
22921
22922         cancel_lru_locks osc &
22923         sleep 1
22924
22925 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22926         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22927         #IO takes another lock, but matches the PENDING one
22928         #and places it to the IO RPC
22929         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22930                 error "failed to read a file with PENDING lock"
22931 }
22932 run_test 275 "Read on a canceled duplicate lock"
22933
22934 test_276() {
22935         remote_ost_nodsh && skip "remote OST with nodsh"
22936         local pid
22937
22938         do_facet ost1 "(while true; do \
22939                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22940                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22941         pid=$!
22942
22943         for LOOP in $(seq 20); do
22944                 stop ost1
22945                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22946         done
22947         kill -9 $pid
22948         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22949                 rm $TMP/sanity_276_pid"
22950 }
22951 run_test 276 "Race between mount and obd_statfs"
22952
22953 test_277() {
22954         $LCTL set_param ldlm.namespaces.*.lru_size=0
22955         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22956         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22957                         grep ^used_mb | awk '{print $2}')
22958         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22959         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22960                 oflag=direct conv=notrunc
22961         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22962                         grep ^used_mb | awk '{print $2}')
22963         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22964 }
22965 run_test 277 "Direct IO shall drop page cache"
22966
22967 test_278() {
22968         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22969         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22970         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22971                 skip "needs the same host for mdt1 mdt2" && return
22972
22973         local pid1
22974         local pid2
22975
22976 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22977         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22978         stop mds2 &
22979         pid2=$!
22980
22981         stop mds1
22982
22983         echo "Starting MDTs"
22984         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22985         wait $pid2
22986 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22987 #will return NULL
22988         do_facet mds2 $LCTL set_param fail_loc=0
22989
22990         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22991         wait_recovery_complete mds2
22992 }
22993 run_test 278 "Race starting MDS between MDTs stop/start"
22994
22995 test_280() {
22996         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22997                 skip "Need MGS version at least 2.13.52"
22998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22999         combined_mgs_mds || skip "needs combined MGS/MDT"
23000
23001         umount_client $MOUNT
23002 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23003         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23004
23005         mount_client $MOUNT &
23006         sleep 1
23007         stop mgs || error "stop mgs failed"
23008         #for a race mgs would crash
23009         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23010         # make sure we unmount client before remounting
23011         wait
23012         umount_client $MOUNT
23013         mount_client $MOUNT || error "mount client failed"
23014 }
23015 run_test 280 "Race between MGS umount and client llog processing"
23016
23017 cleanup_test_300() {
23018         trap 0
23019         umask $SAVE_UMASK
23020 }
23021 test_striped_dir() {
23022         local mdt_index=$1
23023         local stripe_count
23024         local stripe_index
23025
23026         mkdir -p $DIR/$tdir
23027
23028         SAVE_UMASK=$(umask)
23029         trap cleanup_test_300 RETURN EXIT
23030
23031         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23032                                                 $DIR/$tdir/striped_dir ||
23033                 error "set striped dir error"
23034
23035         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23036         [ "$mode" = "755" ] || error "expect 755 got $mode"
23037
23038         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23039                 error "getdirstripe failed"
23040         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23041         if [ "$stripe_count" != "2" ]; then
23042                 error "1:stripe_count is $stripe_count, expect 2"
23043         fi
23044         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23045         if [ "$stripe_count" != "2" ]; then
23046                 error "2:stripe_count is $stripe_count, expect 2"
23047         fi
23048
23049         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23050         if [ "$stripe_index" != "$mdt_index" ]; then
23051                 error "stripe_index is $stripe_index, expect $mdt_index"
23052         fi
23053
23054         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23055                 error "nlink error after create striped dir"
23056
23057         mkdir $DIR/$tdir/striped_dir/a
23058         mkdir $DIR/$tdir/striped_dir/b
23059
23060         stat $DIR/$tdir/striped_dir/a ||
23061                 error "create dir under striped dir failed"
23062         stat $DIR/$tdir/striped_dir/b ||
23063                 error "create dir under striped dir failed"
23064
23065         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23066                 error "nlink error after mkdir"
23067
23068         rmdir $DIR/$tdir/striped_dir/a
23069         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23070                 error "nlink error after rmdir"
23071
23072         rmdir $DIR/$tdir/striped_dir/b
23073         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23074                 error "nlink error after rmdir"
23075
23076         chattr +i $DIR/$tdir/striped_dir
23077         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23078                 error "immutable flags not working under striped dir!"
23079         chattr -i $DIR/$tdir/striped_dir
23080
23081         rmdir $DIR/$tdir/striped_dir ||
23082                 error "rmdir striped dir error"
23083
23084         cleanup_test_300
23085
23086         true
23087 }
23088
23089 test_300a() {
23090         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23091                 skip "skipped for lustre < 2.7.0"
23092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23093         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23094
23095         test_striped_dir 0 || error "failed on striped dir on MDT0"
23096         test_striped_dir 1 || error "failed on striped dir on MDT0"
23097 }
23098 run_test 300a "basic striped dir sanity test"
23099
23100 test_300b() {
23101         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23102                 skip "skipped for lustre < 2.7.0"
23103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23104         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23105
23106         local i
23107         local mtime1
23108         local mtime2
23109         local mtime3
23110
23111         test_mkdir $DIR/$tdir || error "mkdir fail"
23112         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23113                 error "set striped dir error"
23114         for i in {0..9}; do
23115                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23116                 sleep 1
23117                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23118                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23119                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23120                 sleep 1
23121                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23122                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23123                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23124         done
23125         true
23126 }
23127 run_test 300b "check ctime/mtime for striped dir"
23128
23129 test_300c() {
23130         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23131                 skip "skipped for lustre < 2.7.0"
23132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23133         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23134
23135         local file_count
23136
23137         mkdir_on_mdt0 $DIR/$tdir
23138         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23139                 error "set striped dir error"
23140
23141         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23142                 error "chown striped dir failed"
23143
23144         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23145                 error "create 5k files failed"
23146
23147         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23148
23149         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23150
23151         rm -rf $DIR/$tdir
23152 }
23153 run_test 300c "chown && check ls under striped directory"
23154
23155 test_300d() {
23156         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23157                 skip "skipped for lustre < 2.7.0"
23158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23159         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23160
23161         local stripe_count
23162         local file
23163
23164         mkdir -p $DIR/$tdir
23165         $LFS setstripe -c 2 $DIR/$tdir
23166
23167         #local striped directory
23168         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23169                 error "set striped dir error"
23170         #look at the directories for debug purposes
23171         ls -l $DIR/$tdir
23172         $LFS getdirstripe $DIR/$tdir
23173         ls -l $DIR/$tdir/striped_dir
23174         $LFS getdirstripe $DIR/$tdir/striped_dir
23175         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23176                 error "create 10 files failed"
23177
23178         #remote striped directory
23179         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23180                 error "set striped dir error"
23181         #look at the directories for debug purposes
23182         ls -l $DIR/$tdir
23183         $LFS getdirstripe $DIR/$tdir
23184         ls -l $DIR/$tdir/remote_striped_dir
23185         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23186         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23187                 error "create 10 files failed"
23188
23189         for file in $(find $DIR/$tdir); do
23190                 stripe_count=$($LFS getstripe -c $file)
23191                 [ $stripe_count -eq 2 ] ||
23192                         error "wrong stripe $stripe_count for $file"
23193         done
23194
23195         rm -rf $DIR/$tdir
23196 }
23197 run_test 300d "check default stripe under striped directory"
23198
23199 test_300e() {
23200         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23201                 skip "Need MDS version at least 2.7.55"
23202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23203         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23204
23205         local stripe_count
23206         local file
23207
23208         mkdir -p $DIR/$tdir
23209
23210         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23211                 error "set striped dir error"
23212
23213         touch $DIR/$tdir/striped_dir/a
23214         touch $DIR/$tdir/striped_dir/b
23215         touch $DIR/$tdir/striped_dir/c
23216
23217         mkdir $DIR/$tdir/striped_dir/dir_a
23218         mkdir $DIR/$tdir/striped_dir/dir_b
23219         mkdir $DIR/$tdir/striped_dir/dir_c
23220
23221         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23222                 error "set striped adir under striped dir error"
23223
23224         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23225                 error "set striped bdir under striped dir error"
23226
23227         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23228                 error "set striped cdir under striped dir error"
23229
23230         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23231                 error "rename dir under striped dir fails"
23232
23233         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23234                 error "rename dir under different stripes fails"
23235
23236         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23237                 error "rename file under striped dir should succeed"
23238
23239         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23240                 error "rename dir under striped dir should succeed"
23241
23242         rm -rf $DIR/$tdir
23243 }
23244 run_test 300e "check rename under striped directory"
23245
23246 test_300f() {
23247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23248         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23249         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23250                 skip "Need MDS version at least 2.7.55"
23251
23252         local stripe_count
23253         local file
23254
23255         rm -rf $DIR/$tdir
23256         mkdir -p $DIR/$tdir
23257
23258         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23259                 error "set striped dir error"
23260
23261         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23262                 error "set striped dir error"
23263
23264         touch $DIR/$tdir/striped_dir/a
23265         mkdir $DIR/$tdir/striped_dir/dir_a
23266         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23267                 error "create striped dir under striped dir fails"
23268
23269         touch $DIR/$tdir/striped_dir1/b
23270         mkdir $DIR/$tdir/striped_dir1/dir_b
23271         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23272                 error "create striped dir under striped dir fails"
23273
23274         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23275                 error "rename dir under different striped dir should fail"
23276
23277         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23278                 error "rename striped dir under diff striped dir should fail"
23279
23280         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23281                 error "rename file under diff striped dirs fails"
23282
23283         rm -rf $DIR/$tdir
23284 }
23285 run_test 300f "check rename cross striped directory"
23286
23287 test_300_check_default_striped_dir()
23288 {
23289         local dirname=$1
23290         local default_count=$2
23291         local default_index=$3
23292         local stripe_count
23293         local stripe_index
23294         local dir_stripe_index
23295         local dir
23296
23297         echo "checking $dirname $default_count $default_index"
23298         $LFS setdirstripe -D -c $default_count -i $default_index \
23299                                 -H all_char $DIR/$tdir/$dirname ||
23300                 error "set default stripe on striped dir error"
23301         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23302         [ $stripe_count -eq $default_count ] ||
23303                 error "expect $default_count get $stripe_count for $dirname"
23304
23305         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23306         [ $stripe_index -eq $default_index ] ||
23307                 error "expect $default_index get $stripe_index for $dirname"
23308
23309         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23310                                                 error "create dirs failed"
23311
23312         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23313         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23314         for dir in $(find $DIR/$tdir/$dirname/*); do
23315                 stripe_count=$($LFS getdirstripe -c $dir)
23316                 (( $stripe_count == $default_count )) ||
23317                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23318                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23319                 error "stripe count $default_count != $stripe_count for $dir"
23320
23321                 stripe_index=$($LFS getdirstripe -i $dir)
23322                 [ $default_index -eq -1 ] ||
23323                         [ $stripe_index -eq $default_index ] ||
23324                         error "$stripe_index != $default_index for $dir"
23325
23326                 #check default stripe
23327                 stripe_count=$($LFS getdirstripe -D -c $dir)
23328                 [ $stripe_count -eq $default_count ] ||
23329                 error "default count $default_count != $stripe_count for $dir"
23330
23331                 stripe_index=$($LFS getdirstripe -D -i $dir)
23332                 [ $stripe_index -eq $default_index ] ||
23333                 error "default index $default_index != $stripe_index for $dir"
23334         done
23335         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23336 }
23337
23338 test_300g() {
23339         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23340         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23341                 skip "Need MDS version at least 2.7.55"
23342
23343         local dir
23344         local stripe_count
23345         local stripe_index
23346
23347         mkdir_on_mdt0 $DIR/$tdir
23348         mkdir $DIR/$tdir/normal_dir
23349
23350         #Checking when client cache stripe index
23351         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23352         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23353                 error "create striped_dir failed"
23354
23355         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23356                 error "create dir0 fails"
23357         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23358         [ $stripe_index -eq 0 ] ||
23359                 error "dir0 expect index 0 got $stripe_index"
23360
23361         mkdir $DIR/$tdir/striped_dir/dir1 ||
23362                 error "create dir1 fails"
23363         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23364         [ $stripe_index -eq 1 ] ||
23365                 error "dir1 expect index 1 got $stripe_index"
23366
23367         #check default stripe count/stripe index
23368         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23369         test_300_check_default_striped_dir normal_dir 1 0
23370         test_300_check_default_striped_dir normal_dir -1 1
23371         test_300_check_default_striped_dir normal_dir 2 -1
23372
23373         #delete default stripe information
23374         echo "delete default stripeEA"
23375         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23376                 error "set default stripe on striped dir error"
23377
23378         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23379         for dir in $(find $DIR/$tdir/normal_dir/*); do
23380                 stripe_count=$($LFS getdirstripe -c $dir)
23381                 [ $stripe_count -eq 0 ] ||
23382                         error "expect 1 get $stripe_count for $dir"
23383         done
23384 }
23385 run_test 300g "check default striped directory for normal directory"
23386
23387 test_300h() {
23388         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23389         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23390                 skip "Need MDS version at least 2.7.55"
23391
23392         local dir
23393         local stripe_count
23394
23395         mkdir $DIR/$tdir
23396         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23397                 error "set striped dir error"
23398
23399         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23400         test_300_check_default_striped_dir striped_dir 1 0
23401         test_300_check_default_striped_dir striped_dir -1 1
23402         test_300_check_default_striped_dir striped_dir 2 -1
23403
23404         #delete default stripe information
23405         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23406                 error "set default stripe on striped dir error"
23407
23408         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23409         for dir in $(find $DIR/$tdir/striped_dir/*); do
23410                 stripe_count=$($LFS getdirstripe -c $dir)
23411                 [ $stripe_count -eq 0 ] ||
23412                         error "expect 1 get $stripe_count for $dir"
23413         done
23414 }
23415 run_test 300h "check default striped directory for striped directory"
23416
23417 test_300i() {
23418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23419         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23420         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23421                 skip "Need MDS version at least 2.7.55"
23422
23423         local stripe_count
23424         local file
23425
23426         mkdir $DIR/$tdir
23427
23428         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23429                 error "set striped dir error"
23430
23431         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23432                 error "create files under striped dir failed"
23433
23434         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23435                 error "set striped hashdir error"
23436
23437         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23438                 error "create dir0 under hash dir failed"
23439         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23440                 error "create dir1 under hash dir failed"
23441         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23442                 error "create dir2 under hash dir failed"
23443
23444         # unfortunately, we need to umount to clear dir layout cache for now
23445         # once we fully implement dir layout, we can drop this
23446         umount_client $MOUNT || error "umount failed"
23447         mount_client $MOUNT || error "mount failed"
23448
23449         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23450         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23451         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23452
23453         #set the stripe to be unknown hash type
23454         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23455         $LCTL set_param fail_loc=0x1901
23456         for ((i = 0; i < 10; i++)); do
23457                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23458                         error "stat f-$i failed"
23459                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23460         done
23461
23462         touch $DIR/$tdir/striped_dir/f0 &&
23463                 error "create under striped dir with unknown hash should fail"
23464
23465         $LCTL set_param fail_loc=0
23466
23467         umount_client $MOUNT || error "umount failed"
23468         mount_client $MOUNT || error "mount failed"
23469
23470         return 0
23471 }
23472 run_test 300i "client handle unknown hash type striped directory"
23473
23474 test_300j() {
23475         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23477         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23478                 skip "Need MDS version at least 2.7.55"
23479
23480         local stripe_count
23481         local file
23482
23483         mkdir $DIR/$tdir
23484
23485         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23486         $LCTL set_param fail_loc=0x1702
23487         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23488                 error "set striped dir error"
23489
23490         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23491                 error "create files under striped dir failed"
23492
23493         $LCTL set_param fail_loc=0
23494
23495         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23496
23497         return 0
23498 }
23499 run_test 300j "test large update record"
23500
23501 test_300k() {
23502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23503         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23504         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23505                 skip "Need MDS version at least 2.7.55"
23506
23507         # this test needs a huge transaction
23508         local kb
23509         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23510              osd*.$FSNAME-MDT0000.kbytestotal")
23511         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23512
23513         local stripe_count
23514         local file
23515
23516         mkdir $DIR/$tdir
23517
23518         #define OBD_FAIL_LARGE_STRIPE   0x1703
23519         $LCTL set_param fail_loc=0x1703
23520         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23521                 error "set striped dir error"
23522         $LCTL set_param fail_loc=0
23523
23524         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23525                 error "getstripeddir fails"
23526         rm -rf $DIR/$tdir/striped_dir ||
23527                 error "unlink striped dir fails"
23528
23529         return 0
23530 }
23531 run_test 300k "test large striped directory"
23532
23533 test_300l() {
23534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23535         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23536         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23537                 skip "Need MDS version at least 2.7.55"
23538
23539         local stripe_index
23540
23541         test_mkdir -p $DIR/$tdir/striped_dir
23542         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23543                         error "chown $RUNAS_ID failed"
23544         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23545                 error "set default striped dir failed"
23546
23547         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23548         $LCTL set_param fail_loc=0x80000158
23549         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23550
23551         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23552         [ $stripe_index -eq 1 ] ||
23553                 error "expect 1 get $stripe_index for $dir"
23554 }
23555 run_test 300l "non-root user to create dir under striped dir with stale layout"
23556
23557 test_300m() {
23558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23559         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23560         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23561                 skip "Need MDS version at least 2.7.55"
23562
23563         mkdir -p $DIR/$tdir/striped_dir
23564         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23565                 error "set default stripes dir error"
23566
23567         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23568
23569         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23570         [ $stripe_count -eq 0 ] ||
23571                         error "expect 0 get $stripe_count for a"
23572
23573         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23574                 error "set default stripes dir error"
23575
23576         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23577
23578         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23579         [ $stripe_count -eq 0 ] ||
23580                         error "expect 0 get $stripe_count for b"
23581
23582         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23583                 error "set default stripes dir error"
23584
23585         mkdir $DIR/$tdir/striped_dir/c &&
23586                 error "default stripe_index is invalid, mkdir c should fails"
23587
23588         rm -rf $DIR/$tdir || error "rmdir fails"
23589 }
23590 run_test 300m "setstriped directory on single MDT FS"
23591
23592 cleanup_300n() {
23593         local list=$(comma_list $(mdts_nodes))
23594
23595         trap 0
23596         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23597 }
23598
23599 test_300n() {
23600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23601         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23602         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23603                 skip "Need MDS version at least 2.7.55"
23604         remote_mds_nodsh && skip "remote MDS with nodsh"
23605
23606         local stripe_index
23607         local list=$(comma_list $(mdts_nodes))
23608
23609         trap cleanup_300n RETURN EXIT
23610         mkdir -p $DIR/$tdir
23611         chmod 777 $DIR/$tdir
23612         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23613                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23614                 error "create striped dir succeeds with gid=0"
23615
23616         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23617         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23618                 error "create striped dir fails with gid=-1"
23619
23620         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23621         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23622                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23623                 error "set default striped dir succeeds with gid=0"
23624
23625
23626         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23627         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23628                 error "set default striped dir fails with gid=-1"
23629
23630
23631         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23632         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23633                                         error "create test_dir fails"
23634         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23635                                         error "create test_dir1 fails"
23636         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23637                                         error "create test_dir2 fails"
23638         cleanup_300n
23639 }
23640 run_test 300n "non-root user to create dir under striped dir with default EA"
23641
23642 test_300o() {
23643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23644         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23645         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23646                 skip "Need MDS version at least 2.7.55"
23647
23648         local numfree1
23649         local numfree2
23650
23651         mkdir -p $DIR/$tdir
23652
23653         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23654         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23655         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23656                 skip "not enough free inodes $numfree1 $numfree2"
23657         fi
23658
23659         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23660         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23661         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23662                 skip "not enough free space $numfree1 $numfree2"
23663         fi
23664
23665         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23666                 error "setdirstripe fails"
23667
23668         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23669                 error "create dirs fails"
23670
23671         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23672         ls $DIR/$tdir/striped_dir > /dev/null ||
23673                 error "ls striped dir fails"
23674         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23675                 error "unlink big striped dir fails"
23676 }
23677 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23678
23679 test_300p() {
23680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23681         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23682         remote_mds_nodsh && skip "remote MDS with nodsh"
23683
23684         mkdir_on_mdt0 $DIR/$tdir
23685
23686         #define OBD_FAIL_OUT_ENOSPC     0x1704
23687         do_facet mds2 lctl set_param fail_loc=0x80001704
23688         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23689                  && error "create striped directory should fail"
23690
23691         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23692
23693         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23694         true
23695 }
23696 run_test 300p "create striped directory without space"
23697
23698 test_300q() {
23699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23700         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23701
23702         local fd=$(free_fd)
23703         local cmd="exec $fd<$tdir"
23704         cd $DIR
23705         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23706         eval $cmd
23707         cmd="exec $fd<&-"
23708         trap "eval $cmd" EXIT
23709         cd $tdir || error "cd $tdir fails"
23710         rmdir  ../$tdir || error "rmdir $tdir fails"
23711         mkdir local_dir && error "create dir succeeds"
23712         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23713         eval $cmd
23714         return 0
23715 }
23716 run_test 300q "create remote directory under orphan directory"
23717
23718 test_300r() {
23719         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23720                 skip "Need MDS version at least 2.7.55" && return
23721         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23722
23723         mkdir $DIR/$tdir
23724
23725         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23726                 error "set striped dir error"
23727
23728         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23729                 error "getstripeddir fails"
23730
23731         local stripe_count
23732         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23733                       awk '/lmv_stripe_count:/ { print $2 }')
23734
23735         [ $MDSCOUNT -ne $stripe_count ] &&
23736                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23737
23738         rm -rf $DIR/$tdir/striped_dir ||
23739                 error "unlink striped dir fails"
23740 }
23741 run_test 300r "test -1 striped directory"
23742
23743 test_300s_helper() {
23744         local count=$1
23745
23746         local stripe_dir=$DIR/$tdir/striped_dir.$count
23747
23748         $LFS mkdir -c $count $stripe_dir ||
23749                 error "lfs mkdir -c error"
23750
23751         $LFS getdirstripe $stripe_dir ||
23752                 error "lfs getdirstripe fails"
23753
23754         local stripe_count
23755         stripe_count=$($LFS getdirstripe $stripe_dir |
23756                       awk '/lmv_stripe_count:/ { print $2 }')
23757
23758         [ $count -ne $stripe_count ] &&
23759                 error_noexit "bad stripe count $stripe_count expected $count"
23760
23761         local dupe_stripes
23762         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23763                 awk '/0x/ {count[$1] += 1}; END {
23764                         for (idx in count) {
23765                                 if (count[idx]>1) {
23766                                         print "index " idx " count " count[idx]
23767                                 }
23768                         }
23769                 }')
23770
23771         if [[ -n "$dupe_stripes" ]] ; then
23772                 lfs getdirstripe $stripe_dir
23773                 error_noexit "Dupe MDT above: $dupe_stripes "
23774         fi
23775
23776         rm -rf $stripe_dir ||
23777                 error_noexit "unlink $stripe_dir fails"
23778 }
23779
23780 test_300s() {
23781         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23782                 skip "Need MDS version at least 2.7.55" && return
23783         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23784
23785         mkdir $DIR/$tdir
23786         for count in $(seq 2 $MDSCOUNT); do
23787                 test_300s_helper $count
23788         done
23789 }
23790 run_test 300s "test lfs mkdir -c without -i"
23791
23792 test_300t() {
23793         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
23794                 skip "need MDS 2.14.55 or later"
23795         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
23796
23797         local testdir="$DIR/$tdir/striped_dir"
23798         local dir1=$testdir/dir1
23799         local dir2=$testdir/dir2
23800
23801         mkdir -p $testdir
23802
23803         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
23804                 error "failed to set default stripe count for $testdir"
23805
23806         mkdir $dir1
23807         local stripe_count=$($LFS getdirstripe -c $dir1)
23808
23809         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
23810
23811         local max_count=$((MDSCOUNT - 1))
23812         local mdts=$(comma_list $(mdts_nodes))
23813
23814         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
23815         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
23816
23817         mkdir $dir2
23818         stripe_count=$($LFS getdirstripe -c $dir2)
23819
23820         (( $stripe_count == $max_count )) || error "wrong stripe count"
23821 }
23822 run_test 300t "test max_mdt_stripecount"
23823
23824 prepare_remote_file() {
23825         mkdir $DIR/$tdir/src_dir ||
23826                 error "create remote source failed"
23827
23828         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23829                  error "cp to remote source failed"
23830         touch $DIR/$tdir/src_dir/a
23831
23832         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23833                 error "create remote target dir failed"
23834
23835         touch $DIR/$tdir/tgt_dir/b
23836
23837         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23838                 error "rename dir cross MDT failed!"
23839
23840         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23841                 error "src_child still exists after rename"
23842
23843         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23844                 error "missing file(a) after rename"
23845
23846         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23847                 error "diff after rename"
23848 }
23849
23850 test_310a() {
23851         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23853
23854         local remote_file=$DIR/$tdir/tgt_dir/b
23855
23856         mkdir -p $DIR/$tdir
23857
23858         prepare_remote_file || error "prepare remote file failed"
23859
23860         #open-unlink file
23861         $OPENUNLINK $remote_file $remote_file ||
23862                 error "openunlink $remote_file failed"
23863         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23864 }
23865 run_test 310a "open unlink remote file"
23866
23867 test_310b() {
23868         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23870
23871         local remote_file=$DIR/$tdir/tgt_dir/b
23872
23873         mkdir -p $DIR/$tdir
23874
23875         prepare_remote_file || error "prepare remote file failed"
23876
23877         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23878         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23879         $CHECKSTAT -t file $remote_file || error "check file failed"
23880 }
23881 run_test 310b "unlink remote file with multiple links while open"
23882
23883 test_310c() {
23884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23885         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23886
23887         local remote_file=$DIR/$tdir/tgt_dir/b
23888
23889         mkdir -p $DIR/$tdir
23890
23891         prepare_remote_file || error "prepare remote file failed"
23892
23893         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23894         multiop_bg_pause $remote_file O_uc ||
23895                         error "mulitop failed for remote file"
23896         MULTIPID=$!
23897         $MULTIOP $DIR/$tfile Ouc
23898         kill -USR1 $MULTIPID
23899         wait $MULTIPID
23900 }
23901 run_test 310c "open-unlink remote file with multiple links"
23902
23903 #LU-4825
23904 test_311() {
23905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23906         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23907         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23908                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23909         remote_mds_nodsh && skip "remote MDS with nodsh"
23910
23911         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23912         local mdts=$(comma_list $(mdts_nodes))
23913
23914         mkdir -p $DIR/$tdir
23915         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23916         createmany -o $DIR/$tdir/$tfile. 1000
23917
23918         # statfs data is not real time, let's just calculate it
23919         old_iused=$((old_iused + 1000))
23920
23921         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23922                         osp.*OST0000*MDT0000.create_count")
23923         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23924                                 osp.*OST0000*MDT0000.max_create_count")
23925         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23926
23927         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23928         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23929         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23930
23931         unlinkmany $DIR/$tdir/$tfile. 1000
23932
23933         do_nodes $mdts "$LCTL set_param -n \
23934                         osp.*OST0000*.max_create_count=$max_count"
23935         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23936                 do_nodes $mdts "$LCTL set_param -n \
23937                                 osp.*OST0000*.create_count=$count"
23938         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23939                         grep "=0" && error "create_count is zero"
23940
23941         local new_iused
23942         for i in $(seq 120); do
23943                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23944                 # system may be too busy to destroy all objs in time, use
23945                 # a somewhat small value to not fail autotest
23946                 [ $((old_iused - new_iused)) -gt 400 ] && break
23947                 sleep 1
23948         done
23949
23950         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23951         [ $((old_iused - new_iused)) -gt 400 ] ||
23952                 error "objs not destroyed after unlink"
23953 }
23954 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23955
23956 zfs_oid_to_objid()
23957 {
23958         local ost=$1
23959         local objid=$2
23960
23961         local vdevdir=$(dirname $(facet_vdevice $ost))
23962         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23963         local zfs_zapid=$(do_facet $ost $cmd |
23964                           grep -w "/O/0/d$((objid%32))" -C 5 |
23965                           awk '/Object/{getline; print $1}')
23966         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23967                           awk "/$objid = /"'{printf $3}')
23968
23969         echo $zfs_objid
23970 }
23971
23972 zfs_object_blksz() {
23973         local ost=$1
23974         local objid=$2
23975
23976         local vdevdir=$(dirname $(facet_vdevice $ost))
23977         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23978         local blksz=$(do_facet $ost $cmd $objid |
23979                       awk '/dblk/{getline; printf $4}')
23980
23981         case "${blksz: -1}" in
23982                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23983                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23984                 *) ;;
23985         esac
23986
23987         echo $blksz
23988 }
23989
23990 test_312() { # LU-4856
23991         remote_ost_nodsh && skip "remote OST with nodsh"
23992         [ "$ost1_FSTYPE" = "zfs" ] ||
23993                 skip_env "the test only applies to zfs"
23994
23995         local max_blksz=$(do_facet ost1 \
23996                           $ZFS get -p recordsize $(facet_device ost1) |
23997                           awk '!/VALUE/{print $3}')
23998
23999         # to make life a little bit easier
24000         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24001         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24002
24003         local tf=$DIR/$tdir/$tfile
24004         touch $tf
24005         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24006
24007         # Get ZFS object id
24008         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24009         # block size change by sequential overwrite
24010         local bs
24011
24012         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24013                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24014
24015                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24016                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24017         done
24018         rm -f $tf
24019
24020         # block size change by sequential append write
24021         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24022         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24023         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24024         local count
24025
24026         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24027                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24028                         oflag=sync conv=notrunc
24029
24030                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24031                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24032                         error "blksz error, actual $blksz, " \
24033                                 "expected: 2 * $count * $PAGE_SIZE"
24034         done
24035         rm -f $tf
24036
24037         # random write
24038         touch $tf
24039         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24040         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24041
24042         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24043         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24044         [ $blksz -eq $PAGE_SIZE ] ||
24045                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24046
24047         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24048         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24049         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24050
24051         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24052         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24053         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24054 }
24055 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24056
24057 test_313() {
24058         remote_ost_nodsh && skip "remote OST with nodsh"
24059
24060         local file=$DIR/$tfile
24061
24062         rm -f $file
24063         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24064
24065         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24066         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24067         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24068                 error "write should failed"
24069         do_facet ost1 "$LCTL set_param fail_loc=0"
24070         rm -f $file
24071 }
24072 run_test 313 "io should fail after last_rcvd update fail"
24073
24074 test_314() {
24075         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24076
24077         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24078         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24079         rm -f $DIR/$tfile
24080         wait_delete_completed
24081         do_facet ost1 "$LCTL set_param fail_loc=0"
24082 }
24083 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24084
24085 test_315() { # LU-618
24086         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24087
24088         local file=$DIR/$tfile
24089         rm -f $file
24090
24091         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24092                 error "multiop file write failed"
24093         $MULTIOP $file oO_RDONLY:r4063232_c &
24094         PID=$!
24095
24096         sleep 2
24097
24098         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24099         kill -USR1 $PID
24100
24101         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24102         rm -f $file
24103 }
24104 run_test 315 "read should be accounted"
24105
24106 test_316() {
24107         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24108         large_xattr_enabled || skip_env "ea_inode feature disabled"
24109
24110         rm -rf $DIR/$tdir/d
24111         mkdir -p $DIR/$tdir/d
24112         chown nobody $DIR/$tdir/d
24113         touch $DIR/$tdir/d/file
24114
24115         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
24116 }
24117 run_test 316 "lfs mv"
24118
24119 test_317() {
24120         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24121                 skip "Need MDS version at least 2.11.53"
24122         if [ "$ost1_FSTYPE" == "zfs" ]; then
24123                 skip "LU-10370: no implementation for ZFS"
24124         fi
24125
24126         local trunc_sz
24127         local grant_blk_size
24128
24129         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24130                         awk '/grant_block_size:/ { print $2; exit; }')
24131         #
24132         # Create File of size 5M. Truncate it to below size's and verify
24133         # blocks count.
24134         #
24135         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24136                 error "Create file $DIR/$tfile failed"
24137         stack_trap "rm -f $DIR/$tfile" EXIT
24138
24139         for trunc_sz in 2097152 4097 4000 509 0; do
24140                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24141                         error "truncate $tfile to $trunc_sz failed"
24142                 local sz=$(stat --format=%s $DIR/$tfile)
24143                 local blk=$(stat --format=%b $DIR/$tfile)
24144                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24145                                      grant_blk_size) * 8))
24146
24147                 if [[ $blk -ne $trunc_blk ]]; then
24148                         $(which stat) $DIR/$tfile
24149                         error "Expected Block $trunc_blk got $blk for $tfile"
24150                 fi
24151
24152                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24153                         error "Expected Size $trunc_sz got $sz for $tfile"
24154         done
24155
24156         #
24157         # sparse file test
24158         # Create file with a hole and write actual 65536 bytes which aligned
24159         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24160         #
24161         local bs=65536
24162         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24163                 error "Create file : $DIR/$tfile"
24164
24165         #
24166         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24167         # blocks. The block count must drop to 8.
24168         #
24169         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - \
24170                 ((bs - grant_blk_size) + 1)))
24171         $TRUNCATE $DIR/$tfile $trunc_sz ||
24172                 error "truncate $tfile to $trunc_sz failed"
24173
24174         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24175         sz=$(stat --format=%s $DIR/$tfile)
24176         blk=$(stat --format=%b $DIR/$tfile)
24177
24178         if [[ $blk -ne $trunc_bsz ]]; then
24179                 $(which stat) $DIR/$tfile
24180                 error "Expected Block $trunc_bsz got $blk for $tfile"
24181         fi
24182
24183         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24184                 error "Expected Size $trunc_sz got $sz for $tfile"
24185 }
24186 run_test 317 "Verify blocks get correctly update after truncate"
24187
24188 test_318() {
24189         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24190         local old_max_active=$($LCTL get_param -n \
24191                             ${llite_name}.max_read_ahead_async_active \
24192                             2>/dev/null)
24193
24194         $LCTL set_param llite.*.max_read_ahead_async_active=256
24195         local max_active=$($LCTL get_param -n \
24196                            ${llite_name}.max_read_ahead_async_active \
24197                            2>/dev/null)
24198         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24199
24200         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24201                 error "set max_read_ahead_async_active should succeed"
24202
24203         $LCTL set_param llite.*.max_read_ahead_async_active=512
24204         max_active=$($LCTL get_param -n \
24205                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24206         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24207
24208         # restore @max_active
24209         [ $old_max_active -ne 0 ] && $LCTL set_param \
24210                 llite.*.max_read_ahead_async_active=$old_max_active
24211
24212         local old_threshold=$($LCTL get_param -n \
24213                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24214         local max_per_file_mb=$($LCTL get_param -n \
24215                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24216
24217         local invalid=$(($max_per_file_mb + 1))
24218         $LCTL set_param \
24219                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24220                         && error "set $invalid should fail"
24221
24222         local valid=$(($invalid - 1))
24223         $LCTL set_param \
24224                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24225                         error "set $valid should succeed"
24226         local threshold=$($LCTL get_param -n \
24227                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24228         [ $threshold -eq $valid ] || error \
24229                 "expect threshold $valid got $threshold"
24230         $LCTL set_param \
24231                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24232 }
24233 run_test 318 "Verify async readahead tunables"
24234
24235 test_319() {
24236         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
24237
24238         local before=$(date +%s)
24239         local evict
24240         local mdir=$DIR/$tdir
24241         local file=$mdir/xxx
24242
24243         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24244         touch $file
24245
24246 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24247         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24248         $LFS mv -m1 $file &
24249
24250         sleep 1
24251         dd if=$file of=/dev/null
24252         wait
24253         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24254           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24255
24256         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24257 }
24258 run_test 319 "lost lease lock on migrate error"
24259
24260 test_398a() { # LU-4198
24261         local ost1_imp=$(get_osc_import_name client ost1)
24262         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24263                          cut -d'.' -f2)
24264
24265         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24266         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24267
24268         # request a new lock on client
24269         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24270
24271         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24272         local lock_count=$($LCTL get_param -n \
24273                            ldlm.namespaces.$imp_name.lru_size)
24274         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24275
24276         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24277
24278         # no lock cached, should use lockless IO and not enqueue new lock
24279         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24280         lock_count=$($LCTL get_param -n \
24281                      ldlm.namespaces.$imp_name.lru_size)
24282         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24283 }
24284 run_test 398a "direct IO should cancel lock otherwise lockless"
24285
24286 test_398b() { # LU-4198
24287         which fio || skip_env "no fio installed"
24288         $LFS setstripe -c -1 $DIR/$tfile
24289
24290         local size=12
24291         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24292
24293         local njobs=4
24294         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
24295         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24296                 --numjobs=$njobs --fallocate=none \
24297                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24298                 --filename=$DIR/$tfile &
24299         bg_pid=$!
24300
24301         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
24302         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
24303                 --numjobs=$njobs --fallocate=none \
24304                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24305                 --filename=$DIR/$tfile || true
24306         wait $bg_pid
24307
24308         rm -f $DIR/$tfile
24309 }
24310 run_test 398b "DIO and buffer IO race"
24311
24312 test_398c() { # LU-4198
24313         local ost1_imp=$(get_osc_import_name client ost1)
24314         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24315                          cut -d'.' -f2)
24316
24317         which fio || skip_env "no fio installed"
24318
24319         saved_debug=$($LCTL get_param -n debug)
24320         $LCTL set_param debug=0
24321
24322         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24323         ((size /= 1024)) # by megabytes
24324         ((size /= 2)) # write half of the OST at most
24325         [ $size -gt 40 ] && size=40 #reduce test time anyway
24326
24327         $LFS setstripe -c 1 $DIR/$tfile
24328
24329         # it seems like ldiskfs reserves more space than necessary if the
24330         # writing blocks are not mapped, so it extends the file firstly
24331         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24332         cancel_lru_locks osc
24333
24334         # clear and verify rpc_stats later
24335         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24336
24337         local njobs=4
24338         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24339         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24340                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24341                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24342                 --filename=$DIR/$tfile
24343         [ $? -eq 0 ] || error "fio write error"
24344
24345         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24346                 error "Locks were requested while doing AIO"
24347
24348         # get the percentage of 1-page I/O
24349         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24350                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24351                 awk '{print $7}')
24352         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24353
24354         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24355         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24356                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24357                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24358                 --filename=$DIR/$tfile
24359         [ $? -eq 0 ] || error "fio mixed read write error"
24360
24361         echo "AIO with large block size ${size}M"
24362         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24363                 --numjobs=1 --fallocate=none --ioengine=libaio \
24364                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24365                 --filename=$DIR/$tfile
24366         [ $? -eq 0 ] || error "fio large block size failed"
24367
24368         rm -f $DIR/$tfile
24369         $LCTL set_param debug="$saved_debug"
24370 }
24371 run_test 398c "run fio to test AIO"
24372
24373 test_398d() { #  LU-13846
24374         which aiocp || skip_env "no aiocp installed"
24375         local aio_file=$DIR/$tfile.aio
24376
24377         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24378
24379         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24380         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24381         stack_trap "rm -f $DIR/$tfile $aio_file"
24382
24383         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24384
24385         # make sure we don't crash and fail properly
24386         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24387                 error "aio not aligned with PAGE SIZE should fail"
24388
24389         rm -f $DIR/$tfile $aio_file
24390 }
24391 run_test 398d "run aiocp to verify block size > stripe size"
24392
24393 test_398e() {
24394         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24395         touch $DIR/$tfile.new
24396         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24397 }
24398 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24399
24400 test_398f() { #  LU-14687
24401         which aiocp || skip_env "no aiocp installed"
24402         local aio_file=$DIR/$tfile.aio
24403
24404         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24405
24406         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24407         stack_trap "rm -f $DIR/$tfile $aio_file"
24408
24409         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24410         $LCTL set_param fail_loc=0x1418
24411         # make sure we don't crash and fail properly
24412         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24413                 error "aio with page allocation failure succeeded"
24414         $LCTL set_param fail_loc=0
24415         diff $DIR/$tfile $aio_file
24416         [[ $? != 0 ]] || error "no diff after failed aiocp"
24417 }
24418 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24419
24420 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24421 # stripe and i/o size must be > stripe size
24422 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24423 # single RPC in flight.  This test shows async DIO submission is working by
24424 # showing multiple RPCs in flight.
24425 test_398g() { #  LU-13798
24426         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24427
24428         # We need to do some i/o first to acquire enough grant to put our RPCs
24429         # in flight; otherwise a new connection may not have enough grant
24430         # available
24431         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24432                 error "parallel dio failed"
24433         stack_trap "rm -f $DIR/$tfile"
24434
24435         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24436         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24437         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24438         stack_trap "$LCTL set_param -n $pages_per_rpc"
24439
24440         # Recreate file so it's empty
24441         rm -f $DIR/$tfile
24442         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24443         #Pause rpc completion to guarantee we see multiple rpcs in flight
24444         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24445         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24446         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24447
24448         # Clear rpc stats
24449         $LCTL set_param osc.*.rpc_stats=c
24450
24451         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24452                 error "parallel dio failed"
24453         stack_trap "rm -f $DIR/$tfile"
24454
24455         $LCTL get_param osc.*-OST0000-*.rpc_stats
24456         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24457                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24458                 grep "8:" | awk '{print $8}')
24459         # We look at the "8 rpcs in flight" field, and verify A) it is present
24460         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24461         # as expected for an 8M DIO to a file with 1M stripes.
24462         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24463
24464         # Verify turning off parallel dio works as expected
24465         # Clear rpc stats
24466         $LCTL set_param osc.*.rpc_stats=c
24467         $LCTL set_param llite.*.parallel_dio=0
24468         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24469
24470         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24471                 error "dio with parallel dio disabled failed"
24472
24473         # Ideally, we would see only one RPC in flight here, but there is an
24474         # unavoidable race between i/o completion and RPC in flight counting,
24475         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24476         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24477         # So instead we just verify it's always < 8.
24478         $LCTL get_param osc.*-OST0000-*.rpc_stats
24479         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24480                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24481                 grep '^$' -B1 | grep . | awk '{print $1}')
24482         [ $ret != "8:" ] ||
24483                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24484 }
24485 run_test 398g "verify parallel dio async RPC submission"
24486
24487 test_398h() { #  LU-13798
24488         local dio_file=$DIR/$tfile.dio
24489
24490         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24491
24492         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24493         stack_trap "rm -f $DIR/$tfile $dio_file"
24494
24495         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24496                 error "parallel dio failed"
24497         diff $DIR/$tfile $dio_file
24498         [[ $? == 0 ]] || error "file diff after aiocp"
24499 }
24500 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24501
24502 test_398i() { #  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         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24511         $LCTL set_param fail_loc=0x1418
24512         # make sure we don't crash and fail properly
24513         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24514                 error "parallel dio page allocation failure succeeded"
24515         diff $DIR/$tfile $dio_file
24516         [[ $? != 0 ]] || error "no diff after failed aiocp"
24517 }
24518 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24519
24520 test_398j() { #  LU-13798
24521         # Stripe size > RPC size but less than i/o size tests split across
24522         # stripes and RPCs for individual i/o op
24523         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24524
24525         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24526         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24527         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24528         stack_trap "$LCTL set_param -n $pages_per_rpc"
24529
24530         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24531                 error "parallel dio write failed"
24532         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24533
24534         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24535                 error "parallel dio read failed"
24536         diff $DIR/$tfile $DIR/$tfile.2
24537         [[ $? == 0 ]] || error "file diff after parallel dio read"
24538 }
24539 run_test 398j "test parallel dio where stripe size > rpc_size"
24540
24541 test_398k() { #  LU-13798
24542         wait_delete_completed
24543         wait_mds_ost_sync
24544
24545         # 4 stripe file; we will cause out of space on OST0
24546         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24547
24548         # Fill OST0 (if it's not too large)
24549         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24550                    head -n1)
24551         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24552                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24553         fi
24554         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24555         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24556                 error "dd should fill OST0"
24557         stack_trap "rm -f $DIR/$tfile.1"
24558
24559         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24560         err=$?
24561
24562         ls -la $DIR/$tfile
24563         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24564                 error "file is not 0 bytes in size"
24565
24566         # dd above should not succeed, but don't error until here so we can
24567         # get debug info above
24568         [[ $err != 0 ]] ||
24569                 error "parallel dio write with enospc succeeded"
24570         stack_trap "rm -f $DIR/$tfile"
24571 }
24572 run_test 398k "test enospc on first stripe"
24573
24574 test_398l() { #  LU-13798
24575         wait_delete_completed
24576         wait_mds_ost_sync
24577
24578         # 4 stripe file; we will cause out of space on OST0
24579         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24580         # happens on the second i/o chunk we issue
24581         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24582
24583         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24584         stack_trap "rm -f $DIR/$tfile"
24585
24586         # Fill OST0 (if it's not too large)
24587         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24588                    head -n1)
24589         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24590                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24591         fi
24592         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24593         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24594                 error "dd should fill OST0"
24595         stack_trap "rm -f $DIR/$tfile.1"
24596
24597         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24598         err=$?
24599         stack_trap "rm -f $DIR/$tfile.2"
24600
24601         # Check that short write completed as expected
24602         ls -la $DIR/$tfile.2
24603         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24604                 error "file is not 1M in size"
24605
24606         # dd above should not succeed, but don't error until here so we can
24607         # get debug info above
24608         [[ $err != 0 ]] ||
24609                 error "parallel dio write with enospc succeeded"
24610
24611         # Truncate source file to same length as output file and diff them
24612         $TRUNCATE $DIR/$tfile 1048576
24613         diff $DIR/$tfile $DIR/$tfile.2
24614         [[ $? == 0 ]] || error "data incorrect after short write"
24615 }
24616 run_test 398l "test enospc on intermediate stripe/RPC"
24617
24618 test_398m() { #  LU-13798
24619         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24620
24621         # Set up failure on OST0, the first stripe:
24622         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24623         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24624         # So this fail_val specifies OST0
24625         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24626         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24627
24628         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24629                 error "parallel dio write with failure on first stripe succeeded"
24630         stack_trap "rm -f $DIR/$tfile"
24631         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24632
24633         # Place data in file for read
24634         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24635                 error "parallel dio write failed"
24636
24637         # Fail read on OST0, first stripe
24638         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24639         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24640         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24641                 error "parallel dio read with error on first stripe succeeded"
24642         rm -f $DIR/$tfile.2
24643         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24644
24645         # Switch to testing on OST1, second stripe
24646         # Clear file contents, maintain striping
24647         echo > $DIR/$tfile
24648         # Set up failure on OST1, second stripe:
24649         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24650         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24651
24652         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24653                 error "parallel dio write with failure on first stripe succeeded"
24654         stack_trap "rm -f $DIR/$tfile"
24655         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24656
24657         # Place data in file for read
24658         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24659                 error "parallel dio write failed"
24660
24661         # Fail read on OST1, second stripe
24662         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24663         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24664         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24665                 error "parallel dio read with error on first stripe succeeded"
24666         rm -f $DIR/$tfile.2
24667         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24668 }
24669 run_test 398m "test RPC failures with parallel dio"
24670
24671 # Parallel submission of DIO should not cause problems for append, but it's
24672 # important to verify.
24673 test_398n() { #  LU-13798
24674         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24675
24676         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24677                 error "dd to create source file failed"
24678         stack_trap "rm -f $DIR/$tfile"
24679
24680         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24681                 error "parallel dio write with failure on second stripe succeeded"
24682         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24683         diff $DIR/$tfile $DIR/$tfile.1
24684         [[ $? == 0 ]] || error "data incorrect after append"
24685
24686 }
24687 run_test 398n "test append with parallel DIO"
24688
24689 test_fake_rw() {
24690         local read_write=$1
24691         if [ "$read_write" = "write" ]; then
24692                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24693         elif [ "$read_write" = "read" ]; then
24694                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24695         else
24696                 error "argument error"
24697         fi
24698
24699         # turn off debug for performance testing
24700         local saved_debug=$($LCTL get_param -n debug)
24701         $LCTL set_param debug=0
24702
24703         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24704
24705         # get ost1 size - $FSNAME-OST0000
24706         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24707         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24708         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24709
24710         if [ "$read_write" = "read" ]; then
24711                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24712         fi
24713
24714         local start_time=$(date +%s.%N)
24715         $dd_cmd bs=1M count=$blocks oflag=sync ||
24716                 error "real dd $read_write error"
24717         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24718
24719         if [ "$read_write" = "write" ]; then
24720                 rm -f $DIR/$tfile
24721         fi
24722
24723         # define OBD_FAIL_OST_FAKE_RW           0x238
24724         do_facet ost1 $LCTL set_param fail_loc=0x238
24725
24726         local start_time=$(date +%s.%N)
24727         $dd_cmd bs=1M count=$blocks oflag=sync ||
24728                 error "fake dd $read_write error"
24729         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24730
24731         if [ "$read_write" = "write" ]; then
24732                 # verify file size
24733                 cancel_lru_locks osc
24734                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24735                         error "$tfile size not $blocks MB"
24736         fi
24737         do_facet ost1 $LCTL set_param fail_loc=0
24738
24739         echo "fake $read_write $duration_fake vs. normal $read_write" \
24740                 "$duration in seconds"
24741         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24742                 error_not_in_vm "fake write is slower"
24743
24744         $LCTL set_param -n debug="$saved_debug"
24745         rm -f $DIR/$tfile
24746 }
24747 test_399a() { # LU-7655 for OST fake write
24748         remote_ost_nodsh && skip "remote OST with nodsh"
24749
24750         test_fake_rw write
24751 }
24752 run_test 399a "fake write should not be slower than normal write"
24753
24754 test_399b() { # LU-8726 for OST fake read
24755         remote_ost_nodsh && skip "remote OST with nodsh"
24756         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24757                 skip_env "ldiskfs only test"
24758         fi
24759
24760         test_fake_rw read
24761 }
24762 run_test 399b "fake read should not be slower than normal read"
24763
24764 test_400a() { # LU-1606, was conf-sanity test_74
24765         if ! which $CC > /dev/null 2>&1; then
24766                 skip_env "$CC is not installed"
24767         fi
24768
24769         local extra_flags=''
24770         local out=$TMP/$tfile
24771         local prefix=/usr/include/lustre
24772         local prog
24773
24774         # Oleg removes c files in his test rig so test if any c files exist
24775         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24776                 skip_env "Needed c test files are missing"
24777
24778         if ! [[ -d $prefix ]]; then
24779                 # Assume we're running in tree and fixup the include path.
24780                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24781                 extra_flags+=" -L$LUSTRE/utils/.lib"
24782         fi
24783
24784         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24785                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24786                         error "client api broken"
24787         done
24788         rm -f $out
24789 }
24790 run_test 400a "Lustre client api program can compile and link"
24791
24792 test_400b() { # LU-1606, LU-5011
24793         local header
24794         local out=$TMP/$tfile
24795         local prefix=/usr/include/linux/lustre
24796
24797         # We use a hard coded prefix so that this test will not fail
24798         # when run in tree. There are headers in lustre/include/lustre/
24799         # that are not packaged (like lustre_idl.h) and have more
24800         # complicated include dependencies (like config.h and lnet/types.h).
24801         # Since this test about correct packaging we just skip them when
24802         # they don't exist (see below) rather than try to fixup cppflags.
24803
24804         if ! which $CC > /dev/null 2>&1; then
24805                 skip_env "$CC is not installed"
24806         fi
24807
24808         for header in $prefix/*.h; do
24809                 if ! [[ -f "$header" ]]; then
24810                         continue
24811                 fi
24812
24813                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24814                         continue # lustre_ioctl.h is internal header
24815                 fi
24816
24817                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24818                         error "cannot compile '$header'"
24819         done
24820         rm -f $out
24821 }
24822 run_test 400b "packaged headers can be compiled"
24823
24824 test_401a() { #LU-7437
24825         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24826         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24827
24828         #count the number of parameters by "list_param -R"
24829         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24830         #count the number of parameters by listing proc files
24831         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24832         echo "proc_dirs='$proc_dirs'"
24833         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24834         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24835                       sort -u | wc -l)
24836
24837         [ $params -eq $procs ] ||
24838                 error "found $params parameters vs. $procs proc files"
24839
24840         # test the list_param -D option only returns directories
24841         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24842         #count the number of parameters by listing proc directories
24843         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24844                 sort -u | wc -l)
24845
24846         [ $params -eq $procs ] ||
24847                 error "found $params parameters vs. $procs proc files"
24848 }
24849 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24850
24851 test_401b() {
24852         # jobid_var may not allow arbitrary values, so use jobid_name
24853         # if available
24854         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24855                 local testname=jobid_name tmp='testing%p'
24856         else
24857                 local testname=jobid_var tmp=testing
24858         fi
24859
24860         local save=$($LCTL get_param -n $testname)
24861
24862         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24863                 error "no error returned when setting bad parameters"
24864
24865         local jobid_new=$($LCTL get_param -n foe $testname baz)
24866         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24867
24868         $LCTL set_param -n fog=bam $testname=$save bat=fog
24869         local jobid_old=$($LCTL get_param -n foe $testname bag)
24870         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24871 }
24872 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24873
24874 test_401c() {
24875         # jobid_var may not allow arbitrary values, so use jobid_name
24876         # if available
24877         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24878                 local testname=jobid_name
24879         else
24880                 local testname=jobid_var
24881         fi
24882
24883         local jobid_var_old=$($LCTL get_param -n $testname)
24884         local jobid_var_new
24885
24886         $LCTL set_param $testname= &&
24887                 error "no error returned for 'set_param a='"
24888
24889         jobid_var_new=$($LCTL get_param -n $testname)
24890         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24891                 error "$testname was changed by setting without value"
24892
24893         $LCTL set_param $testname &&
24894                 error "no error returned for 'set_param a'"
24895
24896         jobid_var_new=$($LCTL get_param -n $testname)
24897         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24898                 error "$testname was changed by setting without value"
24899 }
24900 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24901
24902 test_401d() {
24903         # jobid_var may not allow arbitrary values, so use jobid_name
24904         # if available
24905         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24906                 local testname=jobid_name new_value='foo=bar%p'
24907         else
24908                 local testname=jobid_var new_valuie=foo=bar
24909         fi
24910
24911         local jobid_var_old=$($LCTL get_param -n $testname)
24912         local jobid_var_new
24913
24914         $LCTL set_param $testname=$new_value ||
24915                 error "'set_param a=b' did not accept a value containing '='"
24916
24917         jobid_var_new=$($LCTL get_param -n $testname)
24918         [[ "$jobid_var_new" == "$new_value" ]] ||
24919                 error "'set_param a=b' failed on a value containing '='"
24920
24921         # Reset the $testname to test the other format
24922         $LCTL set_param $testname=$jobid_var_old
24923         jobid_var_new=$($LCTL get_param -n $testname)
24924         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24925                 error "failed to reset $testname"
24926
24927         $LCTL set_param $testname $new_value ||
24928                 error "'set_param a b' did not accept a value containing '='"
24929
24930         jobid_var_new=$($LCTL get_param -n $testname)
24931         [[ "$jobid_var_new" == "$new_value" ]] ||
24932                 error "'set_param a b' failed on a value containing '='"
24933
24934         $LCTL set_param $testname $jobid_var_old
24935         jobid_var_new=$($LCTL get_param -n $testname)
24936         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24937                 error "failed to reset $testname"
24938 }
24939 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24940
24941 test_401e() { # LU-14779
24942         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24943                 error "lctl list_param MGC* failed"
24944         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24945         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24946                 error "lctl get_param lru_size failed"
24947 }
24948 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24949
24950 test_402() {
24951         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24952         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24953                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24954         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24955                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24956                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24957         remote_mds_nodsh && skip "remote MDS with nodsh"
24958
24959         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24960 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24961         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24962         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24963                 echo "Touch failed - OK"
24964 }
24965 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24966
24967 test_403() {
24968         local file1=$DIR/$tfile.1
24969         local file2=$DIR/$tfile.2
24970         local tfile=$TMP/$tfile
24971
24972         rm -f $file1 $file2 $tfile
24973
24974         touch $file1
24975         ln $file1 $file2
24976
24977         # 30 sec OBD_TIMEOUT in ll_getattr()
24978         # right before populating st_nlink
24979         $LCTL set_param fail_loc=0x80001409
24980         stat -c %h $file1 > $tfile &
24981
24982         # create an alias, drop all locks and reclaim the dentry
24983         < $file2
24984         cancel_lru_locks mdc
24985         cancel_lru_locks osc
24986         sysctl -w vm.drop_caches=2
24987
24988         wait
24989
24990         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24991
24992         rm -f $tfile $file1 $file2
24993 }
24994 run_test 403 "i_nlink should not drop to zero due to aliasing"
24995
24996 test_404() { # LU-6601
24997         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24998                 skip "Need server version newer than 2.8.52"
24999         remote_mds_nodsh && skip "remote MDS with nodsh"
25000
25001         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25002                 awk '/osp .*-osc-MDT/ { print $4}')
25003
25004         local osp
25005         for osp in $mosps; do
25006                 echo "Deactivate: " $osp
25007                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25008                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25009                         awk -vp=$osp '$4 == p { print $2 }')
25010                 [ $stat = IN ] || {
25011                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25012                         error "deactivate error"
25013                 }
25014                 echo "Activate: " $osp
25015                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25016                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25017                         awk -vp=$osp '$4 == p { print $2 }')
25018                 [ $stat = UP ] || {
25019                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25020                         error "activate error"
25021                 }
25022         done
25023 }
25024 run_test 404 "validate manual {de}activated works properly for OSPs"
25025
25026 test_405() {
25027         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25028         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25029                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25030                         skip "Layout swap lock is not supported"
25031
25032         check_swap_layouts_support
25033         check_swap_layout_no_dom $DIR
25034
25035         test_mkdir $DIR/$tdir
25036         swap_lock_test -d $DIR/$tdir ||
25037                 error "One layout swap locked test failed"
25038 }
25039 run_test 405 "Various layout swap lock tests"
25040
25041 test_406() {
25042         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25043         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25044         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25046         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25047                 skip "Need MDS version at least 2.8.50"
25048
25049         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25050         local test_pool=$TESTNAME
25051
25052         pool_add $test_pool || error "pool_add failed"
25053         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25054                 error "pool_add_targets failed"
25055
25056         save_layout_restore_at_exit $MOUNT
25057
25058         # parent set default stripe count only, child will stripe from both
25059         # parent and fs default
25060         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25061                 error "setstripe $MOUNT failed"
25062         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25063         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25064         for i in $(seq 10); do
25065                 local f=$DIR/$tdir/$tfile.$i
25066                 touch $f || error "touch failed"
25067                 local count=$($LFS getstripe -c $f)
25068                 [ $count -eq $OSTCOUNT ] ||
25069                         error "$f stripe count $count != $OSTCOUNT"
25070                 local offset=$($LFS getstripe -i $f)
25071                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25072                 local size=$($LFS getstripe -S $f)
25073                 [ $size -eq $((def_stripe_size * 2)) ] ||
25074                         error "$f stripe size $size != $((def_stripe_size * 2))"
25075                 local pool=$($LFS getstripe -p $f)
25076                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25077         done
25078
25079         # change fs default striping, delete parent default striping, now child
25080         # will stripe from new fs default striping only
25081         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25082                 error "change $MOUNT default stripe failed"
25083         $LFS setstripe -c 0 $DIR/$tdir ||
25084                 error "delete $tdir default stripe failed"
25085         for i in $(seq 11 20); do
25086                 local f=$DIR/$tdir/$tfile.$i
25087                 touch $f || error "touch $f failed"
25088                 local count=$($LFS getstripe -c $f)
25089                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25090                 local offset=$($LFS getstripe -i $f)
25091                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25092                 local size=$($LFS getstripe -S $f)
25093                 [ $size -eq $def_stripe_size ] ||
25094                         error "$f stripe size $size != $def_stripe_size"
25095                 local pool=$($LFS getstripe -p $f)
25096                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25097         done
25098
25099         unlinkmany $DIR/$tdir/$tfile. 1 20
25100
25101         local f=$DIR/$tdir/$tfile
25102         pool_remove_all_targets $test_pool $f
25103         pool_remove $test_pool $f
25104 }
25105 run_test 406 "DNE support fs default striping"
25106
25107 test_407() {
25108         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25109         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25110                 skip "Need MDS version at least 2.8.55"
25111         remote_mds_nodsh && skip "remote MDS with nodsh"
25112
25113         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25114                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25115         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25116                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25117         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25118
25119         #define OBD_FAIL_DT_TXN_STOP    0x2019
25120         for idx in $(seq $MDSCOUNT); do
25121                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25122         done
25123         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25124         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25125                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25126         true
25127 }
25128 run_test 407 "transaction fail should cause operation fail"
25129
25130 test_408() {
25131         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25132
25133         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25134         lctl set_param fail_loc=0x8000040a
25135         # let ll_prepare_partial_page() fail
25136         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25137
25138         rm -f $DIR/$tfile
25139
25140         # create at least 100 unused inodes so that
25141         # shrink_icache_memory(0) should not return 0
25142         touch $DIR/$tfile-{0..100}
25143         rm -f $DIR/$tfile-{0..100}
25144         sync
25145
25146         echo 2 > /proc/sys/vm/drop_caches
25147 }
25148 run_test 408 "drop_caches should not hang due to page leaks"
25149
25150 test_409()
25151 {
25152         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25153
25154         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25155         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25156         touch $DIR/$tdir/guard || error "(2) Fail to create"
25157
25158         local PREFIX=$(str_repeat 'A' 128)
25159         echo "Create 1K hard links start at $(date)"
25160         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25161                 error "(3) Fail to hard link"
25162
25163         echo "Links count should be right although linkEA overflow"
25164         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25165         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25166         [ $linkcount -eq 1001 ] ||
25167                 error "(5) Unexpected hard links count: $linkcount"
25168
25169         echo "List all links start at $(date)"
25170         ls -l $DIR/$tdir/foo > /dev/null ||
25171                 error "(6) Fail to list $DIR/$tdir/foo"
25172
25173         echo "Unlink hard links start at $(date)"
25174         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25175                 error "(7) Fail to unlink"
25176         echo "Unlink hard links finished at $(date)"
25177 }
25178 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25179
25180 test_410()
25181 {
25182         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25183                 skip "Need client version at least 2.9.59"
25184         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25185                 skip "Need MODULES build"
25186
25187         # Create a file, and stat it from the kernel
25188         local testfile=$DIR/$tfile
25189         touch $testfile
25190
25191         local run_id=$RANDOM
25192         local my_ino=$(stat --format "%i" $testfile)
25193
25194         # Try to insert the module. This will always fail as the
25195         # module is designed to not be inserted.
25196         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25197             &> /dev/null
25198
25199         # Anything but success is a test failure
25200         dmesg | grep -q \
25201             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25202             error "no inode match"
25203 }
25204 run_test 410 "Test inode number returned from kernel thread"
25205
25206 cleanup_test411_cgroup() {
25207         trap 0
25208         rmdir "$1"
25209 }
25210
25211 test_411() {
25212         local cg_basedir=/sys/fs/cgroup/memory
25213         # LU-9966
25214         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25215                 skip "no setup for cgroup"
25216
25217         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25218                 error "test file creation failed"
25219         cancel_lru_locks osc
25220
25221         # Create a very small memory cgroup to force a slab allocation error
25222         local cgdir=$cg_basedir/osc_slab_alloc
25223         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25224         trap "cleanup_test411_cgroup $cgdir" EXIT
25225         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25226         echo 1M > $cgdir/memory.limit_in_bytes
25227
25228         # Should not LBUG, just be killed by oom-killer
25229         # dd will return 0 even allocation failure in some environment.
25230         # So don't check return value
25231         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25232         cleanup_test411_cgroup $cgdir
25233
25234         return 0
25235 }
25236 run_test 411 "Slab allocation error with cgroup does not LBUG"
25237
25238 test_412() {
25239         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25240         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25241                 skip "Need server version at least 2.10.55"
25242
25243         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25244                 error "mkdir failed"
25245         $LFS getdirstripe $DIR/$tdir
25246         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25247         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25248                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25249         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25250         [ $stripe_count -eq 2 ] ||
25251                 error "expect 2 get $stripe_count"
25252
25253         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25254
25255         local index
25256         local index2
25257
25258         # subdirs should be on the same MDT as parent
25259         for i in $(seq 0 $((MDSCOUNT - 1))); do
25260                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25261                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25262                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25263                 (( index == i )) || error "mdt$i/sub on MDT$index"
25264         done
25265
25266         # stripe offset -1, ditto
25267         for i in {1..10}; do
25268                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25269                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25270                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25271                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25272                 (( index == index2 )) ||
25273                         error "qos$i on MDT$index, sub on MDT$index2"
25274         done
25275
25276         local testdir=$DIR/$tdir/inherit
25277
25278         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25279         # inherit 2 levels
25280         for i in 1 2; do
25281                 testdir=$testdir/s$i
25282                 mkdir $testdir || error "mkdir $testdir failed"
25283                 index=$($LFS getstripe -m $testdir)
25284                 (( index == 1 )) ||
25285                         error "$testdir on MDT$index"
25286         done
25287
25288         # not inherit any more
25289         testdir=$testdir/s3
25290         mkdir $testdir || error "mkdir $testdir failed"
25291         getfattr -d -m dmv $testdir | grep dmv &&
25292                 error "default LMV set on $testdir" || true
25293 }
25294 run_test 412 "mkdir on specific MDTs"
25295
25296 generate_uneven_mdts() {
25297         local threshold=$1
25298         local lmv_qos_maxage
25299         local lod_qos_maxage
25300         local ffree
25301         local bavail
25302         local max
25303         local min
25304         local max_index
25305         local min_index
25306         local tmp
25307         local i
25308
25309         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25310         $LCTL set_param lmv.*.qos_maxage=1
25311         stack_trap "$LCTL set_param \
25312                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25313         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25314                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25315         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25316                 lod.*.mdt_qos_maxage=1
25317         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25318                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25319
25320         echo
25321         echo "Check for uneven MDTs: "
25322
25323         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25324         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25325         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25326
25327         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25328         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25329         max_index=0
25330         min_index=0
25331         for ((i = 1; i < ${#ffree[@]}; i++)); do
25332                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25333                 if [ $tmp -gt $max ]; then
25334                         max=$tmp
25335                         max_index=$i
25336                 fi
25337                 if [ $tmp -lt $min ]; then
25338                         min=$tmp
25339                         min_index=$i
25340                 fi
25341         done
25342
25343         (( ${ffree[min_index]} > 0 )) ||
25344                 skip "no free files in MDT$min_index"
25345         (( ${ffree[min_index]} < 10000000 )) ||
25346                 skip "too many free files in MDT$min_index"
25347
25348         # Check if we need to generate uneven MDTs
25349         local diff=$(((max - min) * 100 / min))
25350         local testdir=$DIR/$tdir-fillmdt
25351         local start
25352
25353         mkdir -p $testdir
25354
25355         i=0
25356         while (( diff < threshold )); do
25357                 # generate uneven MDTs, create till $threshold% diff
25358                 echo -n "weight diff=$diff% must be > $threshold% ..."
25359                 echo "Fill MDT$min_index with 1000 files: loop $i"
25360                 testdir=$DIR/$tdir-fillmdt/$i
25361                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25362                         error "mkdir $testdir failed"
25363                 $LFS setstripe -E 1M -L mdt $testdir ||
25364                         error "setstripe $testdir failed"
25365                 start=$SECONDS
25366                 for F in f.{0..999}; do
25367                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25368                                 /dev/null 2>&1 || error "dd $F failed"
25369                 done
25370
25371                 # wait for QOS to update
25372                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25373
25374                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25375                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25376                 max=$(((${ffree[max_index]} >> 8) * \
25377                         (${bavail[max_index]} * bsize >> 16)))
25378                 min=$(((${ffree[min_index]} >> 8) * \
25379                         (${bavail[min_index]} * bsize >> 16)))
25380                 diff=$(((max - min) * 100 / min))
25381                 i=$((i + 1))
25382         done
25383
25384         echo "MDT filesfree available: ${ffree[@]}"
25385         echo "MDT blocks available: ${bavail[@]}"
25386         echo "weight diff=$diff%"
25387 }
25388
25389 test_qos_mkdir() {
25390         local mkdir_cmd=$1
25391         local stripe_count=$2
25392         local mdts=$(comma_list $(mdts_nodes))
25393
25394         local testdir
25395         local lmv_qos_prio_free
25396         local lmv_qos_threshold_rr
25397         local lmv_qos_maxage
25398         local lod_qos_prio_free
25399         local lod_qos_threshold_rr
25400         local lod_qos_maxage
25401         local count
25402         local i
25403
25404         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25405         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25406         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25407                 head -n1)
25408         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25409         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25410         stack_trap "$LCTL set_param \
25411                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25412         stack_trap "$LCTL set_param \
25413                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25414         stack_trap "$LCTL set_param \
25415                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25416
25417         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25418                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25419         lod_qos_prio_free=${lod_qos_prio_free%%%}
25420         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25421                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25422         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25423         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25424                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25425         stack_trap "do_nodes $mdts $LCTL set_param \
25426                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25427         stack_trap "do_nodes $mdts $LCTL set_param \
25428                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25429         stack_trap "do_nodes $mdts $LCTL set_param \
25430                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25431
25432         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25433         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25434
25435         testdir=$DIR/$tdir-s$stripe_count/rr
25436
25437         local stripe_index=$($LFS getstripe -m $testdir)
25438         local test_mkdir_rr=true
25439
25440         getfattr -d -m dmv -e hex $testdir | grep dmv
25441         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25442                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25443                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25444                         test_mkdir_rr=false
25445         fi
25446
25447         echo
25448         $test_mkdir_rr &&
25449                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25450                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25451
25452         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25453         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25454                 eval $mkdir_cmd $testdir/subdir$i ||
25455                         error "$mkdir_cmd subdir$i failed"
25456         done
25457
25458         for (( i = 0; i < $MDSCOUNT; i++ )); do
25459                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25460                 echo "$count directories created on MDT$i"
25461                 if $test_mkdir_rr; then
25462                         (( $count == 100 )) ||
25463                                 error "subdirs are not evenly distributed"
25464                 elif (( $i == $stripe_index )); then
25465                         (( $count == 100 * MDSCOUNT )) ||
25466                                 error "$count subdirs created on MDT$i"
25467                 else
25468                         (( $count == 0 )) ||
25469                                 error "$count subdirs created on MDT$i"
25470                 fi
25471
25472                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25473                         count=$($LFS getdirstripe $testdir/* |
25474                                 grep -c -P "^\s+$i\t")
25475                         echo "$count stripes created on MDT$i"
25476                         # deviation should < 5% of average
25477                         (( $count >= 95 * stripe_count &&
25478                            $count <= 105 * stripe_count)) ||
25479                                 error "stripes are not evenly distributed"
25480                 fi
25481         done
25482
25483         echo
25484         echo "Check for uneven MDTs: "
25485
25486         local ffree
25487         local bavail
25488         local max
25489         local min
25490         local max_index
25491         local min_index
25492         local tmp
25493
25494         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25495         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25496         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25497
25498         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25499         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25500         max_index=0
25501         min_index=0
25502         for ((i = 1; i < ${#ffree[@]}; i++)); do
25503                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25504                 if [ $tmp -gt $max ]; then
25505                         max=$tmp
25506                         max_index=$i
25507                 fi
25508                 if [ $tmp -lt $min ]; then
25509                         min=$tmp
25510                         min_index=$i
25511                 fi
25512         done
25513
25514         (( ${ffree[min_index]} > 0 )) ||
25515                 skip "no free files in MDT$min_index"
25516         (( ${ffree[min_index]} < 10000000 )) ||
25517                 skip "too many free files in MDT$min_index"
25518
25519         echo "MDT filesfree available: ${ffree[@]}"
25520         echo "MDT blocks available: ${bavail[@]}"
25521         echo "weight diff=$(((max - min) * 100 / min))%"
25522         echo
25523         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25524
25525         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25526         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25527         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25528         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25529         # decrease statfs age, so that it can be updated in time
25530         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25531         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25532
25533         sleep 1
25534
25535         testdir=$DIR/$tdir-s$stripe_count/qos
25536         local num=200
25537
25538         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25539         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25540                 eval $mkdir_cmd $testdir/subdir$i ||
25541                         error "$mkdir_cmd subdir$i failed"
25542         done
25543
25544         max=0
25545         for (( i = 0; i < $MDSCOUNT; i++ )); do
25546                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25547                 (( count > max )) && max=$count
25548                 echo "$count directories created on MDT$i"
25549         done
25550
25551         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25552
25553         # D-value should > 10% of averge
25554         (( max - min > num / 10 )) ||
25555                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25556
25557         # ditto for stripes
25558         if (( stripe_count > 1 )); then
25559                 max=0
25560                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25561                         count=$($LFS getdirstripe $testdir/* |
25562                                 grep -c -P "^\s+$i\t")
25563                         (( count > max )) && max=$count
25564                         echo "$count stripes created on MDT$i"
25565                 done
25566
25567                 min=$($LFS getdirstripe $testdir/* |
25568                         grep -c -P "^\s+$min_index\t")
25569                 (( max - min > num * stripe_count / 10 )) ||
25570                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25571         fi
25572 }
25573
25574 most_full_mdt() {
25575         local ffree
25576         local bavail
25577         local bsize
25578         local min
25579         local min_index
25580         local tmp
25581
25582         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25583         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25584         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25585
25586         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25587         min_index=0
25588         for ((i = 1; i < ${#ffree[@]}; i++)); do
25589                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25590                 (( tmp < min )) && min=$tmp && min_index=$i
25591         done
25592
25593         echo -n $min_index
25594 }
25595
25596 test_413a() {
25597         [ $MDSCOUNT -lt 2 ] &&
25598                 skip "We need at least 2 MDTs for this test"
25599
25600         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25601                 skip "Need server version at least 2.12.52"
25602
25603         local stripe_count
25604
25605         generate_uneven_mdts 100
25606         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25607                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25608                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25609                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25610                         error "mkdir failed"
25611                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25612         done
25613 }
25614 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25615
25616 test_413b() {
25617         [ $MDSCOUNT -lt 2 ] &&
25618                 skip "We need at least 2 MDTs for this test"
25619
25620         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25621                 skip "Need server version at least 2.12.52"
25622
25623         local testdir
25624         local stripe_count
25625
25626         generate_uneven_mdts 100
25627         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25628                 testdir=$DIR/$tdir-s$stripe_count
25629                 mkdir $testdir || error "mkdir $testdir failed"
25630                 mkdir $testdir/rr || error "mkdir rr failed"
25631                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25632                         error "mkdir qos failed"
25633                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25634                         $testdir/rr || error "setdirstripe rr failed"
25635                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25636                         error "setdirstripe failed"
25637                 test_qos_mkdir "mkdir" $stripe_count
25638         done
25639 }
25640 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25641
25642 test_413c() {
25643         (( $MDSCOUNT >= 2 )) ||
25644                 skip "We need at least 2 MDTs for this test"
25645
25646         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25647                 skip "Need server version at least 2.14.51"
25648
25649         local testdir
25650         local inherit
25651         local inherit_rr
25652
25653         testdir=$DIR/${tdir}-s1
25654         mkdir $testdir || error "mkdir $testdir failed"
25655         mkdir $testdir/rr || error "mkdir rr failed"
25656         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25657         # default max_inherit is -1, default max_inherit_rr is 0
25658         $LFS setdirstripe -D -c 1 $testdir/rr ||
25659                 error "setdirstripe rr failed"
25660         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25661                 error "setdirstripe qos failed"
25662         test_qos_mkdir "mkdir" 1
25663
25664         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25665         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25666         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25667         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25668         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25669
25670         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25671         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25672         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25673         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25674         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25675         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25676         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25677                 error "level2 shouldn't have default LMV" || true
25678 }
25679 run_test 413c "mkdir with default LMV max inherit rr"
25680
25681 test_413d() {
25682         (( MDSCOUNT >= 2 )) ||
25683                 skip "We need at least 2 MDTs for this test"
25684
25685         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25686                 skip "Need server version at least 2.14.51"
25687
25688         local lmv_qos_threshold_rr
25689
25690         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25691                 head -n1)
25692         stack_trap "$LCTL set_param \
25693                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25694
25695         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25696         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25697         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25698                 error "$tdir shouldn't have default LMV"
25699         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25700                 error "mkdir sub failed"
25701
25702         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25703
25704         (( count == 100 )) || error "$count subdirs on MDT0"
25705 }
25706 run_test 413d "inherit ROOT default LMV"
25707
25708 test_413e() {
25709         (( MDSCOUNT >= 2 )) ||
25710                 skip "We need at least 2 MDTs for this test"
25711         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25712                 skip "Need server version at least 2.14.55"
25713
25714         local testdir=$DIR/$tdir
25715         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25716         local max_inherit
25717         local sub_max_inherit
25718
25719         mkdir -p $testdir || error "failed to create $testdir"
25720
25721         # set default max-inherit to -1 if stripe count is 0 or 1
25722         $LFS setdirstripe -D -c 1 $testdir ||
25723                 error "failed to set default LMV"
25724         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25725         (( max_inherit == -1 )) ||
25726                 error "wrong max_inherit value $max_inherit"
25727
25728         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25729         $LFS setdirstripe -D -c -1 $testdir ||
25730                 error "failed to set default LMV"
25731         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25732         (( max_inherit > 0 )) ||
25733                 error "wrong max_inherit value $max_inherit"
25734
25735         # and the subdir will decrease the max_inherit by 1
25736         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25737         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
25738         (( sub_max_inherit == max_inherit - 1)) ||
25739                 error "wrong max-inherit of subdir $sub_max_inherit"
25740
25741         # check specified --max-inherit and warning message
25742         stack_trap "rm -f $tmpfile"
25743         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
25744                 error "failed to set default LMV"
25745         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25746         (( max_inherit == -1 )) ||
25747                 error "wrong max_inherit value $max_inherit"
25748
25749         # check the warning messages
25750         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
25751                 error "failed to detect warning string"
25752         fi
25753 }
25754 run_test 413e "check default max-inherit value"
25755
25756 test_413f() {
25757         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
25758
25759         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25760                 skip "Need server version at least 2.14.55"
25761
25762         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
25763                 error "dump $DIR default LMV failed"
25764         stack_trap "setfattr --restore=$TMP/dmv.ea"
25765
25766         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
25767                 error "set $DIR default LMV failed"
25768
25769         local testdir=$DIR/$tdir
25770
25771         local count
25772         local inherit
25773         local inherit_rr
25774
25775         for i in $(seq 3); do
25776                 mkdir $testdir || error "mkdir $testdir failed"
25777                 count=$($LFS getdirstripe -D -c $testdir)
25778                 (( count == 1 )) ||
25779                         error "$testdir default LMV count mismatch $count != 1"
25780                 inherit=$($LFS getdirstripe -D -X $testdir)
25781                 (( inherit == 3 - i )) ||
25782                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
25783                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
25784                 (( inherit_rr == 3 - i )) ||
25785                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
25786                 testdir=$testdir/sub
25787         done
25788
25789         mkdir $testdir || error "mkdir $testdir failed"
25790         count=$($LFS getdirstripe -D -c $testdir)
25791         (( count == 0 )) ||
25792                 error "$testdir default LMV count not zero: $count"
25793 }
25794 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
25795
25796 test_413z() {
25797         local pids=""
25798         local subdir
25799         local pid
25800
25801         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25802                 unlinkmany $subdir/f. 1000 &
25803                 pids="$pids $!"
25804         done
25805
25806         for pid in $pids; do
25807                 wait $pid
25808         done
25809 }
25810 run_test 413z "413 test cleanup"
25811
25812 test_414() {
25813 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25814         $LCTL set_param fail_loc=0x80000521
25815         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25816         rm -f $DIR/$tfile
25817 }
25818 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25819
25820 test_415() {
25821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25822         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25823                 skip "Need server version at least 2.11.52"
25824
25825         # LU-11102
25826         local total
25827         local setattr_pid
25828         local start_time
25829         local end_time
25830         local duration
25831
25832         total=500
25833         # this test may be slow on ZFS
25834         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25835
25836         # though this test is designed for striped directory, let's test normal
25837         # directory too since lock is always saved as CoS lock.
25838         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25839         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25840
25841         (
25842                 while true; do
25843                         touch $DIR/$tdir
25844                 done
25845         ) &
25846         setattr_pid=$!
25847
25848         start_time=$(date +%s)
25849         for i in $(seq $total); do
25850                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25851                         > /dev/null
25852         done
25853         end_time=$(date +%s)
25854         duration=$((end_time - start_time))
25855
25856         kill -9 $setattr_pid
25857
25858         echo "rename $total files took $duration sec"
25859         [ $duration -lt 100 ] || error "rename took $duration sec"
25860 }
25861 run_test 415 "lock revoke is not missing"
25862
25863 test_416() {
25864         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25865                 skip "Need server version at least 2.11.55"
25866
25867         # define OBD_FAIL_OSD_TXN_START    0x19a
25868         do_facet mds1 lctl set_param fail_loc=0x19a
25869
25870         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25871
25872         true
25873 }
25874 run_test 416 "transaction start failure won't cause system hung"
25875
25876 cleanup_417() {
25877         trap 0
25878         do_nodes $(comma_list $(mdts_nodes)) \
25879                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25880         do_nodes $(comma_list $(mdts_nodes)) \
25881                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25882         do_nodes $(comma_list $(mdts_nodes)) \
25883                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25884 }
25885
25886 test_417() {
25887         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25888         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25889                 skip "Need MDS version at least 2.11.56"
25890
25891         trap cleanup_417 RETURN EXIT
25892
25893         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25894         do_nodes $(comma_list $(mdts_nodes)) \
25895                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25896         $LFS migrate -m 0 $DIR/$tdir.1 &&
25897                 error "migrate dir $tdir.1 should fail"
25898
25899         do_nodes $(comma_list $(mdts_nodes)) \
25900                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25901         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25902                 error "create remote dir $tdir.2 should fail"
25903
25904         do_nodes $(comma_list $(mdts_nodes)) \
25905                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25906         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25907                 error "create striped dir $tdir.3 should fail"
25908         true
25909 }
25910 run_test 417 "disable remote dir, striped dir and dir migration"
25911
25912 # Checks that the outputs of df [-i] and lfs df [-i] match
25913 #
25914 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25915 check_lfs_df() {
25916         local dir=$2
25917         local inodes
25918         local df_out
25919         local lfs_df_out
25920         local count
25921         local passed=false
25922
25923         # blocks or inodes
25924         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25925
25926         for count in {1..100}; do
25927                 do_nodes "$CLIENTS" \
25928                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25929                 sync; sleep 0.2
25930
25931                 # read the lines of interest
25932                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25933                         error "df $inodes $dir | tail -n +2 failed"
25934                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25935                         error "lfs df $inodes $dir | grep summary: failed"
25936
25937                 # skip first substrings of each output as they are different
25938                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25939                 # compare the two outputs
25940                 passed=true
25941                 #  skip "available" on MDT until LU-13997 is fixed.
25942                 #for i in {1..5}; do
25943                 for i in 1 2 4 5; do
25944                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25945                 done
25946                 $passed && break
25947         done
25948
25949         if ! $passed; then
25950                 df -P $inodes $dir
25951                 echo
25952                 lfs df $inodes $dir
25953                 error "df and lfs df $1 output mismatch: "      \
25954                       "df ${inodes}: ${df_out[*]}, "            \
25955                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25956         fi
25957 }
25958
25959 test_418() {
25960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25961
25962         local dir=$DIR/$tdir
25963         local numfiles=$((RANDOM % 4096 + 2))
25964         local numblocks=$((RANDOM % 256 + 1))
25965
25966         wait_delete_completed
25967         test_mkdir $dir
25968
25969         # check block output
25970         check_lfs_df blocks $dir
25971         # check inode output
25972         check_lfs_df inodes $dir
25973
25974         # create a single file and retest
25975         echo "Creating a single file and testing"
25976         createmany -o $dir/$tfile- 1 &>/dev/null ||
25977                 error "creating 1 file in $dir failed"
25978         check_lfs_df blocks $dir
25979         check_lfs_df inodes $dir
25980
25981         # create a random number of files
25982         echo "Creating $((numfiles - 1)) files and testing"
25983         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25984                 error "creating $((numfiles - 1)) files in $dir failed"
25985
25986         # write a random number of blocks to the first test file
25987         echo "Writing $numblocks 4K blocks and testing"
25988         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25989                 count=$numblocks &>/dev/null ||
25990                 error "dd to $dir/${tfile}-0 failed"
25991
25992         # retest
25993         check_lfs_df blocks $dir
25994         check_lfs_df inodes $dir
25995
25996         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25997                 error "unlinking $numfiles files in $dir failed"
25998 }
25999 run_test 418 "df and lfs df outputs match"
26000
26001 test_419()
26002 {
26003         local dir=$DIR/$tdir
26004
26005         mkdir -p $dir
26006         touch $dir/file
26007
26008         cancel_lru_locks mdc
26009
26010         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26011         $LCTL set_param fail_loc=0x1410
26012         cat $dir/file
26013         $LCTL set_param fail_loc=0
26014         rm -rf $dir
26015 }
26016 run_test 419 "Verify open file by name doesn't crash kernel"
26017
26018 test_420()
26019 {
26020         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26021                 skip "Need MDS version at least 2.12.53"
26022
26023         local SAVE_UMASK=$(umask)
26024         local dir=$DIR/$tdir
26025         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26026
26027         mkdir -p $dir
26028         umask 0000
26029         mkdir -m03777 $dir/testdir
26030         ls -dn $dir/testdir
26031         # Need to remove trailing '.' when SELinux is enabled
26032         local dirperms=$(ls -dn $dir/testdir |
26033                          awk '{ sub(/\.$/, "", $1); print $1}')
26034         [ $dirperms == "drwxrwsrwt" ] ||
26035                 error "incorrect perms on $dir/testdir"
26036
26037         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26038                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26039         ls -n $dir/testdir/testfile
26040         local fileperms=$(ls -n $dir/testdir/testfile |
26041                           awk '{ sub(/\.$/, "", $1); print $1}')
26042         [ $fileperms == "-rwxr-xr-x" ] ||
26043                 error "incorrect perms on $dir/testdir/testfile"
26044
26045         umask $SAVE_UMASK
26046 }
26047 run_test 420 "clear SGID bit on non-directories for non-members"
26048
26049 test_421a() {
26050         local cnt
26051         local fid1
26052         local fid2
26053
26054         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26055                 skip "Need MDS version at least 2.12.54"
26056
26057         test_mkdir $DIR/$tdir
26058         createmany -o $DIR/$tdir/f 3
26059         cnt=$(ls -1 $DIR/$tdir | wc -l)
26060         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26061
26062         fid1=$(lfs path2fid $DIR/$tdir/f1)
26063         fid2=$(lfs path2fid $DIR/$tdir/f2)
26064         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26065
26066         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26067         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26068
26069         cnt=$(ls -1 $DIR/$tdir | wc -l)
26070         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26071
26072         rm -f $DIR/$tdir/f3 || error "can't remove f3"
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         echo "remove using fsname $FSNAME"
26080         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26081
26082         cnt=$(ls -1 $DIR/$tdir | wc -l)
26083         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26084 }
26085 run_test 421a "simple rm by fid"
26086
26087 test_421b() {
26088         local cnt
26089         local FID1
26090         local FID2
26091
26092         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26093                 skip "Need MDS version at least 2.12.54"
26094
26095         test_mkdir $DIR/$tdir
26096         createmany -o $DIR/$tdir/f 3
26097         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26098         MULTIPID=$!
26099
26100         FID1=$(lfs path2fid $DIR/$tdir/f1)
26101         FID2=$(lfs path2fid $DIR/$tdir/f2)
26102         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26103
26104         kill -USR1 $MULTIPID
26105         wait
26106
26107         cnt=$(ls $DIR/$tdir | wc -l)
26108         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26109 }
26110 run_test 421b "rm by fid on open file"
26111
26112 test_421c() {
26113         local cnt
26114         local FIDS
26115
26116         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26117                 skip "Need MDS version at least 2.12.54"
26118
26119         test_mkdir $DIR/$tdir
26120         createmany -o $DIR/$tdir/f 3
26121         touch $DIR/$tdir/$tfile
26122         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26123         cnt=$(ls -1 $DIR/$tdir | wc -l)
26124         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26125
26126         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26127         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26128
26129         cnt=$(ls $DIR/$tdir | wc -l)
26130         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26131 }
26132 run_test 421c "rm by fid against hardlinked files"
26133
26134 test_421d() {
26135         local cnt
26136         local FIDS
26137
26138         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26139                 skip "Need MDS version at least 2.12.54"
26140
26141         test_mkdir $DIR/$tdir
26142         createmany -o $DIR/$tdir/f 4097
26143         cnt=$(ls -1 $DIR/$tdir | wc -l)
26144         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26145
26146         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26147         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26148
26149         cnt=$(ls $DIR/$tdir | wc -l)
26150         rm -rf $DIR/$tdir
26151         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26152 }
26153 run_test 421d "rmfid en masse"
26154
26155 test_421e() {
26156         local cnt
26157         local FID
26158
26159         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26160         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26161                 skip "Need MDS version at least 2.12.54"
26162
26163         mkdir -p $DIR/$tdir
26164         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26165         createmany -o $DIR/$tdir/striped_dir/f 512
26166         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26167         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26168
26169         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26170                 sed "s/[/][^:]*://g")
26171         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26172
26173         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26174         rm -rf $DIR/$tdir
26175         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26176 }
26177 run_test 421e "rmfid in DNE"
26178
26179 test_421f() {
26180         local cnt
26181         local FID
26182
26183         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26184                 skip "Need MDS version at least 2.12.54"
26185
26186         test_mkdir $DIR/$tdir
26187         touch $DIR/$tdir/f
26188         cnt=$(ls -1 $DIR/$tdir | wc -l)
26189         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26190
26191         FID=$(lfs path2fid $DIR/$tdir/f)
26192         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26193         # rmfid should fail
26194         cnt=$(ls -1 $DIR/$tdir | wc -l)
26195         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26196
26197         chmod a+rw $DIR/$tdir
26198         ls -la $DIR/$tdir
26199         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26200         # rmfid should fail
26201         cnt=$(ls -1 $DIR/$tdir | wc -l)
26202         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26203
26204         rm -f $DIR/$tdir/f
26205         $RUNAS touch $DIR/$tdir/f
26206         FID=$(lfs path2fid $DIR/$tdir/f)
26207         echo "rmfid as root"
26208         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26209         cnt=$(ls -1 $DIR/$tdir | wc -l)
26210         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26211
26212         rm -f $DIR/$tdir/f
26213         $RUNAS touch $DIR/$tdir/f
26214         cnt=$(ls -1 $DIR/$tdir | wc -l)
26215         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26216         FID=$(lfs path2fid $DIR/$tdir/f)
26217         # rmfid w/o user_fid2path mount option should fail
26218         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26219         cnt=$(ls -1 $DIR/$tdir | wc -l)
26220         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26221
26222         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26223         stack_trap "rmdir $tmpdir"
26224         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26225                 error "failed to mount client'"
26226         stack_trap "umount_client $tmpdir"
26227
26228         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26229         # rmfid should succeed
26230         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26231         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26232
26233         # rmfid shouldn't allow to remove files due to dir's permission
26234         chmod a+rwx $tmpdir/$tdir
26235         touch $tmpdir/$tdir/f
26236         ls -la $tmpdir/$tdir
26237         FID=$(lfs path2fid $tmpdir/$tdir/f)
26238         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26239         return 0
26240 }
26241 run_test 421f "rmfid checks permissions"
26242
26243 test_421g() {
26244         local cnt
26245         local FIDS
26246
26247         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26248         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26249                 skip "Need MDS version at least 2.12.54"
26250
26251         mkdir -p $DIR/$tdir
26252         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26253         createmany -o $DIR/$tdir/striped_dir/f 512
26254         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26255         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26256
26257         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26258                 sed "s/[/][^:]*://g")
26259
26260         rm -f $DIR/$tdir/striped_dir/f1*
26261         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26262         removed=$((512 - cnt))
26263
26264         # few files have been just removed, so we expect
26265         # rmfid to fail on their fids
26266         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26267         [ $removed != $errors ] && error "$errors != $removed"
26268
26269         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26270         rm -rf $DIR/$tdir
26271         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26272 }
26273 run_test 421g "rmfid to return errors properly"
26274
26275 test_422() {
26276         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26277         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26278         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26279         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26280         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26281
26282         local amc=$(at_max_get client)
26283         local amo=$(at_max_get mds1)
26284         local timeout=`lctl get_param -n timeout`
26285
26286         at_max_set 0 client
26287         at_max_set 0 mds1
26288
26289 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26290         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26291                         fail_val=$(((2*timeout + 10)*1000))
26292         touch $DIR/$tdir/d3/file &
26293         sleep 2
26294 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26295         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26296                         fail_val=$((2*timeout + 5))
26297         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26298         local pid=$!
26299         sleep 1
26300         kill -9 $pid
26301         sleep $((2 * timeout))
26302         echo kill $pid
26303         kill -9 $pid
26304         lctl mark touch
26305         touch $DIR/$tdir/d2/file3
26306         touch $DIR/$tdir/d2/file4
26307         touch $DIR/$tdir/d2/file5
26308
26309         wait
26310         at_max_set $amc client
26311         at_max_set $amo mds1
26312
26313         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26314         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26315                 error "Watchdog is always throttled"
26316 }
26317 run_test 422 "kill a process with RPC in progress"
26318
26319 stat_test() {
26320     df -h $MOUNT &
26321     df -h $MOUNT &
26322     df -h $MOUNT &
26323     df -h $MOUNT &
26324     df -h $MOUNT &
26325     df -h $MOUNT &
26326 }
26327
26328 test_423() {
26329     local _stats
26330     # ensure statfs cache is expired
26331     sleep 2;
26332
26333     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26334     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26335
26336     return 0
26337 }
26338 run_test 423 "statfs should return a right data"
26339
26340 test_424() {
26341 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26342         $LCTL set_param fail_loc=0x80000522
26343         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26344         rm -f $DIR/$tfile
26345 }
26346 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26347
26348 test_425() {
26349         test_mkdir -c -1 $DIR/$tdir
26350         $LFS setstripe -c -1 $DIR/$tdir
26351
26352         lru_resize_disable "" 100
26353         stack_trap "lru_resize_enable" EXIT
26354
26355         sleep 5
26356
26357         for i in $(seq $((MDSCOUNT * 125))); do
26358                 local t=$DIR/$tdir/$tfile_$i
26359
26360                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26361                         error_noexit "Create file $t"
26362         done
26363         stack_trap "rm -rf $DIR/$tdir" EXIT
26364
26365         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26366                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26367                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26368
26369                 [ $lock_count -le $lru_size ] ||
26370                         error "osc lock count $lock_count > lru size $lru_size"
26371         done
26372
26373         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26374                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26375                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26376
26377                 [ $lock_count -le $lru_size ] ||
26378                         error "mdc lock count $lock_count > lru size $lru_size"
26379         done
26380 }
26381 run_test 425 "lock count should not exceed lru size"
26382
26383 test_426() {
26384         splice-test -r $DIR/$tfile
26385         splice-test -rd $DIR/$tfile
26386         splice-test $DIR/$tfile
26387         splice-test -d $DIR/$tfile
26388 }
26389 run_test 426 "splice test on Lustre"
26390
26391 test_427() {
26392         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26393         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26394                 skip "Need MDS version at least 2.12.4"
26395         local log
26396
26397         mkdir $DIR/$tdir
26398         mkdir $DIR/$tdir/1
26399         mkdir $DIR/$tdir/2
26400         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26401         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26402
26403         $LFS getdirstripe $DIR/$tdir/1/dir
26404
26405         #first setfattr for creating updatelog
26406         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26407
26408 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26409         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26410         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26411         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26412
26413         sleep 2
26414         fail mds2
26415         wait_recovery_complete mds2 $((2*TIMEOUT))
26416
26417         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26418         echo $log | grep "get update log failed" &&
26419                 error "update log corruption is detected" || true
26420 }
26421 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26422
26423 test_428() {
26424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26425         local cache_limit=$CACHE_MAX
26426
26427         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26428         $LCTL set_param -n llite.*.max_cached_mb=64
26429
26430         mkdir $DIR/$tdir
26431         $LFS setstripe -c 1 $DIR/$tdir
26432         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26433         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26434         #test write
26435         for f in $(seq 4); do
26436                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26437         done
26438         wait
26439
26440         cancel_lru_locks osc
26441         # Test read
26442         for f in $(seq 4); do
26443                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26444         done
26445         wait
26446 }
26447 run_test 428 "large block size IO should not hang"
26448
26449 test_429() { # LU-7915 / LU-10948
26450         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26451         local testfile=$DIR/$tfile
26452         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26453         local new_flag=1
26454         local first_rpc
26455         local second_rpc
26456         local third_rpc
26457
26458         $LCTL get_param $ll_opencache_threshold_count ||
26459                 skip "client does not have opencache parameter"
26460
26461         set_opencache $new_flag
26462         stack_trap "restore_opencache"
26463         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26464                 error "enable opencache failed"
26465         touch $testfile
26466         # drop MDC DLM locks
26467         cancel_lru_locks mdc
26468         # clear MDC RPC stats counters
26469         $LCTL set_param $mdc_rpcstats=clear
26470
26471         # According to the current implementation, we need to run 3 times
26472         # open & close file to verify if opencache is enabled correctly.
26473         # 1st, RPCs are sent for lookup/open and open handle is released on
26474         #      close finally.
26475         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26476         #      so open handle won't be released thereafter.
26477         # 3rd, No RPC is sent out.
26478         $MULTIOP $testfile oc || error "multiop failed"
26479         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26480         echo "1st: $first_rpc RPCs in flight"
26481
26482         $MULTIOP $testfile oc || error "multiop failed"
26483         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26484         echo "2nd: $second_rpc RPCs in flight"
26485
26486         $MULTIOP $testfile oc || error "multiop failed"
26487         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26488         echo "3rd: $third_rpc RPCs in flight"
26489
26490         #verify no MDC RPC is sent
26491         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26492 }
26493 run_test 429 "verify if opencache flag on client side does work"
26494
26495 lseek_test_430() {
26496         local offset
26497         local file=$1
26498
26499         # data at [200K, 400K)
26500         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26501                 error "256K->512K dd fails"
26502         # data at [2M, 3M)
26503         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26504                 error "2M->3M dd fails"
26505         # data at [4M, 5M)
26506         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26507                 error "4M->5M dd fails"
26508         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26509         # start at first component hole #1
26510         printf "Seeking hole from 1000 ... "
26511         offset=$(lseek_test -l 1000 $file)
26512         echo $offset
26513         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26514         printf "Seeking data from 1000 ... "
26515         offset=$(lseek_test -d 1000 $file)
26516         echo $offset
26517         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26518
26519         # start at first component data block
26520         printf "Seeking hole from 300000 ... "
26521         offset=$(lseek_test -l 300000 $file)
26522         echo $offset
26523         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26524         printf "Seeking data from 300000 ... "
26525         offset=$(lseek_test -d 300000 $file)
26526         echo $offset
26527         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26528
26529         # start at the first component but beyond end of object size
26530         printf "Seeking hole from 1000000 ... "
26531         offset=$(lseek_test -l 1000000 $file)
26532         echo $offset
26533         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26534         printf "Seeking data from 1000000 ... "
26535         offset=$(lseek_test -d 1000000 $file)
26536         echo $offset
26537         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26538
26539         # start at second component stripe 2 (empty file)
26540         printf "Seeking hole from 1500000 ... "
26541         offset=$(lseek_test -l 1500000 $file)
26542         echo $offset
26543         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26544         printf "Seeking data from 1500000 ... "
26545         offset=$(lseek_test -d 1500000 $file)
26546         echo $offset
26547         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26548
26549         # start at second component stripe 1 (all data)
26550         printf "Seeking hole from 3000000 ... "
26551         offset=$(lseek_test -l 3000000 $file)
26552         echo $offset
26553         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26554         printf "Seeking data from 3000000 ... "
26555         offset=$(lseek_test -d 3000000 $file)
26556         echo $offset
26557         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26558
26559         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26560                 error "2nd dd fails"
26561         echo "Add data block at 640K...1280K"
26562
26563         # start at before new data block, in hole
26564         printf "Seeking hole from 600000 ... "
26565         offset=$(lseek_test -l 600000 $file)
26566         echo $offset
26567         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26568         printf "Seeking data from 600000 ... "
26569         offset=$(lseek_test -d 600000 $file)
26570         echo $offset
26571         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26572
26573         # start at the first component new data block
26574         printf "Seeking hole from 1000000 ... "
26575         offset=$(lseek_test -l 1000000 $file)
26576         echo $offset
26577         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26578         printf "Seeking data from 1000000 ... "
26579         offset=$(lseek_test -d 1000000 $file)
26580         echo $offset
26581         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26582
26583         # start at second component stripe 2, new data
26584         printf "Seeking hole from 1200000 ... "
26585         offset=$(lseek_test -l 1200000 $file)
26586         echo $offset
26587         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26588         printf "Seeking data from 1200000 ... "
26589         offset=$(lseek_test -d 1200000 $file)
26590         echo $offset
26591         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26592
26593         # start beyond file end
26594         printf "Using offset > filesize ... "
26595         lseek_test -l 4000000 $file && error "lseek should fail"
26596         printf "Using offset > filesize ... "
26597         lseek_test -d 4000000 $file && error "lseek should fail"
26598
26599         printf "Done\n\n"
26600 }
26601
26602 test_430a() {
26603         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26604                 skip "MDT does not support SEEK_HOLE"
26605
26606         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26607                 skip "OST does not support SEEK_HOLE"
26608
26609         local file=$DIR/$tdir/$tfile
26610
26611         mkdir -p $DIR/$tdir
26612
26613         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26614         # OST stripe #1 will have continuous data at [1M, 3M)
26615         # OST stripe #2 is empty
26616         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26617         lseek_test_430 $file
26618         rm $file
26619         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26620         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26621         lseek_test_430 $file
26622         rm $file
26623         $LFS setstripe -c2 -S 512K $file
26624         echo "Two stripes, stripe size 512K"
26625         lseek_test_430 $file
26626         rm $file
26627         # FLR with stale mirror
26628         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26629                        -N -c2 -S 1M $file
26630         echo "Mirrored file:"
26631         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26632         echo "Plain 2 stripes 1M"
26633         lseek_test_430 $file
26634         rm $file
26635 }
26636 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26637
26638 test_430b() {
26639         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26640                 skip "OST does not support SEEK_HOLE"
26641
26642         local offset
26643         local file=$DIR/$tdir/$tfile
26644
26645         mkdir -p $DIR/$tdir
26646         # Empty layout lseek should fail
26647         $MCREATE $file
26648         # seek from 0
26649         printf "Seeking hole from 0 ... "
26650         lseek_test -l 0 $file && error "lseek should fail"
26651         printf "Seeking data from 0 ... "
26652         lseek_test -d 0 $file && error "lseek should fail"
26653         rm $file
26654
26655         # 1M-hole file
26656         $LFS setstripe -E 1M -c2 -E eof $file
26657         $TRUNCATE $file 1048576
26658         printf "Seeking hole from 1000000 ... "
26659         offset=$(lseek_test -l 1000000 $file)
26660         echo $offset
26661         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26662         printf "Seeking data from 1000000 ... "
26663         lseek_test -d 1000000 $file && error "lseek should fail"
26664         rm $file
26665
26666         # full component followed by non-inited one
26667         $LFS setstripe -E 1M -c2 -E eof $file
26668         dd if=/dev/urandom of=$file bs=1M count=1
26669         printf "Seeking hole from 1000000 ... "
26670         offset=$(lseek_test -l 1000000 $file)
26671         echo $offset
26672         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26673         printf "Seeking hole from 1048576 ... "
26674         lseek_test -l 1048576 $file && error "lseek should fail"
26675         # init second component and truncate back
26676         echo "123" >> $file
26677         $TRUNCATE $file 1048576
26678         printf "Seeking hole from 1000000 ... "
26679         offset=$(lseek_test -l 1000000 $file)
26680         echo $offset
26681         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26682         printf "Seeking hole from 1048576 ... "
26683         lseek_test -l 1048576 $file && error "lseek should fail"
26684         # boundary checks for big values
26685         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26686         offset=$(lseek_test -d 0 $file.10g)
26687         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26688         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26689         offset=$(lseek_test -d 0 $file.100g)
26690         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26691         return 0
26692 }
26693 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26694
26695 test_430c() {
26696         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26697                 skip "OST does not support SEEK_HOLE"
26698
26699         local file=$DIR/$tdir/$tfile
26700         local start
26701
26702         mkdir -p $DIR/$tdir
26703         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26704
26705         # cp version 8.33+ prefers lseek over fiemap
26706         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26707                 start=$SECONDS
26708                 time cp $file /dev/null
26709                 (( SECONDS - start < 5 )) ||
26710                         error "cp: too long runtime $((SECONDS - start))"
26711
26712         fi
26713         # tar version 1.29+ supports SEEK_HOLE/DATA
26714         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26715                 start=$SECONDS
26716                 time tar cS $file - | cat > /dev/null
26717                 (( SECONDS - start < 5 )) ||
26718                         error "tar: too long runtime $((SECONDS - start))"
26719         fi
26720 }
26721 run_test 430c "lseek: external tools check"
26722
26723 test_431() { # LU-14187
26724         local file=$DIR/$tdir/$tfile
26725
26726         mkdir -p $DIR/$tdir
26727         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26728         dd if=/dev/urandom of=$file bs=4k count=1
26729         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26730         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26731         #define OBD_FAIL_OST_RESTART_IO 0x251
26732         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26733         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26734         cp $file $file.0
26735         cancel_lru_locks
26736         sync_all_data
26737         echo 3 > /proc/sys/vm/drop_caches
26738         diff  $file $file.0 || error "data diff"
26739 }
26740 run_test 431 "Restart transaction for IO"
26741
26742 cleanup_test_432() {
26743         do_facet mgs $LCTL nodemap_activate 0
26744         wait_nm_sync active
26745 }
26746
26747 test_432() {
26748         local tmpdir=$TMP/dir432
26749
26750         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26751                 skip "Need MDS version at least 2.14.52"
26752
26753         stack_trap cleanup_test_432 EXIT
26754         mkdir $DIR/$tdir
26755         mkdir $tmpdir
26756
26757         do_facet mgs $LCTL nodemap_activate 1
26758         wait_nm_sync active
26759         do_facet mgs $LCTL nodemap_modify --name default \
26760                 --property admin --value 1
26761         do_facet mgs $LCTL nodemap_modify --name default \
26762                 --property trusted --value 1
26763         cancel_lru_locks mdc
26764         wait_nm_sync default admin_nodemap
26765         wait_nm_sync default trusted_nodemap
26766
26767         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26768                grep -ci "Operation not permitted") -ne 0 ]; then
26769                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26770         fi
26771 }
26772 run_test 432 "mv dir from outside Lustre"
26773
26774 prep_801() {
26775         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26776         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26777                 skip "Need server version at least 2.9.55"
26778
26779         start_full_debug_logging
26780 }
26781
26782 post_801() {
26783         stop_full_debug_logging
26784 }
26785
26786 barrier_stat() {
26787         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26788                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26789                            awk '/The barrier for/ { print $7 }')
26790                 echo $st
26791         else
26792                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26793                 echo \'$st\'
26794         fi
26795 }
26796
26797 barrier_expired() {
26798         local expired
26799
26800         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26801                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26802                           awk '/will be expired/ { print $7 }')
26803         else
26804                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26805         fi
26806
26807         echo $expired
26808 }
26809
26810 test_801a() {
26811         prep_801
26812
26813         echo "Start barrier_freeze at: $(date)"
26814         #define OBD_FAIL_BARRIER_DELAY          0x2202
26815         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26816         # Do not reduce barrier time - See LU-11873
26817         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26818
26819         sleep 2
26820         local b_status=$(barrier_stat)
26821         echo "Got barrier status at: $(date)"
26822         [ "$b_status" = "'freezing_p1'" ] ||
26823                 error "(1) unexpected barrier status $b_status"
26824
26825         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26826         wait
26827         b_status=$(barrier_stat)
26828         [ "$b_status" = "'frozen'" ] ||
26829                 error "(2) unexpected barrier status $b_status"
26830
26831         local expired=$(barrier_expired)
26832         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26833         sleep $((expired + 3))
26834
26835         b_status=$(barrier_stat)
26836         [ "$b_status" = "'expired'" ] ||
26837                 error "(3) unexpected barrier status $b_status"
26838
26839         # Do not reduce barrier time - See LU-11873
26840         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26841                 error "(4) fail to freeze barrier"
26842
26843         b_status=$(barrier_stat)
26844         [ "$b_status" = "'frozen'" ] ||
26845                 error "(5) unexpected barrier status $b_status"
26846
26847         echo "Start barrier_thaw at: $(date)"
26848         #define OBD_FAIL_BARRIER_DELAY          0x2202
26849         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26850         do_facet mgs $LCTL barrier_thaw $FSNAME &
26851
26852         sleep 2
26853         b_status=$(barrier_stat)
26854         echo "Got barrier status at: $(date)"
26855         [ "$b_status" = "'thawing'" ] ||
26856                 error "(6) unexpected barrier status $b_status"
26857
26858         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26859         wait
26860         b_status=$(barrier_stat)
26861         [ "$b_status" = "'thawed'" ] ||
26862                 error "(7) unexpected barrier status $b_status"
26863
26864         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26865         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26866         do_facet mgs $LCTL barrier_freeze $FSNAME
26867
26868         b_status=$(barrier_stat)
26869         [ "$b_status" = "'failed'" ] ||
26870                 error "(8) unexpected barrier status $b_status"
26871
26872         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26873         do_facet mgs $LCTL barrier_thaw $FSNAME
26874
26875         post_801
26876 }
26877 run_test 801a "write barrier user interfaces and stat machine"
26878
26879 test_801b() {
26880         prep_801
26881
26882         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26883         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
26884         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26885         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26886         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26887
26888         cancel_lru_locks mdc
26889
26890         # 180 seconds should be long enough
26891         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26892
26893         local b_status=$(barrier_stat)
26894         [ "$b_status" = "'frozen'" ] ||
26895                 error "(6) unexpected barrier status $b_status"
26896
26897         mkdir $DIR/$tdir/d0/d10 &
26898         mkdir_pid=$!
26899
26900         touch $DIR/$tdir/d1/f13 &
26901         touch_pid=$!
26902
26903         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26904         ln_pid=$!
26905
26906         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26907         mv_pid=$!
26908
26909         rm -f $DIR/$tdir/d4/f12 &
26910         rm_pid=$!
26911
26912         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26913
26914         # To guarantee taht the 'stat' is not blocked
26915         b_status=$(barrier_stat)
26916         [ "$b_status" = "'frozen'" ] ||
26917                 error "(8) unexpected barrier status $b_status"
26918
26919         # let above commands to run at background
26920         sleep 5
26921
26922         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26923         ps -p $touch_pid || error "(10) touch should be blocked"
26924         ps -p $ln_pid || error "(11) link should be blocked"
26925         ps -p $mv_pid || error "(12) rename should be blocked"
26926         ps -p $rm_pid || error "(13) unlink should be blocked"
26927
26928         b_status=$(barrier_stat)
26929         [ "$b_status" = "'frozen'" ] ||
26930                 error "(14) unexpected barrier status $b_status"
26931
26932         do_facet mgs $LCTL barrier_thaw $FSNAME
26933         b_status=$(barrier_stat)
26934         [ "$b_status" = "'thawed'" ] ||
26935                 error "(15) unexpected barrier status $b_status"
26936
26937         wait $mkdir_pid || error "(16) mkdir should succeed"
26938         wait $touch_pid || error "(17) touch should succeed"
26939         wait $ln_pid || error "(18) link should succeed"
26940         wait $mv_pid || error "(19) rename should succeed"
26941         wait $rm_pid || error "(20) unlink should succeed"
26942
26943         post_801
26944 }
26945 run_test 801b "modification will be blocked by write barrier"
26946
26947 test_801c() {
26948         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26949
26950         prep_801
26951
26952         stop mds2 || error "(1) Fail to stop mds2"
26953
26954         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26955
26956         local b_status=$(barrier_stat)
26957         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26958                 do_facet mgs $LCTL barrier_thaw $FSNAME
26959                 error "(2) unexpected barrier status $b_status"
26960         }
26961
26962         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26963                 error "(3) Fail to rescan barrier bitmap"
26964
26965         # Do not reduce barrier time - See LU-11873
26966         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26967
26968         b_status=$(barrier_stat)
26969         [ "$b_status" = "'frozen'" ] ||
26970                 error "(4) unexpected barrier status $b_status"
26971
26972         do_facet mgs $LCTL barrier_thaw $FSNAME
26973         b_status=$(barrier_stat)
26974         [ "$b_status" = "'thawed'" ] ||
26975                 error "(5) unexpected barrier status $b_status"
26976
26977         local devname=$(mdsdevname 2)
26978
26979         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26980
26981         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26982                 error "(7) Fail to rescan barrier bitmap"
26983
26984         post_801
26985 }
26986 run_test 801c "rescan barrier bitmap"
26987
26988 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26989 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26990 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26991 saved_MOUNT_OPTS=$MOUNT_OPTS
26992
26993 cleanup_802a() {
26994         trap 0
26995
26996         stopall
26997         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26998         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26999         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27000         MOUNT_OPTS=$saved_MOUNT_OPTS
27001         setupall
27002 }
27003
27004 test_802a() {
27005         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27006         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27007         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27008                 skip "Need server version at least 2.9.55"
27009
27010         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27011
27012         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27013
27014         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27015                 error "(2) Fail to copy"
27016
27017         trap cleanup_802a EXIT
27018
27019         # sync by force before remount as readonly
27020         sync; sync_all_data; sleep 3; sync_all_data
27021
27022         stopall
27023
27024         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27025         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27026         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27027
27028         echo "Mount the server as read only"
27029         setupall server_only || error "(3) Fail to start servers"
27030
27031         echo "Mount client without ro should fail"
27032         mount_client $MOUNT &&
27033                 error "(4) Mount client without 'ro' should fail"
27034
27035         echo "Mount client with ro should succeed"
27036         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27037         mount_client $MOUNT ||
27038                 error "(5) Mount client with 'ro' should succeed"
27039
27040         echo "Modify should be refused"
27041         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27042
27043         echo "Read should be allowed"
27044         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27045                 error "(7) Read should succeed under ro mode"
27046
27047         cleanup_802a
27048 }
27049 run_test 802a "simulate readonly device"
27050
27051 test_802b() {
27052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27053         remote_mds_nodsh && skip "remote MDS with nodsh"
27054
27055         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27056                 skip "readonly option not available"
27057
27058         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27059
27060         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27061                 error "(2) Fail to copy"
27062
27063         # write back all cached data before setting MDT to readonly
27064         cancel_lru_locks
27065         sync_all_data
27066
27067         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27068         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27069
27070         echo "Modify should be refused"
27071         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27072
27073         echo "Read should be allowed"
27074         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27075                 error "(7) Read should succeed under ro mode"
27076
27077         # disable readonly
27078         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27079 }
27080 run_test 802b "be able to set MDTs to readonly"
27081
27082 test_803a() {
27083         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27084         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27085                 skip "MDS needs to be newer than 2.10.54"
27086
27087         mkdir_on_mdt0 $DIR/$tdir
27088         # Create some objects on all MDTs to trigger related logs objects
27089         for idx in $(seq $MDSCOUNT); do
27090                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27091                         $DIR/$tdir/dir${idx} ||
27092                         error "Fail to create $DIR/$tdir/dir${idx}"
27093         done
27094
27095         sync; sleep 3
27096         wait_delete_completed # ensure old test cleanups are finished
27097         echo "before create:"
27098         $LFS df -i $MOUNT
27099         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27100
27101         for i in {1..10}; do
27102                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27103                         error "Fail to create $DIR/$tdir/foo$i"
27104         done
27105
27106         sync; sleep 3
27107         echo "after create:"
27108         $LFS df -i $MOUNT
27109         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27110
27111         # allow for an llog to be cleaned up during the test
27112         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27113                 error "before ($before_used) + 10 > after ($after_used)"
27114
27115         for i in {1..10}; do
27116                 rm -rf $DIR/$tdir/foo$i ||
27117                         error "Fail to remove $DIR/$tdir/foo$i"
27118         done
27119
27120         sleep 3 # avoid MDT return cached statfs
27121         wait_delete_completed
27122         echo "after unlink:"
27123         $LFS df -i $MOUNT
27124         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27125
27126         # allow for an llog to be created during the test
27127         [ $after_used -le $((before_used + 1)) ] ||
27128                 error "after ($after_used) > before ($before_used) + 1"
27129 }
27130 run_test 803a "verify agent object for remote object"
27131
27132 test_803b() {
27133         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27134         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27135                 skip "MDS needs to be newer than 2.13.56"
27136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27137
27138         for i in $(seq 0 $((MDSCOUNT - 1))); do
27139                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27140         done
27141
27142         local before=0
27143         local after=0
27144
27145         local tmp
27146
27147         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27148         for i in $(seq 0 $((MDSCOUNT - 1))); do
27149                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27150                         awk '/getattr/ { print $2 }')
27151                 before=$((before + tmp))
27152         done
27153         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27154         for i in $(seq 0 $((MDSCOUNT - 1))); do
27155                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27156                         awk '/getattr/ { print $2 }')
27157                 after=$((after + tmp))
27158         done
27159
27160         [ $before -eq $after ] || error "getattr count $before != $after"
27161 }
27162 run_test 803b "remote object can getattr from cache"
27163
27164 test_804() {
27165         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27166         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27167                 skip "MDS needs to be newer than 2.10.54"
27168         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27169
27170         mkdir -p $DIR/$tdir
27171         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27172                 error "Fail to create $DIR/$tdir/dir0"
27173
27174         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27175         local dev=$(mdsdevname 2)
27176
27177         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27178                 grep ${fid} || error "NOT found agent entry for dir0"
27179
27180         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27181                 error "Fail to create $DIR/$tdir/dir1"
27182
27183         touch $DIR/$tdir/dir1/foo0 ||
27184                 error "Fail to create $DIR/$tdir/dir1/foo0"
27185         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27186         local rc=0
27187
27188         for idx in $(seq $MDSCOUNT); do
27189                 dev=$(mdsdevname $idx)
27190                 do_facet mds${idx} \
27191                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27192                         grep ${fid} && rc=$idx
27193         done
27194
27195         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27196                 error "Fail to rename foo0 to foo1"
27197         if [ $rc -eq 0 ]; then
27198                 for idx in $(seq $MDSCOUNT); do
27199                         dev=$(mdsdevname $idx)
27200                         do_facet mds${idx} \
27201                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27202                         grep ${fid} && rc=$idx
27203                 done
27204         fi
27205
27206         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27207                 error "Fail to rename foo1 to foo2"
27208         if [ $rc -eq 0 ]; then
27209                 for idx in $(seq $MDSCOUNT); do
27210                         dev=$(mdsdevname $idx)
27211                         do_facet mds${idx} \
27212                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27213                         grep ${fid} && rc=$idx
27214                 done
27215         fi
27216
27217         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27218
27219         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27220                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27221         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27222                 error "Fail to rename foo2 to foo0"
27223         unlink $DIR/$tdir/dir1/foo0 ||
27224                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27225         rm -rf $DIR/$tdir/dir0 ||
27226                 error "Fail to rm $DIR/$tdir/dir0"
27227
27228         for idx in $(seq $MDSCOUNT); do
27229                 dev=$(mdsdevname $idx)
27230                 rc=0
27231
27232                 stop mds${idx}
27233                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27234                         rc=$?
27235                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27236                         error "mount mds$idx failed"
27237                 df $MOUNT > /dev/null 2>&1
27238
27239                 # e2fsck should not return error
27240                 [ $rc -eq 0 ] ||
27241                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27242         done
27243 }
27244 run_test 804 "verify agent entry for remote entry"
27245
27246 cleanup_805() {
27247         do_facet $SINGLEMDS zfs set quota=$old $fsset
27248         unlinkmany $DIR/$tdir/f- 1000000
27249         trap 0
27250 }
27251
27252 test_805() {
27253         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27254         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27255         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27256                 skip "netfree not implemented before 0.7"
27257         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27258                 skip "Need MDS version at least 2.10.57"
27259
27260         local fsset
27261         local freekb
27262         local usedkb
27263         local old
27264         local quota
27265         local pref="osd-zfs.$FSNAME-MDT0000."
27266
27267         # limit available space on MDS dataset to meet nospace issue
27268         # quickly. then ZFS 0.7.2 can use reserved space if asked
27269         # properly (using netfree flag in osd_declare_destroy()
27270         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27271         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27272                 gawk '{print $3}')
27273         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27274         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27275         let "usedkb=usedkb-freekb"
27276         let "freekb=freekb/2"
27277         if let "freekb > 5000"; then
27278                 let "freekb=5000"
27279         fi
27280         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27281         trap cleanup_805 EXIT
27282         mkdir_on_mdt0 $DIR/$tdir
27283         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27284                 error "Can't set PFL layout"
27285         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27286         rm -rf $DIR/$tdir || error "not able to remove"
27287         do_facet $SINGLEMDS zfs set quota=$old $fsset
27288         trap 0
27289 }
27290 run_test 805 "ZFS can remove from full fs"
27291
27292 # Size-on-MDS test
27293 check_lsom_data()
27294 {
27295         local file=$1
27296         local expect=$(stat -c %s $file)
27297
27298         check_lsom_size $1 $expect
27299
27300         local blocks=$($LFS getsom -b $file)
27301         expect=$(stat -c %b $file)
27302         [[ $blocks == $expect ]] ||
27303                 error "$file expected blocks: $expect, got: $blocks"
27304 }
27305
27306 check_lsom_size()
27307 {
27308         local size
27309         local expect=$2
27310
27311         cancel_lru_locks mdc
27312
27313         size=$($LFS getsom -s $1)
27314         [[ $size == $expect ]] ||
27315                 error "$file expected size: $expect, got: $size"
27316 }
27317
27318 test_806() {
27319         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27320                 skip "Need MDS version at least 2.11.52"
27321
27322         local bs=1048576
27323
27324         touch $DIR/$tfile || error "touch $tfile failed"
27325
27326         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27327         save_lustre_params client "llite.*.xattr_cache" > $save
27328         lctl set_param llite.*.xattr_cache=0
27329         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27330
27331         # single-threaded write
27332         echo "Test SOM for single-threaded write"
27333         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27334                 error "write $tfile failed"
27335         check_lsom_size $DIR/$tfile $bs
27336
27337         local num=32
27338         local size=$(($num * $bs))
27339         local offset=0
27340         local i
27341
27342         echo "Test SOM for single client multi-threaded($num) write"
27343         $TRUNCATE $DIR/$tfile 0
27344         for ((i = 0; i < $num; i++)); do
27345                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27346                 local pids[$i]=$!
27347                 offset=$((offset + $bs))
27348         done
27349         for (( i=0; i < $num; i++ )); do
27350                 wait ${pids[$i]}
27351         done
27352         check_lsom_size $DIR/$tfile $size
27353
27354         $TRUNCATE $DIR/$tfile 0
27355         for ((i = 0; i < $num; i++)); do
27356                 offset=$((offset - $bs))
27357                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27358                 local pids[$i]=$!
27359         done
27360         for (( i=0; i < $num; i++ )); do
27361                 wait ${pids[$i]}
27362         done
27363         check_lsom_size $DIR/$tfile $size
27364
27365         # multi-client writes
27366         num=$(get_node_count ${CLIENTS//,/ })
27367         size=$(($num * $bs))
27368         offset=0
27369         i=0
27370
27371         echo "Test SOM for multi-client ($num) writes"
27372         $TRUNCATE $DIR/$tfile 0
27373         for client in ${CLIENTS//,/ }; do
27374                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27375                 local pids[$i]=$!
27376                 i=$((i + 1))
27377                 offset=$((offset + $bs))
27378         done
27379         for (( i=0; i < $num; i++ )); do
27380                 wait ${pids[$i]}
27381         done
27382         check_lsom_size $DIR/$tfile $offset
27383
27384         i=0
27385         $TRUNCATE $DIR/$tfile 0
27386         for client in ${CLIENTS//,/ }; do
27387                 offset=$((offset - $bs))
27388                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27389                 local pids[$i]=$!
27390                 i=$((i + 1))
27391         done
27392         for (( i=0; i < $num; i++ )); do
27393                 wait ${pids[$i]}
27394         done
27395         check_lsom_size $DIR/$tfile $size
27396
27397         # verify truncate
27398         echo "Test SOM for truncate"
27399         $TRUNCATE $DIR/$tfile 1048576
27400         check_lsom_size $DIR/$tfile 1048576
27401         $TRUNCATE $DIR/$tfile 1234
27402         check_lsom_size $DIR/$tfile 1234
27403
27404         # verify SOM blocks count
27405         echo "Verify SOM block count"
27406         $TRUNCATE $DIR/$tfile 0
27407         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27408                 error "failed to write file $tfile"
27409         check_lsom_data $DIR/$tfile
27410 }
27411 run_test 806 "Verify Lazy Size on MDS"
27412
27413 test_807() {
27414         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27415         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27416                 skip "Need MDS version at least 2.11.52"
27417
27418         # Registration step
27419         changelog_register || error "changelog_register failed"
27420         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27421         changelog_users $SINGLEMDS | grep -q $cl_user ||
27422                 error "User $cl_user not found in changelog_users"
27423
27424         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27425         save_lustre_params client "llite.*.xattr_cache" > $save
27426         lctl set_param llite.*.xattr_cache=0
27427         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27428
27429         rm -rf $DIR/$tdir || error "rm $tdir failed"
27430         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27431         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27432         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27433         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27434                 error "truncate $tdir/trunc failed"
27435
27436         local bs=1048576
27437         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27438                 error "write $tfile failed"
27439
27440         # multi-client wirtes
27441         local num=$(get_node_count ${CLIENTS//,/ })
27442         local offset=0
27443         local i=0
27444
27445         echo "Test SOM for multi-client ($num) writes"
27446         touch $DIR/$tfile || error "touch $tfile failed"
27447         $TRUNCATE $DIR/$tfile 0
27448         for client in ${CLIENTS//,/ }; do
27449                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27450                 local pids[$i]=$!
27451                 i=$((i + 1))
27452                 offset=$((offset + $bs))
27453         done
27454         for (( i=0; i < $num; i++ )); do
27455                 wait ${pids[$i]}
27456         done
27457
27458         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27459         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27460         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27461         check_lsom_data $DIR/$tdir/trunc
27462         check_lsom_data $DIR/$tdir/single_dd
27463         check_lsom_data $DIR/$tfile
27464
27465         rm -rf $DIR/$tdir
27466         # Deregistration step
27467         changelog_deregister || error "changelog_deregister failed"
27468 }
27469 run_test 807 "verify LSOM syncing tool"
27470
27471 check_som_nologged()
27472 {
27473         local lines=$($LFS changelog $FSNAME-MDT0000 |
27474                 grep 'x=trusted.som' | wc -l)
27475         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27476 }
27477
27478 test_808() {
27479         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27480                 skip "Need MDS version at least 2.11.55"
27481
27482         # Registration step
27483         changelog_register || error "changelog_register failed"
27484
27485         touch $DIR/$tfile || error "touch $tfile failed"
27486         check_som_nologged
27487
27488         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27489                 error "write $tfile failed"
27490         check_som_nologged
27491
27492         $TRUNCATE $DIR/$tfile 1234
27493         check_som_nologged
27494
27495         $TRUNCATE $DIR/$tfile 1048576
27496         check_som_nologged
27497
27498         # Deregistration step
27499         changelog_deregister || error "changelog_deregister failed"
27500 }
27501 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27502
27503 check_som_nodata()
27504 {
27505         $LFS getsom $1
27506         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27507 }
27508
27509 test_809() {
27510         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27511                 skip "Need MDS version at least 2.11.56"
27512
27513         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27514                 error "failed to create DoM-only file $DIR/$tfile"
27515         touch $DIR/$tfile || error "touch $tfile failed"
27516         check_som_nodata $DIR/$tfile
27517
27518         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27519                 error "write $tfile failed"
27520         check_som_nodata $DIR/$tfile
27521
27522         $TRUNCATE $DIR/$tfile 1234
27523         check_som_nodata $DIR/$tfile
27524
27525         $TRUNCATE $DIR/$tfile 4097
27526         check_som_nodata $DIR/$file
27527 }
27528 run_test 809 "Verify no SOM xattr store for DoM-only files"
27529
27530 test_810() {
27531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27532         $GSS && skip_env "could not run with gss"
27533         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27534                 skip "OST < 2.12.58 doesn't align checksum"
27535
27536         set_checksums 1
27537         stack_trap "set_checksums $ORIG_CSUM" EXIT
27538         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27539
27540         local csum
27541         local before
27542         local after
27543         for csum in $CKSUM_TYPES; do
27544                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27545                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27546                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27547                         eval set -- $i
27548                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27549                         before=$(md5sum $DIR/$tfile)
27550                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27551                         after=$(md5sum $DIR/$tfile)
27552                         [ "$before" == "$after" ] ||
27553                                 error "$csum: $before != $after bs=$1 seek=$2"
27554                 done
27555         done
27556 }
27557 run_test 810 "partial page writes on ZFS (LU-11663)"
27558
27559 test_812a() {
27560         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27561                 skip "OST < 2.12.51 doesn't support this fail_loc"
27562
27563         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27564         # ensure ost1 is connected
27565         stat $DIR/$tfile >/dev/null || error "can't stat"
27566         wait_osc_import_state client ost1 FULL
27567         # no locks, no reqs to let the connection idle
27568         cancel_lru_locks osc
27569
27570         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27571 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27572         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27573         wait_osc_import_state client ost1 CONNECTING
27574         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27575
27576         stat $DIR/$tfile >/dev/null || error "can't stat file"
27577 }
27578 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27579
27580 test_812b() { # LU-12378
27581         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27582                 skip "OST < 2.12.51 doesn't support this fail_loc"
27583
27584         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27585         # ensure ost1 is connected
27586         stat $DIR/$tfile >/dev/null || error "can't stat"
27587         wait_osc_import_state client ost1 FULL
27588         # no locks, no reqs to let the connection idle
27589         cancel_lru_locks osc
27590
27591         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27592 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27593         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27594         wait_osc_import_state client ost1 CONNECTING
27595         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27596
27597         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27598         wait_osc_import_state client ost1 IDLE
27599 }
27600 run_test 812b "do not drop no resend request for idle connect"
27601
27602 test_812c() {
27603         local old
27604
27605         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27606
27607         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27608         $LFS getstripe $DIR/$tfile
27609         $LCTL set_param osc.*.idle_timeout=10
27610         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27611         # ensure ost1 is connected
27612         stat $DIR/$tfile >/dev/null || error "can't stat"
27613         wait_osc_import_state client ost1 FULL
27614         # no locks, no reqs to let the connection idle
27615         cancel_lru_locks osc
27616
27617 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27618         $LCTL set_param fail_loc=0x80000533
27619         sleep 15
27620         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27621 }
27622 run_test 812c "idle import vs lock enqueue race"
27623
27624 test_813() {
27625         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27626         [ -z "$file_heat_sav" ] && skip "no file heat support"
27627
27628         local readsample
27629         local writesample
27630         local readbyte
27631         local writebyte
27632         local readsample1
27633         local writesample1
27634         local readbyte1
27635         local writebyte1
27636
27637         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27638         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27639
27640         $LCTL set_param -n llite.*.file_heat=1
27641         echo "Turn on file heat"
27642         echo "Period second: $period_second, Decay percentage: $decay_pct"
27643
27644         echo "QQQQ" > $DIR/$tfile
27645         echo "QQQQ" > $DIR/$tfile
27646         echo "QQQQ" > $DIR/$tfile
27647         cat $DIR/$tfile > /dev/null
27648         cat $DIR/$tfile > /dev/null
27649         cat $DIR/$tfile > /dev/null
27650         cat $DIR/$tfile > /dev/null
27651
27652         local out=$($LFS heat_get $DIR/$tfile)
27653
27654         $LFS heat_get $DIR/$tfile
27655         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27656         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27657         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27658         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27659
27660         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27661         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27662         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27663         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27664
27665         sleep $((period_second + 3))
27666         echo "Sleep $((period_second + 3)) seconds..."
27667         # The recursion formula to calculate the heat of the file f is as
27668         # follow:
27669         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27670         # Where Hi is the heat value in the period between time points i*I and
27671         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27672         # to the weight of Ci.
27673         out=$($LFS heat_get $DIR/$tfile)
27674         $LFS heat_get $DIR/$tfile
27675         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27676         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27677         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27678         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27679
27680         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27681                 error "read sample ($readsample) is wrong"
27682         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27683                 error "write sample ($writesample) is wrong"
27684         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27685                 error "read bytes ($readbyte) is wrong"
27686         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27687                 error "write bytes ($writebyte) is wrong"
27688
27689         echo "QQQQ" > $DIR/$tfile
27690         echo "QQQQ" > $DIR/$tfile
27691         echo "QQQQ" > $DIR/$tfile
27692         cat $DIR/$tfile > /dev/null
27693         cat $DIR/$tfile > /dev/null
27694         cat $DIR/$tfile > /dev/null
27695         cat $DIR/$tfile > /dev/null
27696
27697         sleep $((period_second + 3))
27698         echo "Sleep $((period_second + 3)) seconds..."
27699
27700         out=$($LFS heat_get $DIR/$tfile)
27701         $LFS heat_get $DIR/$tfile
27702         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27703         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27704         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27705         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27706
27707         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27708                 4 * $decay_pct) / 100") -eq 1 ] ||
27709                 error "read sample ($readsample1) is wrong"
27710         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27711                 3 * $decay_pct) / 100") -eq 1 ] ||
27712                 error "write sample ($writesample1) is wrong"
27713         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27714                 20 * $decay_pct) / 100") -eq 1 ] ||
27715                 error "read bytes ($readbyte1) is wrong"
27716         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27717                 15 * $decay_pct) / 100") -eq 1 ] ||
27718                 error "write bytes ($writebyte1) is wrong"
27719
27720         echo "Turn off file heat for the file $DIR/$tfile"
27721         $LFS heat_set -o $DIR/$tfile
27722
27723         echo "QQQQ" > $DIR/$tfile
27724         echo "QQQQ" > $DIR/$tfile
27725         echo "QQQQ" > $DIR/$tfile
27726         cat $DIR/$tfile > /dev/null
27727         cat $DIR/$tfile > /dev/null
27728         cat $DIR/$tfile > /dev/null
27729         cat $DIR/$tfile > /dev/null
27730
27731         out=$($LFS heat_get $DIR/$tfile)
27732         $LFS heat_get $DIR/$tfile
27733         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27734         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27735         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27736         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27737
27738         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27739         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27740         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27741         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27742
27743         echo "Trun on file heat for the file $DIR/$tfile"
27744         $LFS heat_set -O $DIR/$tfile
27745
27746         echo "QQQQ" > $DIR/$tfile
27747         echo "QQQQ" > $DIR/$tfile
27748         echo "QQQQ" > $DIR/$tfile
27749         cat $DIR/$tfile > /dev/null
27750         cat $DIR/$tfile > /dev/null
27751         cat $DIR/$tfile > /dev/null
27752         cat $DIR/$tfile > /dev/null
27753
27754         out=$($LFS heat_get $DIR/$tfile)
27755         $LFS heat_get $DIR/$tfile
27756         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27757         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27758         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27759         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27760
27761         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27762         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27763         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27764         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27765
27766         $LFS heat_set -c $DIR/$tfile
27767         $LCTL set_param -n llite.*.file_heat=0
27768         echo "Turn off file heat support for the Lustre filesystem"
27769
27770         echo "QQQQ" > $DIR/$tfile
27771         echo "QQQQ" > $DIR/$tfile
27772         echo "QQQQ" > $DIR/$tfile
27773         cat $DIR/$tfile > /dev/null
27774         cat $DIR/$tfile > /dev/null
27775         cat $DIR/$tfile > /dev/null
27776         cat $DIR/$tfile > /dev/null
27777
27778         out=$($LFS heat_get $DIR/$tfile)
27779         $LFS heat_get $DIR/$tfile
27780         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27781         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27782         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27783         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27784
27785         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27786         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27787         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27788         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27789
27790         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27791         rm -f $DIR/$tfile
27792 }
27793 run_test 813 "File heat verfication"
27794
27795 test_814()
27796 {
27797         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27798         echo -n y >> $DIR/$tfile
27799         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27800         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27801 }
27802 run_test 814 "sparse cp works as expected (LU-12361)"
27803
27804 test_815()
27805 {
27806         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27807         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27808 }
27809 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27810
27811 test_816() {
27812         local ost1_imp=$(get_osc_import_name client ost1)
27813         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27814                          cut -d'.' -f2)
27815
27816         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27817         # ensure ost1 is connected
27818
27819         stat $DIR/$tfile >/dev/null || error "can't stat"
27820         wait_osc_import_state client ost1 FULL
27821         # no locks, no reqs to let the connection idle
27822         cancel_lru_locks osc
27823         lru_resize_disable osc
27824         local before
27825         local now
27826         before=$($LCTL get_param -n \
27827                  ldlm.namespaces.$imp_name.lru_size)
27828
27829         wait_osc_import_state client ost1 IDLE
27830         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27831         now=$($LCTL get_param -n \
27832               ldlm.namespaces.$imp_name.lru_size)
27833         [ $before == $now ] || error "lru_size changed $before != $now"
27834 }
27835 run_test 816 "do not reset lru_resize on idle reconnect"
27836
27837 cleanup_817() {
27838         umount $tmpdir
27839         exportfs -u localhost:$DIR/nfsexp
27840         rm -rf $DIR/nfsexp
27841 }
27842
27843 test_817() {
27844         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27845
27846         mkdir -p $DIR/nfsexp
27847         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27848                 error "failed to export nfs"
27849
27850         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27851         stack_trap cleanup_817 EXIT
27852
27853         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27854                 error "failed to mount nfs to $tmpdir"
27855
27856         cp /bin/true $tmpdir
27857         $DIR/nfsexp/true || error "failed to execute 'true' command"
27858 }
27859 run_test 817 "nfsd won't cache write lock for exec file"
27860
27861 test_818() {
27862         test_mkdir -i0 -c1 $DIR/$tdir
27863         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
27864         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
27865         stop $SINGLEMDS
27866
27867         # restore osp-syn threads
27868         stack_trap "fail $SINGLEMDS"
27869
27870         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27871         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27872         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27873                 error "start $SINGLEMDS failed"
27874         rm -rf $DIR/$tdir
27875
27876         local testid=$(echo $TESTNAME | tr '_' ' ')
27877
27878         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
27879                 grep "run LFSCK" || error "run LFSCK is not suggested"
27880 }
27881 run_test 818 "unlink with failed llog"
27882
27883 test_819a() {
27884         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27885         cancel_lru_locks osc
27886         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27887         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27888         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27889         rm -f $TDIR/$tfile
27890 }
27891 run_test 819a "too big niobuf in read"
27892
27893 test_819b() {
27894         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27895         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27896         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27897         cancel_lru_locks osc
27898         sleep 1
27899         rm -f $TDIR/$tfile
27900 }
27901 run_test 819b "too big niobuf in write"
27902
27903
27904 function test_820_start_ost() {
27905         sleep 5
27906
27907         for num in $(seq $OSTCOUNT); do
27908                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27909         done
27910 }
27911
27912 test_820() {
27913         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27914
27915         mkdir $DIR/$tdir
27916         umount_client $MOUNT || error "umount failed"
27917         for num in $(seq $OSTCOUNT); do
27918                 stop ost$num
27919         done
27920
27921         # mount client with no active OSTs
27922         # so that the client can't initialize max LOV EA size
27923         # from OSC notifications
27924         mount_client $MOUNT || error "mount failed"
27925         # delay OST starting to keep this 0 max EA size for a while
27926         test_820_start_ost &
27927
27928         # create a directory on MDS2
27929         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27930                 error "Failed to create directory"
27931         # open intent should update default EA size
27932         # see mdc_update_max_ea_from_body()
27933         # notice this is the very first RPC to MDS2
27934         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27935         ret=$?
27936         echo $out
27937         # With SSK, this situation can lead to -EPERM being returned.
27938         # In that case, simply retry.
27939         if [ $ret -ne 0 ] && $SHARED_KEY; then
27940                 if echo "$out" | grep -q "not permitted"; then
27941                         cp /etc/services $DIR/$tdir/mds2
27942                         ret=$?
27943                 fi
27944         fi
27945         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27946 }
27947 run_test 820 "update max EA from open intent"
27948
27949 test_822() {
27950         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27951
27952         save_lustre_params mds1 \
27953                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27954         do_facet $SINGLEMDS "$LCTL set_param -n \
27955                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27956         do_facet $SINGLEMDS "$LCTL set_param -n \
27957                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27958
27959         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27960         local maxage=$(do_facet mds1 $LCTL get_param -n \
27961                        osp.$FSNAME-OST0000*MDT0000.maxage)
27962         sleep $((maxage + 1))
27963
27964         #define OBD_FAIL_NET_ERROR_RPC          0x532
27965         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27966
27967         stack_trap "restore_lustre_params < $p; rm $p"
27968
27969         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27970                       osp.$FSNAME-OST0000*MDT0000.create_count")
27971         for i in $(seq 1 $count); do
27972                 touch $DIR/$tfile.${i} || error "touch failed"
27973         done
27974 }
27975 run_test 822 "test precreate failure"
27976
27977 test_823() {
27978         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27979         local OST_MAX_PRECREATE=20000
27980
27981         save_lustre_params mds1 \
27982                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27983         do_facet $SINGLEMDS "$LCTL set_param -n \
27984                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
27985         do_facet $SINGLEMDS "$LCTL set_param -n \
27986                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
27987
27988         stack_trap "restore_lustre_params < $p; rm $p"
27989
27990         do_facet $SINGLEMDS "$LCTL set_param -n \
27991                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
27992
27993         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27994                       osp.$FSNAME-OST0000*MDT0000.create_count")
27995         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27996                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
27997         local expect_count=$(((($max/2)/256) * 256))
27998
27999         log "setting create_count to 100200:"
28000         log " -result- count: $count with max: $max, expecting: $expect_count"
28001
28002         [[ $count -eq expect_count ]] ||
28003                 error "Create count not set to max precreate."
28004 }
28005 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28006
28007 test_831() {
28008         local sync_changes=$(do_facet $SINGLEMDS \
28009                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28010
28011         [ "$sync_changes" -gt 100 ] &&
28012                 skip "Sync changes $sync_changes > 100 already"
28013
28014         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28015
28016         $LFS mkdir -i 0 $DIR/$tdir
28017         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28018
28019         save_lustre_params mds1 \
28020                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28021         save_lustre_params mds1 \
28022                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28023
28024         do_facet mds1 "$LCTL set_param -n \
28025                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28026                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28027         stack_trap "restore_lustre_params < $p" EXIT
28028
28029         createmany -o $DIR/$tdir/f- 1000
28030         unlinkmany $DIR/$tdir/f- 1000 &
28031         local UNLINK_PID=$!
28032
28033         while sleep 1; do
28034                 sync_changes=$(do_facet mds1 \
28035                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28036                 # the check in the code is racy, fail the test
28037                 # if the value above the limit by 10.
28038                 [ $sync_changes -gt 110 ] && {
28039                         kill -2 $UNLINK_PID
28040                         wait
28041                         error "osp changes throttling failed, $sync_changes>110"
28042                 }
28043                 kill -0 $UNLINK_PID 2> /dev/null || break
28044         done
28045         wait
28046 }
28047 run_test 831 "throttling unlink/setattr queuing on OSP"
28048
28049 #
28050 # tests that do cleanup/setup should be run at the end
28051 #
28052
28053 test_900() {
28054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28055         local ls
28056
28057         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28058         $LCTL set_param fail_loc=0x903
28059
28060         cancel_lru_locks MGC
28061
28062         FAIL_ON_ERROR=true cleanup
28063         FAIL_ON_ERROR=true setup
28064 }
28065 run_test 900 "umount should not race with any mgc requeue thread"
28066
28067 # LUS-6253/LU-11185
28068 test_901() {
28069         local old
28070         local count
28071         local oldc
28072         local newc
28073         local olds
28074         local news
28075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28076
28077         # some get_param have a bug to handle dot in param name
28078         cancel_lru_locks MGC
28079         old=$(mount -t lustre | wc -l)
28080         # 1 config+sptlrpc
28081         # 2 params
28082         # 3 nodemap
28083         # 4 IR
28084         old=$((old * 4))
28085         oldc=0
28086         count=0
28087         while [ $old -ne $oldc ]; do
28088                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28089                 sleep 1
28090                 ((count++))
28091                 if [ $count -ge $TIMEOUT ]; then
28092                         error "too large timeout"
28093                 fi
28094         done
28095         umount_client $MOUNT || error "umount failed"
28096         mount_client $MOUNT || error "mount failed"
28097         cancel_lru_locks MGC
28098         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28099
28100         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28101
28102         return 0
28103 }
28104 run_test 901 "don't leak a mgc lock on client umount"
28105
28106 # LU-13377
28107 test_902() {
28108         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28109                 skip "client does not have LU-13377 fix"
28110         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28111         $LCTL set_param fail_loc=0x1415
28112         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28113         cancel_lru_locks osc
28114         rm -f $DIR/$tfile
28115 }
28116 run_test 902 "test short write doesn't hang lustre"
28117
28118 # LU-14711
28119 test_903() {
28120         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28121         echo "blah" > $DIR/${tfile}-2
28122         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28123         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28124         $LCTL set_param fail_loc=0x417 fail_val=20
28125
28126         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28127         sleep 1 # To start the destroy
28128         wait_destroy_complete 150 || error "Destroy taking too long"
28129         cat $DIR/$tfile > /dev/null || error "Evicted"
28130 }
28131 run_test 903 "Test long page discard does not cause evictions"
28132
28133 test_904() {
28134         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28135         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28136                 grep -q project || skip "skip project quota not supported"
28137
28138         local testfile="$DIR/$tdir/$tfile"
28139         local xattr="trusted.projid"
28140         local projid
28141
28142         mkdir -p $DIR/$tdir
28143         touch $testfile
28144         #should be hidden when projid is 0
28145         $LFS project -p 0 $testfile ||
28146                 error "set $testfile project id failed"
28147         getfattr -m - $testfile | grep $xattr &&
28148                 error "do not show trusted.projid with project ID 0"
28149
28150         #still can getxattr explicitly
28151         projid=$(getfattr -n $xattr $testfile |
28152                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28153         [ $projid == "0" ] ||
28154                 error "projid expected 0 not $projid"
28155
28156         #set the projid via setxattr
28157         setfattr -n $xattr -v "1000" $testfile ||
28158                 error "setattr failed with $?"
28159         projid=($($LFS project $testfile))
28160         [ ${projid[0]} == "1000" ] ||
28161                 error "projid expected 1000 not $projid"
28162
28163         #check the new projid via getxattr
28164         $LFS project -p 1001 $testfile ||
28165                 error "set $testfile project id failed"
28166         projid=$(getfattr -n $xattr $testfile |
28167                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28168         [ $projid == "1001" ] ||
28169                 error "projid expected 1001 not $projid"
28170
28171         #try to set invalid projid
28172         setfattr -n $xattr -v "4294967295" $testfile &&
28173                 error "set invalid projid should fail"
28174
28175         #remove the xattr means setting projid to 0
28176         setfattr -x $xattr $testfile ||
28177                 error "setfattr failed with $?"
28178         projid=($($LFS project $testfile))
28179         [ ${projid[0]} == "0" ] ||
28180                 error "projid expected 0 not $projid"
28181
28182         #should be hidden when parent has inherit flag and same projid
28183         $LFS project -srp 1002 $DIR/$tdir ||
28184                 error "set $tdir project id failed"
28185         getfattr -m - $testfile | grep $xattr &&
28186                 error "do not show trusted.projid with inherit flag"
28187
28188         #still can getxattr explicitly
28189         projid=$(getfattr -n $xattr $testfile |
28190                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28191         [ $projid == "1002" ] ||
28192                 error "projid expected 1002 not $projid"
28193 }
28194 run_test 904 "virtual project ID xattr"
28195
28196 complete $SECONDS
28197 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28198 check_and_cleanup_lustre
28199 if [ "$I_MOUNTED" != "yes" ]; then
28200         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28201 fi
28202 exit_status