Whamcloud - gitweb
LU-15548 osd-ldiskfs: hide virtual projid xattr
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11671
61         ALWAYS_EXCEPT+=" 45"
62         # bug number:    LU-14067 LU-14067
63         ALWAYS_EXCEPT+=" 400a     400b"
64 fi
65
66 # skip nfs tests on kernels >= 4.12.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
68         # bug number:   LU-12661
69         ALWAYS_EXCEPT+=" 817"
70 fi
71 # skip cgroup tests on RHEL8.1 kernels until they are fixed
72 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
73       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
74         # bug number:   LU-13063
75         ALWAYS_EXCEPT+=" 411"
76 fi
77
78 #skip ACL tests on RHEL8 and SLES15 until tests changed to use other users
79 if (( $(egrep -cw "^bin|^daemon" /etc/passwd) < 2 )); then
80         # bug number:   LU-15259 LU-15259
81         ALWAYS_EXCEPT+=" 103a  125   154a"
82 fi
83
84 #                                  5              12     8   12  15   (min)"
85 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
86
87 if [ "$mds1_FSTYPE" = "zfs" ]; then
88         # bug number for skipped test:
89         ALWAYS_EXCEPT+="              "
90         #                                               13    (min)"
91         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
92 fi
93
94 if [ "$ost1_FSTYPE" = "zfs" ]; then
95         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
96         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
97 fi
98
99 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
100
101 # Get the SLES distro version
102 #
103 # Returns a version string that should only be used in comparing
104 # strings returned by version_code()
105 sles_version_code()
106 {
107         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
108
109         # All SuSE Linux versions have one decimal. version_code expects two
110         local sles_version=$version.0
111         version_code $sles_version
112 }
113
114 # Check if we are running on Ubuntu or SLES so we can make decisions on
115 # what tests to run
116 if [ -r /etc/SuSE-release ]; then
117         sles_version=$(sles_version_code)
118         [ $sles_version -lt $(version_code 11.4.0) ] &&
119                 # bug number for skipped test: LU-4341
120                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
121         [ $sles_version -lt $(version_code 12.0.0) ] &&
122                 # bug number for skipped test: LU-3703
123                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
124 elif [ -r /etc/os-release ]; then
125         if grep -qi ubuntu /etc/os-release; then
126                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
127                                                 -e 's/^VERSION=//p' \
128                                                 /etc/os-release |
129                                                 awk '{ print $1 }'))
130
131                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
132                         # bug number for skipped test:
133                         #                LU-10334 LU-10366
134                         ALWAYS_EXCEPT+=" 103a     410"
135                 fi
136         fi
137 fi
138
139 build_test_filter
140 FAIL_ON_ERROR=false
141
142 cleanup() {
143         echo -n "cln.."
144         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
145         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
146 }
147 setup() {
148         echo -n "mnt.."
149         load_modules
150         setupall || exit 10
151         echo "done"
152 }
153
154 check_swap_layouts_support()
155 {
156         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
157                 skip "Does not support layout lock."
158 }
159
160 check_swap_layout_no_dom()
161 {
162         local FOLDER=$1
163         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
164         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
165 }
166
167 check_and_setup_lustre
168 DIR=${DIR:-$MOUNT}
169 assert_DIR
170
171 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
172
173 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
174 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
175 rm -rf $DIR/[Rdfs][0-9]*
176
177 # $RUNAS_ID may get set incorrectly somewhere else
178 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
179         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
180
181 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
182
183 if [ "${ONLY}" = "MOUNT" ] ; then
184         echo "Lustre is up, please go on"
185         exit
186 fi
187
188 echo "preparing for tests involving mounts"
189 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
190 touch $EXT2_DEV
191 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
192 echo # add a newline after mke2fs.
193
194 umask 077
195
196 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
197 lctl set_param debug=-1 2> /dev/null || true
198 test_0a() {
199         touch $DIR/$tfile
200         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
201         rm $DIR/$tfile
202         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
203 }
204 run_test 0a "touch; rm ====================="
205
206 test_0b() {
207         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
208         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
209 }
210 run_test 0b "chmod 0755 $DIR ============================="
211
212 test_0c() {
213         $LCTL get_param mdc.*.import | grep "state: FULL" ||
214                 error "import not FULL"
215         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
216                 error "bad target"
217 }
218 run_test 0c "check import proc"
219
220 test_0d() { # LU-3397
221         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
222                 skip "proc exports not supported before 2.10.57"
223
224         local mgs_exp="mgs.MGS.exports"
225         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
226         local exp_client_nid
227         local exp_client_version
228         local exp_val
229         local imp_val
230         local temp_imp=$DIR/$tfile.import
231         local temp_exp=$DIR/$tfile.export
232
233         # save mgc import file to $temp_imp
234         $LCTL get_param mgc.*.import | tee $temp_imp
235         # Check if client uuid is found in MGS export
236         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
237                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
238                         $client_uuid ] &&
239                         break;
240         done
241         # save mgs export file to $temp_exp
242         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
243
244         # Compare the value of field "connect_flags"
245         imp_val=$(grep "connect_flags" $temp_imp)
246         exp_val=$(grep "connect_flags" $temp_exp)
247         [ "$exp_val" == "$imp_val" ] ||
248                 error "export flags '$exp_val' != import flags '$imp_val'"
249
250         # Compare client versions.  Only compare top-3 fields for compatibility
251         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
252         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
253         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
254         [ "$exp_val" == "$imp_val" ] ||
255                 error "exp version '$exp_client_version'($exp_val) != " \
256                         "'$(lustre_build_version client)'($imp_val)"
257 }
258 run_test 0d "check export proc ============================="
259
260 test_0e() { # LU-13417
261         (( $MDSCOUNT > 1 )) ||
262                 skip "We need at least 2 MDTs for this test"
263
264         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
265                 skip "Need server version at least 2.14.51"
266
267         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
268         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
269
270         [ $default_lmv_count -eq 1 ] ||
271                 error "$MOUNT default stripe count $default_lmv_count"
272
273         [ $default_lmv_index -eq -1 ] ||
274                 error "$MOUNT default stripe index $default_lmv_index"
275
276         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
277         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
278
279         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
280         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
281
282         [ $mdt_index1 -eq $mdt_index2 ] &&
283                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
284
285         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
286 }
287 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
288
289 test_1() {
290         test_mkdir $DIR/$tdir
291         test_mkdir $DIR/$tdir/d2
292         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
293         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
294         rmdir $DIR/$tdir/d2
295         rmdir $DIR/$tdir
296         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
297 }
298 run_test 1 "mkdir; remkdir; rmdir"
299
300 test_2() {
301         test_mkdir $DIR/$tdir
302         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
303         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
304         rm -r $DIR/$tdir
305         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
306 }
307 run_test 2 "mkdir; touch; rmdir; check file"
308
309 test_3() {
310         test_mkdir $DIR/$tdir
311         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
312         touch $DIR/$tdir/$tfile
313         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
314         rm -r $DIR/$tdir
315         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
316 }
317 run_test 3 "mkdir; touch; rmdir; check dir"
318
319 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
320 test_4() {
321         test_mkdir -i 1 $DIR/$tdir
322
323         touch $DIR/$tdir/$tfile ||
324                 error "Create file under remote directory failed"
325
326         rmdir $DIR/$tdir &&
327                 error "Expect error removing in-use dir $DIR/$tdir"
328
329         test -d $DIR/$tdir || error "Remote directory disappeared"
330
331         rm -rf $DIR/$tdir || error "remove remote dir error"
332 }
333 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
334
335 test_5() {
336         test_mkdir $DIR/$tdir
337         test_mkdir $DIR/$tdir/d2
338         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
339         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
340         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
341 }
342 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
343
344 test_6a() {
345         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
346         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
347         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
348                 error "$tfile does not have perm 0666 or UID $UID"
349         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
350         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
351                 error "$tfile should be 0666 and owned by UID $UID"
352 }
353 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
354
355 test_6c() {
356         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
357
358         touch $DIR/$tfile
359         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
360         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
361                 error "$tfile should be owned by UID $RUNAS_ID"
362         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
363         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
364                 error "$tfile should be owned by UID $RUNAS_ID"
365 }
366 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
367
368 test_6e() {
369         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
370
371         touch $DIR/$tfile
372         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
373         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
374                 error "$tfile should be owned by GID $UID"
375         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
376         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
377                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
378 }
379 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
380
381 test_6g() {
382         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
383
384         test_mkdir $DIR/$tdir
385         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
386         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
387         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
388         test_mkdir $DIR/$tdir/d/subdir
389         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
390                 error "$tdir/d/subdir should be GID $RUNAS_GID"
391         if [[ $MDSCOUNT -gt 1 ]]; then
392                 # check remote dir sgid inherite
393                 $LFS mkdir -i 0 $DIR/$tdir.local ||
394                         error "mkdir $tdir.local failed"
395                 chmod g+s $DIR/$tdir.local ||
396                         error "chmod $tdir.local failed"
397                 chgrp $RUNAS_GID $DIR/$tdir.local ||
398                         error "chgrp $tdir.local failed"
399                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
400                         error "mkdir $tdir.remote failed"
401                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
402                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
403                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
404                         error "$tdir.remote should be mode 02755"
405         fi
406 }
407 run_test 6g "verify new dir in sgid dir inherits group"
408
409 test_6h() { # bug 7331
410         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
411
412         touch $DIR/$tfile || error "touch failed"
413         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
414         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
415                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
416         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
417                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
418 }
419 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
420
421 test_7a() {
422         test_mkdir $DIR/$tdir
423         $MCREATE $DIR/$tdir/$tfile
424         chmod 0666 $DIR/$tdir/$tfile
425         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
426                 error "$tdir/$tfile should be mode 0666"
427 }
428 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
429
430 test_7b() {
431         if [ ! -d $DIR/$tdir ]; then
432                 test_mkdir $DIR/$tdir
433         fi
434         $MCREATE $DIR/$tdir/$tfile
435         echo -n foo > $DIR/$tdir/$tfile
436         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
437         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
438 }
439 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
440
441 test_8() {
442         test_mkdir $DIR/$tdir
443         touch $DIR/$tdir/$tfile
444         chmod 0666 $DIR/$tdir/$tfile
445         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
446                 error "$tfile mode not 0666"
447 }
448 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
449
450 test_9() {
451         test_mkdir $DIR/$tdir
452         test_mkdir $DIR/$tdir/d2
453         test_mkdir $DIR/$tdir/d2/d3
454         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
455 }
456 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
457
458 test_10() {
459         test_mkdir $DIR/$tdir
460         test_mkdir $DIR/$tdir/d2
461         touch $DIR/$tdir/d2/$tfile
462         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
463                 error "$tdir/d2/$tfile not a file"
464 }
465 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
466
467 test_11() {
468         test_mkdir $DIR/$tdir
469         test_mkdir $DIR/$tdir/d2
470         chmod 0666 $DIR/$tdir/d2
471         chmod 0705 $DIR/$tdir/d2
472         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
473                 error "$tdir/d2 mode not 0705"
474 }
475 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
476
477 test_12() {
478         test_mkdir $DIR/$tdir
479         touch $DIR/$tdir/$tfile
480         chmod 0666 $DIR/$tdir/$tfile
481         chmod 0654 $DIR/$tdir/$tfile
482         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
483                 error "$tdir/d2 mode not 0654"
484 }
485 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
486
487 test_13() {
488         test_mkdir $DIR/$tdir
489         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
490         >  $DIR/$tdir/$tfile
491         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
492                 error "$tdir/$tfile size not 0 after truncate"
493 }
494 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
495
496 test_14() {
497         test_mkdir $DIR/$tdir
498         touch $DIR/$tdir/$tfile
499         rm $DIR/$tdir/$tfile
500         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
501 }
502 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
503
504 test_15() {
505         test_mkdir $DIR/$tdir
506         touch $DIR/$tdir/$tfile
507         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
508         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
509                 error "$tdir/${tfile_2} not a file after rename"
510         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
511 }
512 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
513
514 test_16() {
515         test_mkdir $DIR/$tdir
516         touch $DIR/$tdir/$tfile
517         rm -rf $DIR/$tdir/$tfile
518         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
519 }
520 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
521
522 test_17a() {
523         test_mkdir $DIR/$tdir
524         touch $DIR/$tdir/$tfile
525         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
526         ls -l $DIR/$tdir
527         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
528                 error "$tdir/l-exist not a symlink"
529         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
530                 error "$tdir/l-exist not referencing a file"
531         rm -f $DIR/$tdir/l-exist
532         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
533 }
534 run_test 17a "symlinks: create, remove (real)"
535
536 test_17b() {
537         test_mkdir $DIR/$tdir
538         ln -s no-such-file $DIR/$tdir/l-dangle
539         ls -l $DIR/$tdir
540         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
541                 error "$tdir/l-dangle not referencing no-such-file"
542         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
543                 error "$tdir/l-dangle not referencing non-existent file"
544         rm -f $DIR/$tdir/l-dangle
545         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
546 }
547 run_test 17b "symlinks: create, remove (dangling)"
548
549 test_17c() { # bug 3440 - don't save failed open RPC for replay
550         test_mkdir $DIR/$tdir
551         ln -s foo $DIR/$tdir/$tfile
552         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
553 }
554 run_test 17c "symlinks: open dangling (should return error)"
555
556 test_17d() {
557         test_mkdir $DIR/$tdir
558         ln -s foo $DIR/$tdir/$tfile
559         touch $DIR/$tdir/$tfile || error "creating to new symlink"
560 }
561 run_test 17d "symlinks: create dangling"
562
563 test_17e() {
564         test_mkdir $DIR/$tdir
565         local foo=$DIR/$tdir/$tfile
566         ln -s $foo $foo || error "create symlink failed"
567         ls -l $foo || error "ls -l failed"
568         ls $foo && error "ls not failed" || true
569 }
570 run_test 17e "symlinks: create recursive symlink (should return error)"
571
572 test_17f() {
573         test_mkdir $DIR/$tdir
574         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
575         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
576         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
577         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
578         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
579         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
580         ls -l  $DIR/$tdir
581 }
582 run_test 17f "symlinks: long and very long symlink name"
583
584 # str_repeat(S, N) generate a string that is string S repeated N times
585 str_repeat() {
586         local s=$1
587         local n=$2
588         local ret=''
589         while [ $((n -= 1)) -ge 0 ]; do
590                 ret=$ret$s
591         done
592         echo $ret
593 }
594
595 # Long symlinks and LU-2241
596 test_17g() {
597         test_mkdir $DIR/$tdir
598         local TESTS="59 60 61 4094 4095"
599
600         # Fix for inode size boundary in 2.1.4
601         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
602                 TESTS="4094 4095"
603
604         # Patch not applied to 2.2 or 2.3 branches
605         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
606         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
607                 TESTS="4094 4095"
608
609         for i in $TESTS; do
610                 local SYMNAME=$(str_repeat 'x' $i)
611                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
612                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
613         done
614 }
615 run_test 17g "symlinks: really long symlink name and inode boundaries"
616
617 test_17h() { #bug 17378
618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
619         remote_mds_nodsh && skip "remote MDS with nodsh"
620
621         local mdt_idx
622
623         test_mkdir $DIR/$tdir
624         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
625         $LFS setstripe -c -1 $DIR/$tdir
626         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
627         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
628         touch $DIR/$tdir/$tfile || true
629 }
630 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
631
632 test_17i() { #bug 20018
633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
634         remote_mds_nodsh && skip "remote MDS with nodsh"
635
636         local foo=$DIR/$tdir/$tfile
637         local mdt_idx
638
639         test_mkdir -c1 $DIR/$tdir
640         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
641         ln -s $foo $foo || error "create symlink failed"
642 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
643         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
644         ls -l $foo && error "error not detected"
645         return 0
646 }
647 run_test 17i "don't panic on short symlink (should return error)"
648
649 test_17k() { #bug 22301
650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
651         [[ -z "$(which rsync 2>/dev/null)" ]] &&
652                 skip "no rsync command"
653         rsync --help | grep -q xattr ||
654                 skip_env "$(rsync --version | head -n1) does not support xattrs"
655         test_mkdir $DIR/$tdir
656         test_mkdir $DIR/$tdir.new
657         touch $DIR/$tdir/$tfile
658         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
659         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
660                 error "rsync failed with xattrs enabled"
661 }
662 run_test 17k "symlinks: rsync with xattrs enabled"
663
664 test_17l() { # LU-279
665         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
666                 skip "no getfattr command"
667
668         test_mkdir $DIR/$tdir
669         touch $DIR/$tdir/$tfile
670         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
671         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
672                 # -h to not follow symlinks. -m '' to list all the xattrs.
673                 # grep to remove first line: '# file: $path'.
674                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
675                 do
676                         lgetxattr_size_check $path $xattr ||
677                                 error "lgetxattr_size_check $path $xattr failed"
678                 done
679         done
680 }
681 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
682
683 # LU-1540
684 test_17m() {
685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
686         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
687         remote_mds_nodsh && skip "remote MDS with nodsh"
688         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
689         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
690                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
691
692         local short_sym="0123456789"
693         local wdir=$DIR/$tdir
694         local i
695
696         test_mkdir $wdir
697         long_sym=$short_sym
698         # create a long symlink file
699         for ((i = 0; i < 4; ++i)); do
700                 long_sym=${long_sym}${long_sym}
701         done
702
703         echo "create 512 short and long symlink files under $wdir"
704         for ((i = 0; i < 256; ++i)); do
705                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
706                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
707         done
708
709         echo "erase them"
710         rm -f $wdir/*
711         sync
712         wait_delete_completed
713
714         echo "recreate the 512 symlink files with a shorter string"
715         for ((i = 0; i < 512; ++i)); do
716                 # rewrite the symlink file with a shorter string
717                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
718                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
719         done
720
721         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
722
723         echo "stop and checking mds${mds_index}:"
724         # e2fsck should not return error
725         stop mds${mds_index}
726         local devname=$(mdsdevname $mds_index)
727         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
728         rc=$?
729
730         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
731                 error "start mds${mds_index} failed"
732         df $MOUNT > /dev/null 2>&1
733         [ $rc -eq 0 ] ||
734                 error "e2fsck detected error for short/long symlink: rc=$rc"
735         rm -f $wdir/*
736 }
737 run_test 17m "run e2fsck against MDT which contains short/long symlink"
738
739 check_fs_consistency_17n() {
740         local mdt_index
741         local rc=0
742
743         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
744         # so it only check MDT1/MDT2 instead of all of MDTs.
745         for mdt_index in 1 2; do
746                 # e2fsck should not return error
747                 stop mds${mdt_index}
748                 local devname=$(mdsdevname $mdt_index)
749                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
750                         rc=$((rc + $?))
751
752                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
753                         error "mount mds$mdt_index failed"
754                 df $MOUNT > /dev/null 2>&1
755         done
756         return $rc
757 }
758
759 test_17n() {
760         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
762         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
763         remote_mds_nodsh && skip "remote MDS with nodsh"
764         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
765         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
766                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
767
768         local i
769
770         test_mkdir $DIR/$tdir
771         for ((i=0; i<10; i++)); do
772                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
773                         error "create remote dir error $i"
774                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
775                         error "create files under remote dir failed $i"
776         done
777
778         check_fs_consistency_17n ||
779                 error "e2fsck report error after create files under remote dir"
780
781         for ((i = 0; i < 10; i++)); do
782                 rm -rf $DIR/$tdir/remote_dir_${i} ||
783                         error "destroy remote dir error $i"
784         done
785
786         check_fs_consistency_17n ||
787                 error "e2fsck report error after unlink files under remote dir"
788
789         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
790                 skip "lustre < 2.4.50 does not support migrate mv"
791
792         for ((i = 0; i < 10; i++)); do
793                 mkdir -p $DIR/$tdir/remote_dir_${i}
794                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
795                         error "create files under remote dir failed $i"
796                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
797                         error "migrate remote dir error $i"
798         done
799         check_fs_consistency_17n || error "e2fsck report error after migration"
800
801         for ((i = 0; i < 10; i++)); do
802                 rm -rf $DIR/$tdir/remote_dir_${i} ||
803                         error "destroy remote dir error $i"
804         done
805
806         check_fs_consistency_17n || error "e2fsck report error after unlink"
807 }
808 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
809
810 test_17o() {
811         remote_mds_nodsh && skip "remote MDS with nodsh"
812         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
813                 skip "Need MDS version at least 2.3.64"
814
815         local wdir=$DIR/${tdir}o
816         local mdt_index
817         local rc=0
818
819         test_mkdir $wdir
820         touch $wdir/$tfile
821         mdt_index=$($LFS getstripe -m $wdir/$tfile)
822         mdt_index=$((mdt_index + 1))
823
824         cancel_lru_locks mdc
825         #fail mds will wait the failover finish then set
826         #following fail_loc to avoid interfer the recovery process.
827         fail mds${mdt_index}
828
829         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
830         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
831         ls -l $wdir/$tfile && rc=1
832         do_facet mds${mdt_index} lctl set_param fail_loc=0
833         [[ $rc -eq 0 ]] || error "stat file should fail"
834 }
835 run_test 17o "stat file with incompat LMA feature"
836
837 test_18() {
838         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
839         ls $DIR || error "Failed to ls $DIR: $?"
840 }
841 run_test 18 "touch .../f ; ls ... =============================="
842
843 test_19a() {
844         touch $DIR/$tfile
845         ls -l $DIR
846         rm $DIR/$tfile
847         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
848 }
849 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
850
851 test_19b() {
852         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
853 }
854 run_test 19b "ls -l .../f19 (should return error) =============="
855
856 test_19c() {
857         [ $RUNAS_ID -eq $UID ] &&
858                 skip_env "RUNAS_ID = UID = $UID -- skipping"
859
860         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
861 }
862 run_test 19c "$RUNAS touch .../f19 (should return error) =="
863
864 test_19d() {
865         cat $DIR/f19 && error || true
866 }
867 run_test 19d "cat .../f19 (should return error) =============="
868
869 test_20() {
870         touch $DIR/$tfile
871         rm $DIR/$tfile
872         touch $DIR/$tfile
873         rm $DIR/$tfile
874         touch $DIR/$tfile
875         rm $DIR/$tfile
876         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
877 }
878 run_test 20 "touch .../f ; ls -l ..."
879
880 test_21() {
881         test_mkdir $DIR/$tdir
882         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
883         ln -s dangle $DIR/$tdir/link
884         echo foo >> $DIR/$tdir/link
885         cat $DIR/$tdir/dangle
886         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
887         $CHECKSTAT -f -t file $DIR/$tdir/link ||
888                 error "$tdir/link not linked to a file"
889 }
890 run_test 21 "write to dangling link"
891
892 test_22() {
893         local wdir=$DIR/$tdir
894         test_mkdir $wdir
895         chown $RUNAS_ID:$RUNAS_GID $wdir
896         (cd $wdir || error "cd $wdir failed";
897                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
898                 $RUNAS tar xf -)
899         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
900         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
901         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
902                 error "checkstat -u failed"
903 }
904 run_test 22 "unpack tar archive as non-root user"
905
906 # was test_23
907 test_23a() {
908         test_mkdir $DIR/$tdir
909         local file=$DIR/$tdir/$tfile
910
911         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
912         openfile -f O_CREAT:O_EXCL $file &&
913                 error "$file recreate succeeded" || true
914 }
915 run_test 23a "O_CREAT|O_EXCL in subdir"
916
917 test_23b() { # bug 18988
918         test_mkdir $DIR/$tdir
919         local file=$DIR/$tdir/$tfile
920
921         rm -f $file
922         echo foo > $file || error "write filed"
923         echo bar >> $file || error "append filed"
924         $CHECKSTAT -s 8 $file || error "wrong size"
925         rm $file
926 }
927 run_test 23b "O_APPEND check"
928
929 # LU-9409, size with O_APPEND and tiny writes
930 test_23c() {
931         local file=$DIR/$tfile
932
933         # single dd
934         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
935         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
936         rm -f $file
937
938         # racing tiny writes
939         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
940         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
941         wait
942         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
943         rm -f $file
944
945         #racing tiny & normal writes
946         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
947         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
948         wait
949         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
950         rm -f $file
951
952         #racing tiny & normal writes 2, ugly numbers
953         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
954         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
955         wait
956         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
957         rm -f $file
958 }
959 run_test 23c "O_APPEND size checks for tiny writes"
960
961 # LU-11069 file offset is correct after appending writes
962 test_23d() {
963         local file=$DIR/$tfile
964         local offset
965
966         echo CentaurHauls > $file
967         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
968         if ((offset != 26)); then
969                 error "wrong offset, expected 26, got '$offset'"
970         fi
971 }
972 run_test 23d "file offset is correct after appending writes"
973
974 # rename sanity
975 test_24a() {
976         echo '-- same directory rename'
977         test_mkdir $DIR/$tdir
978         touch $DIR/$tdir/$tfile.1
979         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
980         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
981 }
982 run_test 24a "rename file to non-existent target"
983
984 test_24b() {
985         test_mkdir $DIR/$tdir
986         touch $DIR/$tdir/$tfile.{1,2}
987         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
988         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
989         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
990 }
991 run_test 24b "rename file to existing target"
992
993 test_24c() {
994         test_mkdir $DIR/$tdir
995         test_mkdir $DIR/$tdir/d$testnum.1
996         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
997         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
998         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
999 }
1000 run_test 24c "rename directory to non-existent target"
1001
1002 test_24d() {
1003         test_mkdir -c1 $DIR/$tdir
1004         test_mkdir -c1 $DIR/$tdir/d$testnum.1
1005         test_mkdir -c1 $DIR/$tdir/d$testnum.2
1006         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1007         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1008         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1009 }
1010 run_test 24d "rename directory to existing target"
1011
1012 test_24e() {
1013         echo '-- cross directory renames --'
1014         test_mkdir $DIR/R5a
1015         test_mkdir $DIR/R5b
1016         touch $DIR/R5a/f
1017         mv $DIR/R5a/f $DIR/R5b/g
1018         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1019         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1020 }
1021 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1022
1023 test_24f() {
1024         test_mkdir $DIR/R6a
1025         test_mkdir $DIR/R6b
1026         touch $DIR/R6a/f $DIR/R6b/g
1027         mv $DIR/R6a/f $DIR/R6b/g
1028         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1029         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1030 }
1031 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1032
1033 test_24g() {
1034         test_mkdir $DIR/R7a
1035         test_mkdir $DIR/R7b
1036         test_mkdir $DIR/R7a/d
1037         mv $DIR/R7a/d $DIR/R7b/e
1038         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1039         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1040 }
1041 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1042
1043 test_24h() {
1044         test_mkdir -c1 $DIR/R8a
1045         test_mkdir -c1 $DIR/R8b
1046         test_mkdir -c1 $DIR/R8a/d
1047         test_mkdir -c1 $DIR/R8b/e
1048         mrename $DIR/R8a/d $DIR/R8b/e
1049         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1050         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1051 }
1052 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1053
1054 test_24i() {
1055         echo "-- rename error cases"
1056         test_mkdir $DIR/R9
1057         test_mkdir $DIR/R9/a
1058         touch $DIR/R9/f
1059         mrename $DIR/R9/f $DIR/R9/a
1060         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1061         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1062         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1063 }
1064 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1065
1066 test_24j() {
1067         test_mkdir $DIR/R10
1068         mrename $DIR/R10/f $DIR/R10/g
1069         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1070         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1071         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1072 }
1073 run_test 24j "source does not exist ============================"
1074
1075 test_24k() {
1076         test_mkdir $DIR/R11a
1077         test_mkdir $DIR/R11a/d
1078         touch $DIR/R11a/f
1079         mv $DIR/R11a/f $DIR/R11a/d
1080         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1081         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1082 }
1083 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1084
1085 # bug 2429 - rename foo foo foo creates invalid file
1086 test_24l() {
1087         f="$DIR/f24l"
1088         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1089 }
1090 run_test 24l "Renaming a file to itself ========================"
1091
1092 test_24m() {
1093         f="$DIR/f24m"
1094         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1095         # on ext3 this does not remove either the source or target files
1096         # though the "expected" operation would be to remove the source
1097         $CHECKSTAT -t file ${f} || error "${f} missing"
1098         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1099 }
1100 run_test 24m "Renaming a file to a hard link to itself ========="
1101
1102 test_24n() {
1103     f="$DIR/f24n"
1104     # this stats the old file after it was renamed, so it should fail
1105     touch ${f}
1106     $CHECKSTAT ${f} || error "${f} missing"
1107     mv ${f} ${f}.rename
1108     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1109     $CHECKSTAT -a ${f} || error "${f} exists"
1110 }
1111 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1112
1113 test_24o() {
1114         test_mkdir $DIR/$tdir
1115         rename_many -s random -v -n 10 $DIR/$tdir
1116 }
1117 run_test 24o "rename of files during htree split"
1118
1119 test_24p() {
1120         test_mkdir $DIR/R12a
1121         test_mkdir $DIR/R12b
1122         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1123         mrename $DIR/R12a $DIR/R12b
1124         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1125         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1126         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1127         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1128 }
1129 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1130
1131 cleanup_multiop_pause() {
1132         trap 0
1133         kill -USR1 $MULTIPID
1134 }
1135
1136 test_24q() {
1137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1138
1139         test_mkdir $DIR/R13a
1140         test_mkdir $DIR/R13b
1141         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1142         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1143         MULTIPID=$!
1144
1145         trap cleanup_multiop_pause EXIT
1146         mrename $DIR/R13a $DIR/R13b
1147         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1148         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1149         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1150         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1151         cleanup_multiop_pause
1152         wait $MULTIPID || error "multiop close failed"
1153 }
1154 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1155
1156 test_24r() { #bug 3789
1157         test_mkdir $DIR/R14a
1158         test_mkdir $DIR/R14a/b
1159         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1160         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1161         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1162 }
1163 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1164
1165 test_24s() {
1166         test_mkdir $DIR/R15a
1167         test_mkdir $DIR/R15a/b
1168         test_mkdir $DIR/R15a/b/c
1169         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1170         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1171         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1172 }
1173 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1174 test_24t() {
1175         test_mkdir $DIR/R16a
1176         test_mkdir $DIR/R16a/b
1177         test_mkdir $DIR/R16a/b/c
1178         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1179         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1180         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1181 }
1182 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1183
1184 test_24u() { # bug12192
1185         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1186         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1187 }
1188 run_test 24u "create stripe file"
1189
1190 simple_cleanup_common() {
1191         local createmany=$1
1192         local rc=0
1193
1194         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1195
1196         local start=$SECONDS
1197
1198         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1199         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1200         rc=$?
1201         wait_delete_completed
1202         echo "cleanup time $((SECONDS - start))"
1203         return $rc
1204 }
1205
1206 max_pages_per_rpc() {
1207         local mdtname="$(printf "MDT%04x" ${1:-0})"
1208         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1209 }
1210
1211 test_24v() {
1212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1213
1214         local nrfiles=${COUNT:-100000}
1215         local fname="$DIR/$tdir/$tfile"
1216
1217         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1218         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1219
1220         test_mkdir "$(dirname $fname)"
1221         # assume MDT0000 has the fewest inodes
1222         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1223         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1224         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1225
1226         stack_trap "simple_cleanup_common $nrfiles"
1227
1228         createmany -m "$fname" $nrfiles
1229
1230         cancel_lru_locks mdc
1231         lctl set_param mdc.*.stats clear
1232
1233         # was previously test_24D: LU-6101
1234         # readdir() returns correct number of entries after cursor reload
1235         local num_ls=$(ls $DIR/$tdir | wc -l)
1236         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1237         local num_all=$(ls -a $DIR/$tdir | wc -l)
1238         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1239                 [ $num_all -ne $((nrfiles + 2)) ]; then
1240                         error "Expected $nrfiles files, got $num_ls " \
1241                                 "($num_uniq unique $num_all .&..)"
1242         fi
1243         # LU-5 large readdir
1244         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1245         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1246         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1247         # take into account of overhead in lu_dirpage header and end mark in
1248         # each page, plus one in rpc_num calculation.
1249         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1250         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1251         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1252         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1253         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1254         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1255         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1256         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1257                 error "large readdir doesn't take effect: " \
1258                       "$mds_readpage should be about $rpc_max"
1259 }
1260 run_test 24v "list large directory (test hash collision, b=17560)"
1261
1262 test_24w() { # bug21506
1263         SZ1=234852
1264         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1265         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1266         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1267         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1268         [[ "$SZ1" -eq "$SZ2" ]] ||
1269                 error "Error reading at the end of the file $tfile"
1270 }
1271 run_test 24w "Reading a file larger than 4Gb"
1272
1273 test_24x() {
1274         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1276         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1277                 skip "Need MDS version at least 2.7.56"
1278
1279         local MDTIDX=1
1280         local remote_dir=$DIR/$tdir/remote_dir
1281
1282         test_mkdir $DIR/$tdir
1283         $LFS mkdir -i $MDTIDX $remote_dir ||
1284                 error "create remote directory failed"
1285
1286         test_mkdir $DIR/$tdir/src_dir
1287         touch $DIR/$tdir/src_file
1288         test_mkdir $remote_dir/tgt_dir
1289         touch $remote_dir/tgt_file
1290
1291         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1292                 error "rename dir cross MDT failed!"
1293
1294         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1295                 error "rename file cross MDT failed!"
1296
1297         touch $DIR/$tdir/ln_file
1298         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1299                 error "ln file cross MDT failed"
1300
1301         rm -rf $DIR/$tdir || error "Can not delete directories"
1302 }
1303 run_test 24x "cross MDT rename/link"
1304
1305 test_24y() {
1306         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1308
1309         local remote_dir=$DIR/$tdir/remote_dir
1310         local mdtidx=1
1311
1312         test_mkdir $DIR/$tdir
1313         $LFS mkdir -i $mdtidx $remote_dir ||
1314                 error "create remote directory failed"
1315
1316         test_mkdir $remote_dir/src_dir
1317         touch $remote_dir/src_file
1318         test_mkdir $remote_dir/tgt_dir
1319         touch $remote_dir/tgt_file
1320
1321         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1322                 error "rename subdir in the same remote dir failed!"
1323
1324         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1325                 error "rename files in the same remote dir failed!"
1326
1327         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1328                 error "link files in the same remote dir failed!"
1329
1330         rm -rf $DIR/$tdir || error "Can not delete directories"
1331 }
1332 run_test 24y "rename/link on the same dir should succeed"
1333
1334 test_24z() {
1335         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1336         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1337                 skip "Need MDS version at least 2.12.51"
1338
1339         local index
1340
1341         for index in 0 1; do
1342                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1343                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1344         done
1345
1346         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1347
1348         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1349         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1350
1351         local mdts=$(comma_list $(mdts_nodes))
1352
1353         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1354         stack_trap "do_nodes $mdts $LCTL \
1355                 set_param mdt.*.enable_remote_rename=1" EXIT
1356
1357         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1358
1359         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1360         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1361 }
1362 run_test 24z "cross-MDT rename is done as cp"
1363
1364 test_24A() { # LU-3182
1365         local NFILES=5000
1366
1367         test_mkdir $DIR/$tdir
1368         stack_trap "simple_cleanup_common $NFILES"
1369         createmany -m $DIR/$tdir/$tfile $NFILES
1370         local t=$(ls $DIR/$tdir | wc -l)
1371         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1372         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1373
1374         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1375                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1376 }
1377 run_test 24A "readdir() returns correct number of entries."
1378
1379 test_24B() { # LU-4805
1380         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1381
1382         local count
1383
1384         test_mkdir $DIR/$tdir
1385         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1386                 error "create striped dir failed"
1387
1388         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1389         [ $count -eq 2 ] || error "Expected 2, got $count"
1390
1391         touch $DIR/$tdir/striped_dir/a
1392
1393         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1394         [ $count -eq 3 ] || error "Expected 3, got $count"
1395
1396         touch $DIR/$tdir/striped_dir/.f
1397
1398         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1399         [ $count -eq 4 ] || error "Expected 4, got $count"
1400
1401         rm -rf $DIR/$tdir || error "Can not delete directories"
1402 }
1403 run_test 24B "readdir for striped dir return correct number of entries"
1404
1405 test_24C() {
1406         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1407
1408         mkdir $DIR/$tdir
1409         mkdir $DIR/$tdir/d0
1410         mkdir $DIR/$tdir/d1
1411
1412         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1413                 error "create striped dir failed"
1414
1415         cd $DIR/$tdir/d0/striped_dir
1416
1417         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1418         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1419         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1420
1421         [ "$d0_ino" = "$parent_ino" ] ||
1422                 error ".. wrong, expect $d0_ino, get $parent_ino"
1423
1424         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1425                 error "mv striped dir failed"
1426
1427         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1428
1429         [ "$d1_ino" = "$parent_ino" ] ||
1430                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1431 }
1432 run_test 24C "check .. in striped dir"
1433
1434 test_24E() {
1435         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1437
1438         mkdir -p $DIR/$tdir
1439         mkdir $DIR/$tdir/src_dir
1440         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1441                 error "create remote source failed"
1442
1443         touch $DIR/$tdir/src_dir/src_child/a
1444
1445         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1446                 error "create remote target dir failed"
1447
1448         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1449                 error "create remote target child failed"
1450
1451         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1452                 error "rename dir cross MDT failed!"
1453
1454         find $DIR/$tdir
1455
1456         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1457                 error "src_child still exists after rename"
1458
1459         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1460                 error "missing file(a) after rename"
1461
1462         rm -rf $DIR/$tdir || error "Can not delete directories"
1463 }
1464 run_test 24E "cross MDT rename/link"
1465
1466 test_24F () {
1467         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1468
1469         local repeats=1000
1470         [ "$SLOW" = "no" ] && repeats=100
1471
1472         mkdir -p $DIR/$tdir
1473
1474         echo "$repeats repeats"
1475         for ((i = 0; i < repeats; i++)); do
1476                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1477                 touch $DIR/$tdir/test/a || error "touch fails"
1478                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1479                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1480         done
1481
1482         true
1483 }
1484 run_test 24F "hash order vs readdir (LU-11330)"
1485
1486 test_24G () {
1487         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1488
1489         local ino1
1490         local ino2
1491
1492         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1493         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1494         touch $DIR/$tdir-0/f1 || error "touch f1"
1495         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1496         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1497         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1498         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1499         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1500 }
1501 run_test 24G "migrate symlink in rename"
1502
1503 test_24H() {
1504         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1505         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1506                 skip "MDT1 should be on another node"
1507
1508         test_mkdir -i 1 -c 1 $DIR/$tdir
1509 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1510         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1511         touch $DIR/$tdir/$tfile || error "touch failed"
1512 }
1513 run_test 24H "repeat FLD_QUERY rpc"
1514
1515 test_25a() {
1516         echo '== symlink sanity ============================================='
1517
1518         test_mkdir $DIR/d25
1519         ln -s d25 $DIR/s25
1520         touch $DIR/s25/foo ||
1521                 error "File creation in symlinked directory failed"
1522 }
1523 run_test 25a "create file in symlinked directory ==============="
1524
1525 test_25b() {
1526         [ ! -d $DIR/d25 ] && test_25a
1527         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1528 }
1529 run_test 25b "lookup file in symlinked directory ==============="
1530
1531 test_26a() {
1532         test_mkdir $DIR/d26
1533         test_mkdir $DIR/d26/d26-2
1534         ln -s d26/d26-2 $DIR/s26
1535         touch $DIR/s26/foo || error "File creation failed"
1536 }
1537 run_test 26a "multiple component symlink ======================="
1538
1539 test_26b() {
1540         test_mkdir -p $DIR/$tdir/d26-2
1541         ln -s $tdir/d26-2/foo $DIR/s26-2
1542         touch $DIR/s26-2 || error "File creation failed"
1543 }
1544 run_test 26b "multiple component symlink at end of lookup ======"
1545
1546 test_26c() {
1547         test_mkdir $DIR/d26.2
1548         touch $DIR/d26.2/foo
1549         ln -s d26.2 $DIR/s26.2-1
1550         ln -s s26.2-1 $DIR/s26.2-2
1551         ln -s s26.2-2 $DIR/s26.2-3
1552         chmod 0666 $DIR/s26.2-3/foo
1553 }
1554 run_test 26c "chain of symlinks"
1555
1556 # recursive symlinks (bug 439)
1557 test_26d() {
1558         ln -s d26-3/foo $DIR/d26-3
1559 }
1560 run_test 26d "create multiple component recursive symlink"
1561
1562 test_26e() {
1563         [ ! -h $DIR/d26-3 ] && test_26d
1564         rm $DIR/d26-3
1565 }
1566 run_test 26e "unlink multiple component recursive symlink"
1567
1568 # recursive symlinks (bug 7022)
1569 test_26f() {
1570         test_mkdir $DIR/$tdir
1571         test_mkdir $DIR/$tdir/$tfile
1572         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1573         test_mkdir -p lndir/bar1
1574         test_mkdir $DIR/$tdir/$tfile/$tfile
1575         cd $tfile                || error "cd $tfile failed"
1576         ln -s .. dotdot          || error "ln dotdot failed"
1577         ln -s dotdot/lndir lndir || error "ln lndir failed"
1578         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1579         output=`ls $tfile/$tfile/lndir/bar1`
1580         [ "$output" = bar1 ] && error "unexpected output"
1581         rm -r $tfile             || error "rm $tfile failed"
1582         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1583 }
1584 run_test 26f "rm -r of a directory which has recursive symlink"
1585
1586 test_27a() {
1587         test_mkdir $DIR/$tdir
1588         $LFS getstripe $DIR/$tdir
1589         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1590         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1591         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1592 }
1593 run_test 27a "one stripe file"
1594
1595 test_27b() {
1596         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1597
1598         test_mkdir $DIR/$tdir
1599         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1600         $LFS getstripe -c $DIR/$tdir/$tfile
1601         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1602                 error "two-stripe file doesn't have two stripes"
1603
1604         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1605 }
1606 run_test 27b "create and write to two stripe file"
1607
1608 # 27c family tests specific striping, setstripe -o
1609 test_27ca() {
1610         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1611         test_mkdir -p $DIR/$tdir
1612         local osts="1"
1613
1614         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1615         $LFS getstripe -i $DIR/$tdir/$tfile
1616         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1617                 error "stripe not on specified OST"
1618
1619         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1620 }
1621 run_test 27ca "one stripe on specified OST"
1622
1623 test_27cb() {
1624         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1625         test_mkdir -p $DIR/$tdir
1626         local osts="1,0"
1627         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1628         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1629         echo "$getstripe"
1630
1631         # Strip getstripe output to a space separated list of OSTs
1632         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1633                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1634         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1635                 error "stripes not on specified OSTs"
1636
1637         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1638 }
1639 run_test 27cb "two stripes on specified OSTs"
1640
1641 test_27cc() {
1642         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1643         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1644                 skip "server does not support overstriping"
1645
1646         test_mkdir -p $DIR/$tdir
1647         local osts="0,0"
1648         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1649         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1650         echo "$getstripe"
1651
1652         # Strip getstripe output to a space separated list of OSTs
1653         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1654                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1655         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1656                 error "stripes not on specified OSTs"
1657
1658         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1659 }
1660 run_test 27cc "two stripes on the same OST"
1661
1662 test_27cd() {
1663         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1664         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1665                 skip "server does not support overstriping"
1666         test_mkdir -p $DIR/$tdir
1667         local osts="0,1,1,0"
1668         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1669         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1670         echo "$getstripe"
1671
1672         # Strip getstripe output to a space separated list of OSTs
1673         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1674                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1675         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1676                 error "stripes not on specified OSTs"
1677
1678         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1679 }
1680 run_test 27cd "four stripes on two OSTs"
1681
1682 test_27ce() {
1683         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1684                 skip_env "too many osts, skipping"
1685         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1686                 skip "server does not support overstriping"
1687         # We do one more stripe than we have OSTs
1688         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1689                 skip_env "ea_inode feature disabled"
1690
1691         test_mkdir -p $DIR/$tdir
1692         local osts=""
1693         for i in $(seq 0 $OSTCOUNT);
1694         do
1695                 osts=$osts"0"
1696                 if [ $i -ne $OSTCOUNT ]; then
1697                         osts=$osts","
1698                 fi
1699         done
1700         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1701         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1702         echo "$getstripe"
1703
1704         # Strip getstripe output to a space separated list of OSTs
1705         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1706                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1707         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1708                 error "stripes not on specified OSTs"
1709
1710         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1711 }
1712 run_test 27ce "more stripes than OSTs with -o"
1713
1714 test_27cf() {
1715         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1716         local pid=0
1717
1718         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1719         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1720         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1721         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1722                 error "failed to set $osp_proc=0"
1723
1724         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1725         pid=$!
1726         sleep 1
1727         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1728         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1729                 error "failed to set $osp_proc=1"
1730         wait $pid
1731         [[ $pid -ne 0 ]] ||
1732                 error "should return error due to $osp_proc=0"
1733 }
1734 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1735
1736 test_27d() {
1737         test_mkdir $DIR/$tdir
1738         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1739                 error "setstripe failed"
1740         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1741         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1742 }
1743 run_test 27d "create file with default settings"
1744
1745 test_27e() {
1746         # LU-5839 adds check for existed layout before setting it
1747         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1748                 skip "Need MDS version at least 2.7.56"
1749
1750         test_mkdir $DIR/$tdir
1751         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1752         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1753         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1754 }
1755 run_test 27e "setstripe existing file (should return error)"
1756
1757 test_27f() {
1758         test_mkdir $DIR/$tdir
1759         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1760                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1761         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1762                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1763         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1764         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1765 }
1766 run_test 27f "setstripe with bad stripe size (should return error)"
1767
1768 test_27g() {
1769         test_mkdir $DIR/$tdir
1770         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1771         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1772                 error "$DIR/$tdir/$tfile has object"
1773 }
1774 run_test 27g "$LFS getstripe with no objects"
1775
1776 test_27ga() {
1777         test_mkdir $DIR/$tdir
1778         touch $DIR/$tdir/$tfile || error "touch failed"
1779         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1780         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1781         local rc=$?
1782         (( rc == 2 )) || error "getstripe did not return ENOENT"
1783 }
1784 run_test 27ga "$LFS getstripe with missing file (should return error)"
1785
1786 test_27i() {
1787         test_mkdir $DIR/$tdir
1788         touch $DIR/$tdir/$tfile || error "touch failed"
1789         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1790                 error "missing objects"
1791 }
1792 run_test 27i "$LFS getstripe with some objects"
1793
1794 test_27j() {
1795         test_mkdir $DIR/$tdir
1796         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1797                 error "setstripe failed" || true
1798 }
1799 run_test 27j "setstripe with bad stripe offset (should return error)"
1800
1801 test_27k() { # bug 2844
1802         test_mkdir $DIR/$tdir
1803         local file=$DIR/$tdir/$tfile
1804         local ll_max_blksize=$((4 * 1024 * 1024))
1805         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1806         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1807         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1808         dd if=/dev/zero of=$file bs=4k count=1
1809         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1810         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1811 }
1812 run_test 27k "limit i_blksize for broken user apps"
1813
1814 test_27l() {
1815         mcreate $DIR/$tfile || error "creating file"
1816         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1817                 error "setstripe should have failed" || true
1818 }
1819 run_test 27l "check setstripe permissions (should return error)"
1820
1821 test_27m() {
1822         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1823
1824         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1825                 skip_env "multiple clients -- skipping"
1826
1827         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1828                    head -n1)
1829         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1830                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1831         fi
1832         stack_trap simple_cleanup_common
1833         test_mkdir $DIR/$tdir
1834         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1835         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1836                 error "dd should fill OST0"
1837         i=2
1838         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1839                 i=$((i + 1))
1840                 [ $i -gt 256 ] && break
1841         done
1842         i=$((i + 1))
1843         touch $DIR/$tdir/$tfile.$i
1844         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1845             awk '{print $1}'| grep -w "0") ] &&
1846                 error "OST0 was full but new created file still use it"
1847         i=$((i + 1))
1848         touch $DIR/$tdir/$tfile.$i
1849         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1850             awk '{print $1}'| grep -w "0") ] &&
1851                 error "OST0 was full but new created file still use it" || true
1852 }
1853 run_test 27m "create file while OST0 was full"
1854
1855 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1856 # if the OST isn't full anymore.
1857 reset_enospc() {
1858         local ostidx=${1:-""}
1859         local delay
1860         local ready
1861         local get_prealloc
1862
1863         local list=$(comma_list $(osts_nodes))
1864         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1865
1866         do_nodes $list lctl set_param fail_loc=0
1867         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1868         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1869                 awk '{print $1 * 2;exit;}')
1870         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1871                         grep -v \"^0$\""
1872         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1873 }
1874
1875 test_27n() {
1876         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1878         remote_mds_nodsh && skip "remote MDS with nodsh"
1879         remote_ost_nodsh && skip "remote OST with nodsh"
1880
1881         reset_enospc
1882         rm -f $DIR/$tdir/$tfile
1883         exhaust_precreations 0 0x80000215
1884         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1885         touch $DIR/$tdir/$tfile || error "touch failed"
1886         $LFS getstripe $DIR/$tdir/$tfile
1887         reset_enospc
1888 }
1889 run_test 27n "create file with some full OSTs"
1890
1891 test_27o() {
1892         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1894         remote_mds_nodsh && skip "remote MDS with nodsh"
1895         remote_ost_nodsh && skip "remote OST with nodsh"
1896
1897         reset_enospc
1898         rm -f $DIR/$tdir/$tfile
1899         exhaust_all_precreations 0x215
1900
1901         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1902
1903         reset_enospc
1904         rm -rf $DIR/$tdir/*
1905 }
1906 run_test 27o "create file with all full OSTs (should error)"
1907
1908 function create_and_checktime() {
1909         local fname=$1
1910         local loops=$2
1911         local i
1912
1913         for ((i=0; i < $loops; i++)); do
1914                 local start=$SECONDS
1915                 multiop $fname-$i Oc
1916                 ((SECONDS-start < TIMEOUT)) ||
1917                         error "creation took " $((SECONDS-$start)) && return 1
1918         done
1919 }
1920
1921 test_27oo() {
1922         local mdts=$(comma_list $(mdts_nodes))
1923
1924         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1925                 skip "Need MDS version at least 2.13.57"
1926
1927         local f0=$DIR/${tfile}-0
1928         local f1=$DIR/${tfile}-1
1929
1930         wait_delete_completed
1931
1932         # refill precreated objects
1933         $LFS setstripe -i0 -c1 $f0
1934
1935         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1936         # force QoS allocation policy
1937         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1938         stack_trap "do_nodes $mdts $LCTL set_param \
1939                 lov.*.qos_threshold_rr=$saved" EXIT
1940         sleep_maxage
1941
1942         # one OST is unavailable, but still have few objects preallocated
1943         stop ost1
1944         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1945                 rm -rf $f1 $DIR/$tdir*" EXIT
1946
1947         for ((i=0; i < 7; i++)); do
1948                 mkdir $DIR/$tdir$i || error "can't create dir"
1949                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1950                         error "can't set striping"
1951         done
1952         for ((i=0; i < 7; i++)); do
1953                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1954         done
1955         wait
1956 }
1957 run_test 27oo "don't let few threads to reserve too many objects"
1958
1959 test_27p() {
1960         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1962         remote_mds_nodsh && skip "remote MDS with nodsh"
1963         remote_ost_nodsh && skip "remote OST with nodsh"
1964
1965         reset_enospc
1966         rm -f $DIR/$tdir/$tfile
1967         test_mkdir $DIR/$tdir
1968
1969         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1970         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1971         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1972
1973         exhaust_precreations 0 0x80000215
1974         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1975         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1976         $LFS getstripe $DIR/$tdir/$tfile
1977
1978         reset_enospc
1979 }
1980 run_test 27p "append to a truncated file with some full OSTs"
1981
1982 test_27q() {
1983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1985         remote_mds_nodsh && skip "remote MDS with nodsh"
1986         remote_ost_nodsh && skip "remote OST with nodsh"
1987
1988         reset_enospc
1989         rm -f $DIR/$tdir/$tfile
1990
1991         mkdir_on_mdt0 $DIR/$tdir
1992         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1993         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1994                 error "truncate $DIR/$tdir/$tfile failed"
1995         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1996
1997         exhaust_all_precreations 0x215
1998
1999         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2000         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2001
2002         reset_enospc
2003 }
2004 run_test 27q "append to truncated file with all OSTs full (should error)"
2005
2006 test_27r() {
2007         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2009         remote_mds_nodsh && skip "remote MDS with nodsh"
2010         remote_ost_nodsh && skip "remote OST with nodsh"
2011
2012         reset_enospc
2013         rm -f $DIR/$tdir/$tfile
2014         exhaust_precreations 0 0x80000215
2015
2016         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2017
2018         reset_enospc
2019 }
2020 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2021
2022 test_27s() { # bug 10725
2023         test_mkdir $DIR/$tdir
2024         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2025         local stripe_count=0
2026         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2027         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2028                 error "stripe width >= 2^32 succeeded" || true
2029
2030 }
2031 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2032
2033 test_27t() { # bug 10864
2034         WDIR=$(pwd)
2035         WLFS=$(which lfs)
2036         cd $DIR
2037         touch $tfile
2038         $WLFS getstripe $tfile
2039         cd $WDIR
2040 }
2041 run_test 27t "check that utils parse path correctly"
2042
2043 test_27u() { # bug 4900
2044         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2045         remote_mds_nodsh && skip "remote MDS with nodsh"
2046
2047         local index
2048         local list=$(comma_list $(mdts_nodes))
2049
2050 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2051         do_nodes $list $LCTL set_param fail_loc=0x139
2052         test_mkdir -p $DIR/$tdir
2053         stack_trap "simple_cleanup_common 1000"
2054         createmany -o $DIR/$tdir/$tfile 1000
2055         do_nodes $list $LCTL set_param fail_loc=0
2056
2057         TLOG=$TMP/$tfile.getstripe
2058         $LFS getstripe $DIR/$tdir > $TLOG
2059         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2060         [[ $OBJS -gt 0 ]] &&
2061                 error "$OBJS objects created on OST-0. See $TLOG" ||
2062                 rm -f $TLOG
2063 }
2064 run_test 27u "skip object creation on OSC w/o objects"
2065
2066 test_27v() { # bug 4900
2067         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2069         remote_mds_nodsh && skip "remote MDS with nodsh"
2070         remote_ost_nodsh && skip "remote OST with nodsh"
2071
2072         exhaust_all_precreations 0x215
2073         reset_enospc
2074
2075         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2076
2077         touch $DIR/$tdir/$tfile
2078         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2079         # all except ost1
2080         for (( i=1; i < OSTCOUNT; i++ )); do
2081                 do_facet ost$i lctl set_param fail_loc=0x705
2082         done
2083         local START=`date +%s`
2084         createmany -o $DIR/$tdir/$tfile 32
2085
2086         local FINISH=`date +%s`
2087         local TIMEOUT=`lctl get_param -n timeout`
2088         local PROCESS=$((FINISH - START))
2089         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2090                error "$FINISH - $START >= $TIMEOUT / 2"
2091         sleep $((TIMEOUT / 2 - PROCESS))
2092         reset_enospc
2093 }
2094 run_test 27v "skip object creation on slow OST"
2095
2096 test_27w() { # bug 10997
2097         test_mkdir $DIR/$tdir
2098         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2099         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2100                 error "stripe size $size != 65536" || true
2101         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2102                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2103 }
2104 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2105
2106 test_27wa() {
2107         [[ $OSTCOUNT -lt 2 ]] &&
2108                 skip_env "skipping multiple stripe count/offset test"
2109
2110         test_mkdir $DIR/$tdir
2111         for i in $(seq 1 $OSTCOUNT); do
2112                 offset=$((i - 1))
2113                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2114                         error "setstripe -c $i -i $offset failed"
2115                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2116                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2117                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2118                 [ $index -ne $offset ] &&
2119                         error "stripe offset $index != $offset" || true
2120         done
2121 }
2122 run_test 27wa "check $LFS setstripe -c -i options"
2123
2124 test_27x() {
2125         remote_ost_nodsh && skip "remote OST with nodsh"
2126         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2128
2129         OFFSET=$(($OSTCOUNT - 1))
2130         OSTIDX=0
2131         local OST=$(ostname_from_index $OSTIDX)
2132
2133         test_mkdir $DIR/$tdir
2134         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2135         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2136         sleep_maxage
2137         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2138         for i in $(seq 0 $OFFSET); do
2139                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2140                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2141                 error "OST0 was degraded but new created file still use it"
2142         done
2143         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2144 }
2145 run_test 27x "create files while OST0 is degraded"
2146
2147 test_27y() {
2148         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2149         remote_mds_nodsh && skip "remote MDS with nodsh"
2150         remote_ost_nodsh && skip "remote OST with nodsh"
2151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2152
2153         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2154         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2155                 osp.$mdtosc.prealloc_last_id)
2156         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2157                 osp.$mdtosc.prealloc_next_id)
2158         local fcount=$((last_id - next_id))
2159         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2160         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2161
2162         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2163                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2164         local OST_DEACTIVE_IDX=-1
2165         local OSC
2166         local OSTIDX
2167         local OST
2168
2169         for OSC in $MDS_OSCS; do
2170                 OST=$(osc_to_ost $OSC)
2171                 OSTIDX=$(index_from_ostuuid $OST)
2172                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2173                         OST_DEACTIVE_IDX=$OSTIDX
2174                 fi
2175                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2176                         echo $OSC "is Deactivated:"
2177                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2178                 fi
2179         done
2180
2181         OSTIDX=$(index_from_ostuuid $OST)
2182         test_mkdir $DIR/$tdir
2183         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2184
2185         for OSC in $MDS_OSCS; do
2186                 OST=$(osc_to_ost $OSC)
2187                 OSTIDX=$(index_from_ostuuid $OST)
2188                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2189                         echo $OST "is degraded:"
2190                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2191                                                 obdfilter.$OST.degraded=1
2192                 fi
2193         done
2194
2195         sleep_maxage
2196         createmany -o $DIR/$tdir/$tfile $fcount
2197
2198         for OSC in $MDS_OSCS; do
2199                 OST=$(osc_to_ost $OSC)
2200                 OSTIDX=$(index_from_ostuuid $OST)
2201                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2202                         echo $OST "is recovered from degraded:"
2203                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2204                                                 obdfilter.$OST.degraded=0
2205                 else
2206                         do_facet $SINGLEMDS lctl --device %$OSC activate
2207                 fi
2208         done
2209
2210         # all osp devices get activated, hence -1 stripe count restored
2211         local stripe_count=0
2212
2213         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2214         # devices get activated.
2215         sleep_maxage
2216         $LFS setstripe -c -1 $DIR/$tfile
2217         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2218         rm -f $DIR/$tfile
2219         [ $stripe_count -ne $OSTCOUNT ] &&
2220                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2221         return 0
2222 }
2223 run_test 27y "create files while OST0 is degraded and the rest inactive"
2224
2225 check_seq_oid()
2226 {
2227         log "check file $1"
2228
2229         lmm_count=$($LFS getstripe -c $1)
2230         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2231         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2232
2233         local old_ifs="$IFS"
2234         IFS=$'[:]'
2235         fid=($($LFS path2fid $1))
2236         IFS="$old_ifs"
2237
2238         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2239         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2240
2241         # compare lmm_seq and lu_fid->f_seq
2242         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2243         # compare lmm_object_id and lu_fid->oid
2244         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2245
2246         # check the trusted.fid attribute of the OST objects of the file
2247         local have_obdidx=false
2248         local stripe_nr=0
2249         $LFS getstripe $1 | while read obdidx oid hex seq; do
2250                 # skip lines up to and including "obdidx"
2251                 [ -z "$obdidx" ] && break
2252                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2253                 $have_obdidx || continue
2254
2255                 local ost=$((obdidx + 1))
2256                 local dev=$(ostdevname $ost)
2257                 local oid_hex
2258
2259                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2260
2261                 seq=$(echo $seq | sed -e "s/^0x//g")
2262                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2263                         oid_hex=$(echo $oid)
2264                 else
2265                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2266                 fi
2267                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2268
2269                 local ff=""
2270                 #
2271                 # Don't unmount/remount the OSTs if we don't need to do that.
2272                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2273                 # update too, until that use mount/ll_decode_filter_fid/mount.
2274                 # Re-enable when debugfs will understand new filter_fid.
2275                 #
2276                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2277                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2278                                 $dev 2>/dev/null" | grep "parent=")
2279                 fi
2280                 if [ -z "$ff" ]; then
2281                         stop ost$ost
2282                         mount_fstype ost$ost
2283                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2284                                 $(facet_mntpt ost$ost)/$obj_file)
2285                         unmount_fstype ost$ost
2286                         start ost$ost $dev $OST_MOUNT_OPTS
2287                         clients_up
2288                 fi
2289
2290                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2291
2292                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2293
2294                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2295                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2296                 #
2297                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2298                 #       stripe_size=1048576 component_id=1 component_start=0 \
2299                 #       component_end=33554432
2300                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2301                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2302                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2303                 local ff_pstripe
2304                 if grep -q 'stripe=' <<<$ff; then
2305                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2306                 else
2307                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2308                         # into f_ver in this case.  See comment on ff_parent.
2309                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2310                 fi
2311
2312                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2313                 [ $ff_pseq = $lmm_seq ] ||
2314                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2315                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2316                 [ $ff_poid = $lmm_oid ] ||
2317                         error "FF parent OID $ff_poid != $lmm_oid"
2318                 (($ff_pstripe == $stripe_nr)) ||
2319                         error "FF stripe $ff_pstripe != $stripe_nr"
2320
2321                 stripe_nr=$((stripe_nr + 1))
2322                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2323                         continue
2324                 if grep -q 'stripe_count=' <<<$ff; then
2325                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2326                                             -e 's/ .*//' <<<$ff)
2327                         [ $lmm_count = $ff_scnt ] ||
2328                                 error "FF stripe count $lmm_count != $ff_scnt"
2329                 fi
2330         done
2331 }
2332
2333 test_27z() {
2334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2335         remote_ost_nodsh && skip "remote OST with nodsh"
2336
2337         test_mkdir $DIR/$tdir
2338         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2339                 { error "setstripe -c -1 failed"; return 1; }
2340         # We need to send a write to every object to get parent FID info set.
2341         # This _should_ also work for setattr, but does not currently.
2342         # touch $DIR/$tdir/$tfile-1 ||
2343         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2344                 { error "dd $tfile-1 failed"; return 2; }
2345         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2346                 { error "setstripe -c -1 failed"; return 3; }
2347         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2348                 { error "dd $tfile-2 failed"; return 4; }
2349
2350         # make sure write RPCs have been sent to OSTs
2351         sync; sleep 5; sync
2352
2353         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2354         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2355 }
2356 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2357
2358 test_27A() { # b=19102
2359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2360
2361         save_layout_restore_at_exit $MOUNT
2362         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2363         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2364                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2365         local default_size=$($LFS getstripe -S $MOUNT)
2366         local default_offset=$($LFS getstripe -i $MOUNT)
2367         local dsize=$(do_facet $SINGLEMDS \
2368                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2369         [ $default_size -eq $dsize ] ||
2370                 error "stripe size $default_size != $dsize"
2371         [ $default_offset -eq -1 ] ||
2372                 error "stripe offset $default_offset != -1"
2373 }
2374 run_test 27A "check filesystem-wide default LOV EA values"
2375
2376 test_27B() { # LU-2523
2377         test_mkdir $DIR/$tdir
2378         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2379         touch $DIR/$tdir/f0
2380         # open f1 with O_LOV_DELAY_CREATE
2381         # rename f0 onto f1
2382         # call setstripe ioctl on open file descriptor for f1
2383         # close
2384         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2385                 $DIR/$tdir/f0
2386
2387         rm -f $DIR/$tdir/f1
2388         # open f1 with O_LOV_DELAY_CREATE
2389         # unlink f1
2390         # call setstripe ioctl on open file descriptor for f1
2391         # close
2392         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2393
2394         # Allow multiop to fail in imitation of NFS's busted semantics.
2395         true
2396 }
2397 run_test 27B "call setstripe on open unlinked file/rename victim"
2398
2399 # 27C family tests full striping and overstriping
2400 test_27Ca() { #LU-2871
2401         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2402
2403         declare -a ost_idx
2404         local index
2405         local found
2406         local i
2407         local j
2408
2409         test_mkdir $DIR/$tdir
2410         cd $DIR/$tdir
2411         for i in $(seq 0 $((OSTCOUNT - 1))); do
2412                 # set stripe across all OSTs starting from OST$i
2413                 $LFS setstripe -i $i -c -1 $tfile$i
2414                 # get striping information
2415                 ost_idx=($($LFS getstripe $tfile$i |
2416                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2417                 echo ${ost_idx[@]}
2418
2419                 # check the layout
2420                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2421                         error "${#ost_idx[@]} != $OSTCOUNT"
2422
2423                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2424                         found=0
2425                         for j in $(echo ${ost_idx[@]}); do
2426                                 if [ $index -eq $j ]; then
2427                                         found=1
2428                                         break
2429                                 fi
2430                         done
2431                         [ $found = 1 ] ||
2432                                 error "Can not find $index in ${ost_idx[@]}"
2433                 done
2434         done
2435 }
2436 run_test 27Ca "check full striping across all OSTs"
2437
2438 test_27Cb() {
2439         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2440                 skip "server does not support overstriping"
2441         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2442                 skip_env "too many osts, skipping"
2443
2444         test_mkdir -p $DIR/$tdir
2445         local setcount=$(($OSTCOUNT * 2))
2446         [ $setcount -lt 160 ] || large_xattr_enabled ||
2447                 skip_env "ea_inode feature disabled"
2448
2449         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2450                 error "setstripe failed"
2451
2452         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2453         [ $count -eq $setcount ] ||
2454                 error "stripe count $count, should be $setcount"
2455
2456         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2457                 error "overstriped should be set in pattern"
2458
2459         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2460                 error "dd failed"
2461 }
2462 run_test 27Cb "more stripes than OSTs with -C"
2463
2464 test_27Cc() {
2465         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2466                 skip "server does not support overstriping"
2467         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2468
2469         test_mkdir -p $DIR/$tdir
2470         local setcount=$(($OSTCOUNT - 1))
2471
2472         [ $setcount -lt 160 ] || large_xattr_enabled ||
2473                 skip_env "ea_inode feature disabled"
2474
2475         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2476                 error "setstripe failed"
2477
2478         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2479         [ $count -eq $setcount ] ||
2480                 error "stripe count $count, should be $setcount"
2481
2482         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2483                 error "overstriped should not be set in pattern"
2484
2485         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2486                 error "dd failed"
2487 }
2488 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2489
2490 test_27Cd() {
2491         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2492                 skip "server does not support overstriping"
2493         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2494         large_xattr_enabled || skip_env "ea_inode feature disabled"
2495
2496         test_mkdir -p $DIR/$tdir
2497         local setcount=$LOV_MAX_STRIPE_COUNT
2498
2499         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2500                 error "setstripe failed"
2501
2502         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2503         [ $count -eq $setcount ] ||
2504                 error "stripe count $count, should be $setcount"
2505
2506         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2507                 error "overstriped should be set in pattern"
2508
2509         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2510                 error "dd failed"
2511
2512         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2513 }
2514 run_test 27Cd "test maximum stripe count"
2515
2516 test_27Ce() {
2517         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2518                 skip "server does not support overstriping"
2519         test_mkdir -p $DIR/$tdir
2520
2521         pool_add $TESTNAME || error "Pool creation failed"
2522         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2523
2524         local setcount=8
2525
2526         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2527                 error "setstripe failed"
2528
2529         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2530         [ $count -eq $setcount ] ||
2531                 error "stripe count $count, should be $setcount"
2532
2533         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2534                 error "overstriped should be set in pattern"
2535
2536         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2537                 error "dd failed"
2538
2539         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2540 }
2541 run_test 27Ce "test pool with overstriping"
2542
2543 test_27Cf() {
2544         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2545                 skip "server does not support overstriping"
2546         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2547                 skip_env "too many osts, skipping"
2548
2549         test_mkdir -p $DIR/$tdir
2550
2551         local setcount=$(($OSTCOUNT * 2))
2552         [ $setcount -lt 160 ] || large_xattr_enabled ||
2553                 skip_env "ea_inode feature disabled"
2554
2555         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2556                 error "setstripe failed"
2557
2558         echo 1 > $DIR/$tdir/$tfile
2559
2560         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2561         [ $count -eq $setcount ] ||
2562                 error "stripe count $count, should be $setcount"
2563
2564         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2565                 error "overstriped should be set in pattern"
2566
2567         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2568                 error "dd failed"
2569
2570         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2571 }
2572 run_test 27Cf "test default inheritance with overstriping"
2573
2574 test_27D() {
2575         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2576         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2577         remote_mds_nodsh && skip "remote MDS with nodsh"
2578
2579         local POOL=${POOL:-testpool}
2580         local first_ost=0
2581         local last_ost=$(($OSTCOUNT - 1))
2582         local ost_step=1
2583         local ost_list=$(seq $first_ost $ost_step $last_ost)
2584         local ost_range="$first_ost $last_ost $ost_step"
2585
2586         test_mkdir $DIR/$tdir
2587         pool_add $POOL || error "pool_add failed"
2588         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2589
2590         local skip27D
2591         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2592                 skip27D+="-s 29"
2593         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2594                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2595                         skip27D+=" -s 30,31"
2596         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2597           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2598                 skip27D+=" -s 32,33"
2599         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2600                 skip27D+=" -s 34"
2601         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2602                 error "llapi_layout_test failed"
2603
2604         destroy_test_pools || error "destroy test pools failed"
2605 }
2606 run_test 27D "validate llapi_layout API"
2607
2608 # Verify that default_easize is increased from its initial value after
2609 # accessing a widely striped file.
2610 test_27E() {
2611         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2612         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2613                 skip "client does not have LU-3338 fix"
2614
2615         # 72 bytes is the minimum space required to store striping
2616         # information for a file striped across one OST:
2617         # (sizeof(struct lov_user_md_v3) +
2618         #  sizeof(struct lov_user_ost_data_v1))
2619         local min_easize=72
2620         $LCTL set_param -n llite.*.default_easize $min_easize ||
2621                 error "lctl set_param failed"
2622         local easize=$($LCTL get_param -n llite.*.default_easize)
2623
2624         [ $easize -eq $min_easize ] ||
2625                 error "failed to set default_easize"
2626
2627         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2628                 error "setstripe failed"
2629         # In order to ensure stat() call actually talks to MDS we need to
2630         # do something drastic to this file to shake off all lock, e.g.
2631         # rename it (kills lookup lock forcing cache cleaning)
2632         mv $DIR/$tfile $DIR/${tfile}-1
2633         ls -l $DIR/${tfile}-1
2634         rm $DIR/${tfile}-1
2635
2636         easize=$($LCTL get_param -n llite.*.default_easize)
2637
2638         [ $easize -gt $min_easize ] ||
2639                 error "default_easize not updated"
2640 }
2641 run_test 27E "check that default extended attribute size properly increases"
2642
2643 test_27F() { # LU-5346/LU-7975
2644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2645         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2646         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2647                 skip "Need MDS version at least 2.8.51"
2648         remote_ost_nodsh && skip "remote OST with nodsh"
2649
2650         test_mkdir $DIR/$tdir
2651         rm -f $DIR/$tdir/f0
2652         $LFS setstripe -c 2 $DIR/$tdir
2653
2654         # stop all OSTs to reproduce situation for LU-7975 ticket
2655         for num in $(seq $OSTCOUNT); do
2656                 stop ost$num
2657         done
2658
2659         # open/create f0 with O_LOV_DELAY_CREATE
2660         # truncate f0 to a non-0 size
2661         # close
2662         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2663
2664         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2665         # open/write it again to force delayed layout creation
2666         cat /etc/hosts > $DIR/$tdir/f0 &
2667         catpid=$!
2668
2669         # restart OSTs
2670         for num in $(seq $OSTCOUNT); do
2671                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2672                         error "ost$num failed to start"
2673         done
2674
2675         wait $catpid || error "cat failed"
2676
2677         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2678         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2679                 error "wrong stripecount"
2680
2681 }
2682 run_test 27F "Client resend delayed layout creation with non-zero size"
2683
2684 test_27G() { #LU-10629
2685         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2686                 skip "Need MDS version at least 2.11.51"
2687         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2688         remote_mds_nodsh && skip "remote MDS with nodsh"
2689         local POOL=${POOL:-testpool}
2690         local ostrange="0 0 1"
2691
2692         test_mkdir $DIR/$tdir
2693         touch $DIR/$tdir/$tfile.nopool
2694         pool_add $POOL || error "pool_add failed"
2695         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2696         $LFS setstripe -p $POOL $DIR/$tdir
2697
2698         local pool=$($LFS getstripe -p $DIR/$tdir)
2699
2700         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2701         touch $DIR/$tdir/$tfile.default
2702         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2703         $LFS find $DIR/$tdir -type f --pool $POOL
2704         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2705         [[ "$found" == "2" ]] ||
2706                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2707
2708         $LFS setstripe -d $DIR/$tdir
2709
2710         pool=$($LFS getstripe -p -d $DIR/$tdir)
2711
2712         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2713 }
2714 run_test 27G "Clear OST pool from stripe"
2715
2716 test_27H() {
2717         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2718                 skip "Need MDS version newer than 2.11.54"
2719         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2720         test_mkdir $DIR/$tdir
2721         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2722         touch $DIR/$tdir/$tfile
2723         $LFS getstripe -c $DIR/$tdir/$tfile
2724         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2725                 error "two-stripe file doesn't have two stripes"
2726
2727         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2728         $LFS getstripe -y $DIR/$tdir/$tfile
2729         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2730              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2731                 error "expected l_ost_idx: [02]$ not matched"
2732
2733         # make sure ost list has been cleared
2734         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2735         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2736                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2737         touch $DIR/$tdir/f3
2738         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2739 }
2740 run_test 27H "Set specific OSTs stripe"
2741
2742 test_27I() {
2743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2744         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2745         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2746                 skip "Need MDS version newer than 2.12.52"
2747         local pool=$TESTNAME
2748         local ostrange="1 1 1"
2749
2750         save_layout_restore_at_exit $MOUNT
2751         $LFS setstripe -c 2 -i 0 $MOUNT
2752         pool_add $pool || error "pool_add failed"
2753         pool_add_targets $pool $ostrange ||
2754                 error "pool_add_targets failed"
2755         test_mkdir $DIR/$tdir
2756         $LFS setstripe -p $pool $DIR/$tdir
2757         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2758         $LFS getstripe $DIR/$tdir/$tfile
2759 }
2760 run_test 27I "check that root dir striping does not break parent dir one"
2761
2762 test_27J() {
2763         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2764                 skip "Need MDS version newer than 2.12.51"
2765
2766         test_mkdir $DIR/$tdir
2767         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2768         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2769
2770         # create foreign file (raw way)
2771         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2772                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2773
2774         ! $LFS setstripe --foreign --flags foo \
2775                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2776                         error "creating $tfile with '--flags foo' should fail"
2777
2778         ! $LFS setstripe --foreign --flags 0xffffffff \
2779                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2780                         error "creating $tfile w/ 0xffffffff flags should fail"
2781
2782         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2783                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2784
2785         # verify foreign file (raw way)
2786         parse_foreign_file -f $DIR/$tdir/$tfile |
2787                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2788                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2789         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2790                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2791         parse_foreign_file -f $DIR/$tdir/$tfile |
2792                 grep "lov_foreign_size: 73" ||
2793                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2794         parse_foreign_file -f $DIR/$tdir/$tfile |
2795                 grep "lov_foreign_type: 1" ||
2796                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2797         parse_foreign_file -f $DIR/$tdir/$tfile |
2798                 grep "lov_foreign_flags: 0x0000DA08" ||
2799                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2800         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2801                 grep "lov_foreign_value: 0x" |
2802                 sed -e 's/lov_foreign_value: 0x//')
2803         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2804         [[ $lov = ${lov2// /} ]] ||
2805                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2806
2807         # create foreign file (lfs + API)
2808         $LFS setstripe --foreign=none --flags 0xda08 \
2809                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2810                 error "$DIR/$tdir/${tfile}2: create failed"
2811
2812         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2813                 grep "lfm_magic:.*0x0BD70BD0" ||
2814                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2815         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2816         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2817                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2818         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2819                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2820         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2821                 grep "lfm_flags:.*0x0000DA08" ||
2822                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2823         $LFS getstripe $DIR/$tdir/${tfile}2 |
2824                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2825                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2826
2827         # modify striping should fail
2828         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2829                 error "$DIR/$tdir/$tfile: setstripe should fail"
2830         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2831                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2832
2833         # R/W should fail
2834         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2835         cat $DIR/$tdir/${tfile}2 &&
2836                 error "$DIR/$tdir/${tfile}2: read should fail"
2837         cat /etc/passwd > $DIR/$tdir/$tfile &&
2838                 error "$DIR/$tdir/$tfile: write should fail"
2839         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2840                 error "$DIR/$tdir/${tfile}2: write should fail"
2841
2842         # chmod should work
2843         chmod 222 $DIR/$tdir/$tfile ||
2844                 error "$DIR/$tdir/$tfile: chmod failed"
2845         chmod 222 $DIR/$tdir/${tfile}2 ||
2846                 error "$DIR/$tdir/${tfile}2: chmod failed"
2847
2848         # chown should work
2849         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2850                 error "$DIR/$tdir/$tfile: chown failed"
2851         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2852                 error "$DIR/$tdir/${tfile}2: chown failed"
2853
2854         # rename should work
2855         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2856                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2857         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2858                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2859
2860         #remove foreign file
2861         rm $DIR/$tdir/${tfile}.new ||
2862                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2863         rm $DIR/$tdir/${tfile}2.new ||
2864                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2865 }
2866 run_test 27J "basic ops on file with foreign LOV"
2867
2868 test_27K() {
2869         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2870                 skip "Need MDS version newer than 2.12.49"
2871
2872         test_mkdir $DIR/$tdir
2873         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2874         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2875
2876         # create foreign dir (raw way)
2877         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2878                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2879
2880         ! $LFS setdirstripe --foreign --flags foo \
2881                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2882                         error "creating $tdir with '--flags foo' should fail"
2883
2884         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2885                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2886                         error "creating $tdir w/ 0xffffffff flags should fail"
2887
2888         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2889                 error "create_foreign_dir FAILED"
2890
2891         # verify foreign dir (raw way)
2892         parse_foreign_dir -d $DIR/$tdir/$tdir |
2893                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2894                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2895         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2896                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2897         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2898                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2899         parse_foreign_dir -d $DIR/$tdir/$tdir |
2900                 grep "lmv_foreign_flags: 55813$" ||
2901                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2902         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2903                 grep "lmv_foreign_value: 0x" |
2904                 sed 's/lmv_foreign_value: 0x//')
2905         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2906                 sed 's/ //g')
2907         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2908
2909         # create foreign dir (lfs + API)
2910         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2911                 $DIR/$tdir/${tdir}2 ||
2912                 error "$DIR/$tdir/${tdir}2: create failed"
2913
2914         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2915                 grep "lfm_magic:.*0x0CD50CD0" ||
2916                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2917         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2918         # - sizeof(lfm_type) - sizeof(lfm_flags)
2919         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2920                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2921         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2922                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2923         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2924                 grep "lfm_flags:.*0x0000DA05" ||
2925                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2926         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2927                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2928                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2929
2930         # file create in dir should fail
2931         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2932         touch $DIR/$tdir/${tdir}2/$tfile &&
2933                 error "$DIR/${tdir}2: file create should fail"
2934
2935         # chmod should work
2936         chmod 777 $DIR/$tdir/$tdir ||
2937                 error "$DIR/$tdir: chmod failed"
2938         chmod 777 $DIR/$tdir/${tdir}2 ||
2939                 error "$DIR/${tdir}2: chmod failed"
2940
2941         # chown should work
2942         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2943                 error "$DIR/$tdir: chown failed"
2944         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2945                 error "$DIR/${tdir}2: chown failed"
2946
2947         # rename should work
2948         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2949                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2950         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2951                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2952
2953         #remove foreign dir
2954         rmdir $DIR/$tdir/${tdir}.new ||
2955                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2956         rmdir $DIR/$tdir/${tdir}2.new ||
2957                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2958 }
2959 run_test 27K "basic ops on dir with foreign LMV"
2960
2961 test_27L() {
2962         remote_mds_nodsh && skip "remote MDS with nodsh"
2963
2964         local POOL=${POOL:-$TESTNAME}
2965
2966         pool_add $POOL || error "pool_add failed"
2967
2968         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2969                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2970                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2971 }
2972 run_test 27L "lfs pool_list gives correct pool name"
2973
2974 test_27M() {
2975         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2976                 skip "Need MDS version >= than 2.12.57"
2977         remote_mds_nodsh && skip "remote MDS with nodsh"
2978         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2979
2980         test_mkdir $DIR/$tdir
2981
2982         # Set default striping on directory
2983         local setcount=4
2984         local stripe_opt
2985
2986         # if we run against a 2.12 server which lacks overstring support
2987         # then the connect_flag will not report overstriping, even if client
2988         # is 2.14+
2989         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2990                 stripe_opt="-C $setcount"
2991         elif (( $OSTCOUNT >= $setcount )); then
2992                 stripe_opt="-c $setcount"
2993         else
2994                 skip "server does not support overstriping"
2995         fi
2996         $LFS setstripe $stripe_opt $DIR/$tdir
2997
2998         echo 1 > $DIR/$tdir/${tfile}.1
2999         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3000         [ $count -eq $setcount ] ||
3001                 error "(1) stripe count $count, should be $setcount"
3002
3003         # Capture existing append_stripe_count setting for restore
3004         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3005         local mdts=$(comma_list $(mdts_nodes))
3006         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
3007
3008         local appendcount=$orig_count
3009         echo 1 >> $DIR/$tdir/${tfile}.2_append
3010         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3011         [ $count -eq $appendcount ] ||
3012                 error "(2)stripe count $count, should be $appendcount for append"
3013
3014         # Disable O_APPEND striping, verify it works
3015         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3016
3017         # Should now get the default striping, which is 4
3018         setcount=4
3019         echo 1 >> $DIR/$tdir/${tfile}.3_append
3020         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3021         [ $count -eq $setcount ] ||
3022                 error "(3) stripe count $count, should be $setcount"
3023
3024         # Try changing the stripe count for append files
3025         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3026
3027         # Append striping is now 2 (directory default is still 4)
3028         appendcount=2
3029         echo 1 >> $DIR/$tdir/${tfile}.4_append
3030         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3031         [ $count -eq $appendcount ] ||
3032                 error "(4) stripe count $count, should be $appendcount for append"
3033
3034         # Test append stripe count of -1
3035         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3036         appendcount=$OSTCOUNT
3037         echo 1 >> $DIR/$tdir/${tfile}.5
3038         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3039         [ $count -eq $appendcount ] ||
3040                 error "(5) stripe count $count, should be $appendcount for append"
3041
3042         # Set append striping back to default of 1
3043         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3044
3045         # Try a new default striping, PFL + DOM
3046         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3047
3048         # Create normal DOM file, DOM returns stripe count == 0
3049         setcount=0
3050         touch $DIR/$tdir/${tfile}.6
3051         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3052         [ $count -eq $setcount ] ||
3053                 error "(6) stripe count $count, should be $setcount"
3054
3055         # Show
3056         appendcount=1
3057         echo 1 >> $DIR/$tdir/${tfile}.7_append
3058         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3059         [ $count -eq $appendcount ] ||
3060                 error "(7) stripe count $count, should be $appendcount for append"
3061
3062         # Clean up DOM layout
3063         $LFS setstripe -d $DIR/$tdir
3064
3065         save_layout_restore_at_exit $MOUNT
3066         # Now test that append striping works when layout is from root
3067         $LFS setstripe -c 2 $MOUNT
3068         # Make a special directory for this
3069         mkdir $DIR/${tdir}/${tdir}.2
3070
3071         # Verify for normal file
3072         setcount=2
3073         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3074         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3075         [ $count -eq $setcount ] ||
3076                 error "(8) stripe count $count, should be $setcount"
3077
3078         appendcount=1
3079         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3080         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3081         [ $count -eq $appendcount ] ||
3082                 error "(9) stripe count $count, should be $appendcount for append"
3083
3084         # Now test O_APPEND striping with pools
3085         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3086         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3087
3088         # Create the pool
3089         pool_add $TESTNAME || error "pool creation failed"
3090         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3091
3092         echo 1 >> $DIR/$tdir/${tfile}.10_append
3093
3094         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3095         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3096
3097         # Check that count is still correct
3098         appendcount=1
3099         echo 1 >> $DIR/$tdir/${tfile}.11_append
3100         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3101         [ $count -eq $appendcount ] ||
3102                 error "(11) stripe count $count, should be $appendcount for append"
3103
3104         # Disable O_APPEND stripe count, verify pool works separately
3105         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3106
3107         echo 1 >> $DIR/$tdir/${tfile}.12_append
3108
3109         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3110         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3111
3112         # Remove pool setting, verify it's not applied
3113         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3114
3115         echo 1 >> $DIR/$tdir/${tfile}.13_append
3116
3117         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3118         [ "$pool" = "" ] || error "(13) pool found: $pool"
3119 }
3120 run_test 27M "test O_APPEND striping"
3121
3122 test_27N() {
3123         combined_mgs_mds && skip "needs separate MGS/MDT"
3124
3125         pool_add $TESTNAME || error "pool_add failed"
3126         do_facet mgs "$LCTL pool_list $FSNAME" |
3127                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3128                 error "lctl pool_list on MGS failed"
3129 }
3130 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3131
3132 clean_foreign_symlink() {
3133         trap 0
3134         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3135         for i in $DIR/$tdir/* ; do
3136                 $LFS unlink_foreign $i || true
3137         done
3138 }
3139
3140 test_27O() {
3141         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3142                 skip "Need MDS version newer than 2.12.51"
3143
3144         test_mkdir $DIR/$tdir
3145         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3146         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3147
3148         trap clean_foreign_symlink EXIT
3149
3150         # enable foreign_symlink behaviour
3151         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3152
3153         # foreign symlink LOV format is a partial path by default
3154
3155         # create foreign file (lfs + API)
3156         $LFS setstripe --foreign=symlink --flags 0xda05 \
3157                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3158                 error "$DIR/$tdir/${tfile}: create failed"
3159
3160         $LFS getstripe -v $DIR/$tdir/${tfile} |
3161                 grep "lfm_magic:.*0x0BD70BD0" ||
3162                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3163         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3164                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3165         $LFS getstripe -v $DIR/$tdir/${tfile} |
3166                 grep "lfm_flags:.*0x0000DA05" ||
3167                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3168         $LFS getstripe $DIR/$tdir/${tfile} |
3169                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3170                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3171
3172         # modify striping should fail
3173         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3174                 error "$DIR/$tdir/$tfile: setstripe should fail"
3175
3176         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3177         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3178         cat /etc/passwd > $DIR/$tdir/$tfile &&
3179                 error "$DIR/$tdir/$tfile: write should fail"
3180
3181         # rename should succeed
3182         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3183                 error "$DIR/$tdir/$tfile: rename has failed"
3184
3185         #remove foreign_symlink file should fail
3186         rm $DIR/$tdir/${tfile}.new &&
3187                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3188
3189         #test fake symlink
3190         mkdir /tmp/${uuid1} ||
3191                 error "/tmp/${uuid1}: mkdir has failed"
3192         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3193                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3194         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3195         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3197         #read should succeed now
3198         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3199                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3200         #write should succeed now
3201         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3202                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3203         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3204                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3205         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3206                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3207
3208         #check that getstripe still works
3209         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3210                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3211
3212         # chmod should still succeed
3213         chmod 644 $DIR/$tdir/${tfile}.new ||
3214                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3215
3216         # chown should still succeed
3217         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3218                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3219
3220         # rename should still succeed
3221         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3222                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3223
3224         #remove foreign_symlink file should still fail
3225         rm $DIR/$tdir/${tfile} &&
3226                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3227
3228         #use special ioctl() to unlink foreign_symlink file
3229         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3230                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3231
3232 }
3233 run_test 27O "basic ops on foreign file of symlink type"
3234
3235 test_27P() {
3236         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3237                 skip "Need MDS version newer than 2.12.49"
3238
3239         test_mkdir $DIR/$tdir
3240         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3241         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3242
3243         trap clean_foreign_symlink EXIT
3244
3245         # enable foreign_symlink behaviour
3246         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3247
3248         # foreign symlink LMV format is a partial path by default
3249
3250         # create foreign dir (lfs + API)
3251         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3252                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3253                 error "$DIR/$tdir/${tdir}: create failed"
3254
3255         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3256                 grep "lfm_magic:.*0x0CD50CD0" ||
3257                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3258         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3259                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3260         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3261                 grep "lfm_flags:.*0x0000DA05" ||
3262                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3263         $LFS getdirstripe $DIR/$tdir/${tdir} |
3264                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3265                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3266
3267         # file create in dir should fail
3268         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3269         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3270
3271         # rename should succeed
3272         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3273                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3274
3275         #remove foreign_symlink dir should fail
3276         rmdir $DIR/$tdir/${tdir}.new &&
3277                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3278
3279         #test fake symlink
3280         mkdir -p /tmp/${uuid1}/${uuid2} ||
3281                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3282         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3283                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3284         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3285         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3286                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3287         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3288                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3289
3290         #check that getstripe fails now that foreign_symlink enabled
3291         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3292                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3293
3294         # file create in dir should work now
3295         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3296                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3297         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3298                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3299         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3300                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3301
3302         # chmod should still succeed
3303         chmod 755 $DIR/$tdir/${tdir}.new ||
3304                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3305
3306         # chown should still succeed
3307         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3308                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3309
3310         # rename should still succeed
3311         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3312                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3313
3314         #remove foreign_symlink dir should still fail
3315         rmdir $DIR/$tdir/${tdir} &&
3316                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3317
3318         #use special ioctl() to unlink foreign_symlink file
3319         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3320                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3321
3322         #created file should still exist
3323         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3324                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3325         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3326                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3327 }
3328 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3329
3330 test_27Q() {
3331         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3332         stack_trap "rm -f $TMP/$tfile*"
3333
3334         test_mkdir $DIR/$tdir-1
3335         test_mkdir $DIR/$tdir-2
3336
3337         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3338         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3339
3340         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3341         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3342
3343         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3344         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3345
3346         # Create some bad symlinks and ensure that we don't loop
3347         # forever or something. These should return ELOOP (40) and
3348         # ENOENT (2) but I don't want to test for that because there's
3349         # always some weirdo architecture that needs to ruin
3350         # everything by defining these error numbers differently.
3351
3352         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3353         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3354
3355         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3356         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3357
3358         return 0
3359 }
3360 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3361
3362 test_27R() {
3363         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3364                 skip "need MDS 2.14.55 or later"
3365         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3366
3367         local testdir="$DIR/$tdir"
3368         test_mkdir -p $testdir
3369         stack_trap "rm -rf $testdir"
3370         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3371
3372         local f1="$testdir/f1"
3373         touch $f1 || error "failed to touch $f1"
3374         local count=$($LFS getstripe -c $f1)
3375         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3376
3377         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3378         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3379
3380         local maxcount=$(($OSTCOUNT - 1))
3381         local mdts=$(comma_list $(mdts_nodes))
3382         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3383         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3384
3385         local f2="$testdir/f2"
3386         touch $f2 || error "failed to touch $f2"
3387         local count=$($LFS getstripe -c $f2)
3388         (( $count == $maxcount )) || error "wrong stripe count"
3389 }
3390 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3391
3392 test_27S() {
3393         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
3394                 skip "Need MDS version at least 2.14.54"
3395         [[ "$(facet_host mds1)" != "$(facet_host ost1)" ]] ||
3396                 skip "needs different host for mdt1 ost1"
3397
3398         local count=$(precreated_ost_obj_count 0 0)
3399
3400         echo "precreate count $count"
3401         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
3402         $LFS setstripe -i 0 -c 1 $DIR/$tdir || error "setstripe $tdir failed"
3403         #define OBD_FAIL_OSP_GET_LAST_FID       0x2109
3404         do_facet mds1 $LCTL set_param fail_loc=0x2109
3405         #define OBD_FAIL_OST_GET_LAST_FID       0x252
3406         do_facet ost1 $LCTL set_param fail_loc=0x252
3407         createmany -o $DIR/$tdir/f $count &
3408         pid=$!
3409         echo "precreate count $(precreated_ost_obj_count 0 0)"
3410         do_facet mds1 $LCTL set_param fail_loc=0
3411         do_facet ost1 $LCTL set_param fail_loc=0
3412         wait $pid || error "createmany failed"
3413         echo "precreate count $(precreated_ost_obj_count 0 0)"
3414 }
3415 run_test 27S "don't deactivate OSP on network issue"
3416
3417 test_27T() {
3418         [ $(facet_host client) == $(facet_host ost1) ] &&
3419                 skip "need ost1 and client on different nodes"
3420
3421 #define OBD_FAIL_OSC_NO_GRANT            0x411
3422         $LCTL set_param fail_loc=0x20000411 fail_val=1
3423 #define OBD_FAIL_OST_ENOSPC              0x215
3424         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3425         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3426         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3427                 error "multiop failed"
3428 }
3429 run_test 27T "no eio on close on partial write due to enosp"
3430
3431 # createtest also checks that device nodes are created and
3432 # then visible correctly (#2091)
3433 test_28() { # bug 2091
3434         test_mkdir $DIR/d28
3435         $CREATETEST $DIR/d28/ct || error "createtest failed"
3436 }
3437 run_test 28 "create/mknod/mkdir with bad file types ============"
3438
3439 test_29() {
3440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3441
3442         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3443                 disable_opencache
3444                 stack_trap "restore_opencache"
3445         }
3446
3447         sync; sleep 1; sync # flush out any dirty pages from previous tests
3448         cancel_lru_locks
3449         test_mkdir $DIR/d29
3450         touch $DIR/d29/foo
3451         log 'first d29'
3452         ls -l $DIR/d29
3453
3454         declare -i LOCKCOUNTORIG=0
3455         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3456                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3457         done
3458         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3459
3460         declare -i LOCKUNUSEDCOUNTORIG=0
3461         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3462                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3463         done
3464
3465         log 'second d29'
3466         ls -l $DIR/d29
3467         log 'done'
3468
3469         declare -i LOCKCOUNTCURRENT=0
3470         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3471                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3472         done
3473
3474         declare -i LOCKUNUSEDCOUNTCURRENT=0
3475         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3476                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3477         done
3478
3479         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3480                 $LCTL set_param -n ldlm.dump_namespaces ""
3481                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3482                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3483                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3484                 return 2
3485         fi
3486         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3487                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3488                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3489                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3490                 return 3
3491         fi
3492 }
3493 run_test 29 "IT_GETATTR regression  ============================"
3494
3495 test_30a() { # was test_30
3496         cp $(which ls) $DIR || cp /bin/ls $DIR
3497         $DIR/ls / || error "Can't execute binary from lustre"
3498         rm $DIR/ls
3499 }
3500 run_test 30a "execute binary from Lustre (execve) =============="
3501
3502 test_30b() {
3503         cp `which ls` $DIR || cp /bin/ls $DIR
3504         chmod go+rx $DIR/ls
3505         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3506         rm $DIR/ls
3507 }
3508 run_test 30b "execute binary from Lustre as non-root ==========="
3509
3510 test_30c() { # b=22376
3511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3512
3513         cp $(which ls) $DIR || cp /bin/ls $DIR
3514         chmod a-rw $DIR/ls
3515         cancel_lru_locks mdc
3516         cancel_lru_locks osc
3517         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3518         rm -f $DIR/ls
3519 }
3520 run_test 30c "execute binary from Lustre without read perms ===="
3521
3522 test_30d() {
3523         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3524
3525         for i in {1..10}; do
3526                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3527                 local PID=$!
3528                 sleep 1
3529                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3530                 wait $PID || error "executing dd from Lustre failed"
3531                 rm -f $DIR/$tfile
3532         done
3533
3534         rm -f $DIR/dd
3535 }
3536 run_test 30d "execute binary from Lustre while clear locks"
3537
3538 test_31a() {
3539         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3540         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3541 }
3542 run_test 31a "open-unlink file =================================="
3543
3544 test_31b() {
3545         touch $DIR/f31 || error "touch $DIR/f31 failed"
3546         ln $DIR/f31 $DIR/f31b || error "ln failed"
3547         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3548         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3549 }
3550 run_test 31b "unlink file with multiple links while open ======="
3551
3552 test_31c() {
3553         touch $DIR/f31 || error "touch $DIR/f31 failed"
3554         ln $DIR/f31 $DIR/f31c || error "ln failed"
3555         multiop_bg_pause $DIR/f31 O_uc ||
3556                 error "multiop_bg_pause for $DIR/f31 failed"
3557         MULTIPID=$!
3558         $MULTIOP $DIR/f31c Ouc
3559         kill -USR1 $MULTIPID
3560         wait $MULTIPID
3561 }
3562 run_test 31c "open-unlink file with multiple links ============="
3563
3564 test_31d() {
3565         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3566         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3567 }
3568 run_test 31d "remove of open directory ========================="
3569
3570 test_31e() { # bug 2904
3571         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3572 }
3573 run_test 31e "remove of open non-empty directory ==============="
3574
3575 test_31f() { # bug 4554
3576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3577
3578         set -vx
3579         test_mkdir $DIR/d31f
3580         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3581         cp /etc/hosts $DIR/d31f
3582         ls -l $DIR/d31f
3583         $LFS getstripe $DIR/d31f/hosts
3584         multiop_bg_pause $DIR/d31f D_c || return 1
3585         MULTIPID=$!
3586
3587         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3588         test_mkdir $DIR/d31f
3589         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3590         cp /etc/hosts $DIR/d31f
3591         ls -l $DIR/d31f
3592         $LFS getstripe $DIR/d31f/hosts
3593         multiop_bg_pause $DIR/d31f D_c || return 1
3594         MULTIPID2=$!
3595
3596         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3597         wait $MULTIPID || error "first opendir $MULTIPID failed"
3598
3599         sleep 6
3600
3601         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3602         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3603         set +vx
3604 }
3605 run_test 31f "remove of open directory with open-unlink file ==="
3606
3607 test_31g() {
3608         echo "-- cross directory link --"
3609         test_mkdir -c1 $DIR/${tdir}ga
3610         test_mkdir -c1 $DIR/${tdir}gb
3611         touch $DIR/${tdir}ga/f
3612         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3613         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3614         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3615         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3616         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3617 }
3618 run_test 31g "cross directory link==============="
3619
3620 test_31h() {
3621         echo "-- cross directory link --"
3622         test_mkdir -c1 $DIR/${tdir}
3623         test_mkdir -c1 $DIR/${tdir}/dir
3624         touch $DIR/${tdir}/f
3625         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3626         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3627         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3628         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3629         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3630 }
3631 run_test 31h "cross directory link under child==============="
3632
3633 test_31i() {
3634         echo "-- cross directory link --"
3635         test_mkdir -c1 $DIR/$tdir
3636         test_mkdir -c1 $DIR/$tdir/dir
3637         touch $DIR/$tdir/dir/f
3638         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3639         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3640         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3641         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3642         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3643 }
3644 run_test 31i "cross directory link under parent==============="
3645
3646 test_31j() {
3647         test_mkdir -c1 -p $DIR/$tdir
3648         test_mkdir -c1 -p $DIR/$tdir/dir1
3649         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3650         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3651         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3652         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3653         return 0
3654 }
3655 run_test 31j "link for directory==============="
3656
3657 test_31k() {
3658         test_mkdir -c1 -p $DIR/$tdir
3659         touch $DIR/$tdir/s
3660         touch $DIR/$tdir/exist
3661         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3662         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3663         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3664         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3665         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3666         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3667         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3668         return 0
3669 }
3670 run_test 31k "link to file: the same, non-existing, dir==============="
3671
3672 test_31m() {
3673         mkdir $DIR/d31m
3674         touch $DIR/d31m/s
3675         mkdir $DIR/d31m2
3676         touch $DIR/d31m2/exist
3677         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3678         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3679         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3680         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3681         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3682         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3683         return 0
3684 }
3685 run_test 31m "link to file: the same, non-existing, dir==============="
3686
3687 test_31n() {
3688         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3689         nlink=$(stat --format=%h $DIR/$tfile)
3690         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3691         local fd=$(free_fd)
3692         local cmd="exec $fd<$DIR/$tfile"
3693         eval $cmd
3694         cmd="exec $fd<&-"
3695         trap "eval $cmd" EXIT
3696         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3697         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3698         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3699         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3700         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3701         eval $cmd
3702 }
3703 run_test 31n "check link count of unlinked file"
3704
3705 link_one() {
3706         local tempfile=$(mktemp $1_XXXXXX)
3707         mlink $tempfile $1 2> /dev/null &&
3708                 echo "$BASHPID: link $tempfile to $1 succeeded"
3709         munlink $tempfile
3710 }
3711
3712 test_31o() { # LU-2901
3713         test_mkdir $DIR/$tdir
3714         for LOOP in $(seq 100); do
3715                 rm -f $DIR/$tdir/$tfile*
3716                 for THREAD in $(seq 8); do
3717                         link_one $DIR/$tdir/$tfile.$LOOP &
3718                 done
3719                 wait
3720                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3721                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3722                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3723                         break || true
3724         done
3725 }
3726 run_test 31o "duplicate hard links with same filename"
3727
3728 test_31p() {
3729         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3730
3731         test_mkdir $DIR/$tdir
3732         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3733         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3734
3735         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3736                 error "open unlink test1 failed"
3737         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3738                 error "open unlink test2 failed"
3739
3740         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3741                 error "test1 still exists"
3742         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3743                 error "test2 still exists"
3744 }
3745 run_test 31p "remove of open striped directory"
3746
3747 test_31q() {
3748         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3749
3750         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3751         index=$($LFS getdirstripe -i $DIR/$tdir)
3752         [ $index -eq 3 ] || error "first stripe index $index != 3"
3753         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3754         [ $index -eq 1 ] || error "second stripe index $index != 1"
3755
3756         # when "-c <stripe_count>" is set, the number of MDTs specified after
3757         # "-i" should equal to the stripe count
3758         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3759 }
3760 run_test 31q "create striped directory on specific MDTs"
3761
3762 #LU-14949
3763 test_31r() {
3764         touch $DIR/$tfile.target
3765         touch $DIR/$tfile.source
3766
3767         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3768         $LCTL set_param fail_loc=0x1419 fail_val=3
3769         cat $DIR/$tfile.target &
3770         CATPID=$!
3771
3772         # Guarantee open is waiting before we get here
3773         sleep 1
3774         mv $DIR/$tfile.source $DIR/$tfile.target
3775
3776         wait $CATPID
3777         RC=$?
3778         if [[ $RC -ne 0 ]]; then
3779                 error "open with cat failed, rc=$RC"
3780         fi
3781 }
3782 run_test 31r "open-rename(replace) race"
3783
3784 cleanup_test32_mount() {
3785         local rc=0
3786         trap 0
3787         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3788         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3789         losetup -d $loopdev || true
3790         rm -rf $DIR/$tdir
3791         return $rc
3792 }
3793
3794 test_32a() {
3795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3796
3797         echo "== more mountpoints and symlinks ================="
3798         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3799         trap cleanup_test32_mount EXIT
3800         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3801         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3802                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3803         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3804                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3805         cleanup_test32_mount
3806 }
3807 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3808
3809 test_32b() {
3810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3811
3812         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3813         trap cleanup_test32_mount EXIT
3814         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3815         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3816                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3817         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3818                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3819         cleanup_test32_mount
3820 }
3821 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3822
3823 test_32c() {
3824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3825
3826         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3827         trap cleanup_test32_mount EXIT
3828         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3829         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3830                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3831         test_mkdir -p $DIR/$tdir/d2/test_dir
3832         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3833                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3834         cleanup_test32_mount
3835 }
3836 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3837
3838 test_32d() {
3839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3840
3841         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3842         trap cleanup_test32_mount EXIT
3843         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3844         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3845                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3846         test_mkdir -p $DIR/$tdir/d2/test_dir
3847         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3848                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3849         cleanup_test32_mount
3850 }
3851 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3852
3853 test_32e() {
3854         rm -fr $DIR/$tdir
3855         test_mkdir -p $DIR/$tdir/tmp
3856         local tmp_dir=$DIR/$tdir/tmp
3857         ln -s $DIR/$tdir $tmp_dir/symlink11
3858         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3859         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3860         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3861 }
3862 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3863
3864 test_32f() {
3865         rm -fr $DIR/$tdir
3866         test_mkdir -p $DIR/$tdir/tmp
3867         local tmp_dir=$DIR/$tdir/tmp
3868         ln -s $DIR/$tdir $tmp_dir/symlink11
3869         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3870         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3871         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3872 }
3873 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3874
3875 test_32g() {
3876         local tmp_dir=$DIR/$tdir/tmp
3877         test_mkdir -p $tmp_dir
3878         test_mkdir $DIR/${tdir}2
3879         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3880         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3881         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3882         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3883         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3884         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3885 }
3886 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3887
3888 test_32h() {
3889         rm -fr $DIR/$tdir $DIR/${tdir}2
3890         tmp_dir=$DIR/$tdir/tmp
3891         test_mkdir -p $tmp_dir
3892         test_mkdir $DIR/${tdir}2
3893         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3894         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3895         ls $tmp_dir/symlink12 || error "listing symlink12"
3896         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3897 }
3898 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3899
3900 test_32i() {
3901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3902
3903         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3904         trap cleanup_test32_mount EXIT
3905         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3906         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3907                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3908         touch $DIR/$tdir/test_file
3909         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3910                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3911         cleanup_test32_mount
3912 }
3913 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3914
3915 test_32j() {
3916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3917
3918         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3919         trap cleanup_test32_mount EXIT
3920         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3921         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3922                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3923         touch $DIR/$tdir/test_file
3924         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3925                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3926         cleanup_test32_mount
3927 }
3928 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3929
3930 test_32k() {
3931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3932
3933         rm -fr $DIR/$tdir
3934         trap cleanup_test32_mount EXIT
3935         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3936         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3937                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3938         test_mkdir -p $DIR/$tdir/d2
3939         touch $DIR/$tdir/d2/test_file || error "touch failed"
3940         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3941                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3942         cleanup_test32_mount
3943 }
3944 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3945
3946 test_32l() {
3947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3948
3949         rm -fr $DIR/$tdir
3950         trap cleanup_test32_mount EXIT
3951         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3952         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3953                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3954         test_mkdir -p $DIR/$tdir/d2
3955         touch $DIR/$tdir/d2/test_file || error "touch failed"
3956         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3957                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3958         cleanup_test32_mount
3959 }
3960 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3961
3962 test_32m() {
3963         rm -fr $DIR/d32m
3964         test_mkdir -p $DIR/d32m/tmp
3965         TMP_DIR=$DIR/d32m/tmp
3966         ln -s $DIR $TMP_DIR/symlink11
3967         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3968         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3969                 error "symlink11 not a link"
3970         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3971                 error "symlink01 not a link"
3972 }
3973 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3974
3975 test_32n() {
3976         rm -fr $DIR/d32n
3977         test_mkdir -p $DIR/d32n/tmp
3978         TMP_DIR=$DIR/d32n/tmp
3979         ln -s $DIR $TMP_DIR/symlink11
3980         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3981         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3982         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3983 }
3984 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3985
3986 test_32o() {
3987         touch $DIR/$tfile
3988         test_mkdir -p $DIR/d32o/tmp
3989         TMP_DIR=$DIR/d32o/tmp
3990         ln -s $DIR/$tfile $TMP_DIR/symlink12
3991         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3992         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3993                 error "symlink12 not a link"
3994         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3995         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3996                 error "$DIR/d32o/tmp/symlink12 not file type"
3997         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3998                 error "$DIR/d32o/symlink02 not file type"
3999 }
4000 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4001
4002 test_32p() {
4003         log 32p_1
4004         rm -fr $DIR/d32p
4005         log 32p_2
4006         rm -f $DIR/$tfile
4007         log 32p_3
4008         touch $DIR/$tfile
4009         log 32p_4
4010         test_mkdir -p $DIR/d32p/tmp
4011         log 32p_5
4012         TMP_DIR=$DIR/d32p/tmp
4013         log 32p_6
4014         ln -s $DIR/$tfile $TMP_DIR/symlink12
4015         log 32p_7
4016         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4017         log 32p_8
4018         cat $DIR/d32p/tmp/symlink12 ||
4019                 error "Can't open $DIR/d32p/tmp/symlink12"
4020         log 32p_9
4021         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4022         log 32p_10
4023 }
4024 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4025
4026 test_32q() {
4027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4028
4029         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4030         trap cleanup_test32_mount EXIT
4031         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4032         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4033         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4034                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4035         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4036         cleanup_test32_mount
4037 }
4038 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4039
4040 test_32r() {
4041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4042
4043         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4044         trap cleanup_test32_mount EXIT
4045         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4046         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4047         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4048                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4049         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4050         cleanup_test32_mount
4051 }
4052 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4053
4054 test_33aa() {
4055         rm -f $DIR/$tfile
4056         touch $DIR/$tfile
4057         chmod 444 $DIR/$tfile
4058         chown $RUNAS_ID $DIR/$tfile
4059         log 33_1
4060         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4061         log 33_2
4062 }
4063 run_test 33aa "write file with mode 444 (should return error)"
4064
4065 test_33a() {
4066         rm -fr $DIR/$tdir
4067         test_mkdir $DIR/$tdir
4068         chown $RUNAS_ID $DIR/$tdir
4069         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4070                 error "$RUNAS create $tdir/$tfile failed"
4071         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4072                 error "open RDWR" || true
4073 }
4074 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4075
4076 test_33b() {
4077         rm -fr $DIR/$tdir
4078         test_mkdir $DIR/$tdir
4079         chown $RUNAS_ID $DIR/$tdir
4080         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4081 }
4082 run_test 33b "test open file with malformed flags (No panic)"
4083
4084 test_33c() {
4085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4086         remote_ost_nodsh && skip "remote OST with nodsh"
4087
4088         local ostnum
4089         local ostname
4090         local write_bytes
4091         local all_zeros
4092
4093         all_zeros=true
4094         test_mkdir $DIR/$tdir
4095         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4096
4097         sync
4098         for ostnum in $(seq $OSTCOUNT); do
4099                 # test-framework's OST numbering is one-based, while Lustre's
4100                 # is zero-based
4101                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4102                 # check if at least some write_bytes stats are counted
4103                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4104                               obdfilter.$ostname.stats |
4105                               awk '/^write_bytes/ {print $7}' )
4106                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4107                 if (( ${write_bytes:-0} > 0 )); then
4108                         all_zeros=false
4109                         break
4110                 fi
4111         done
4112
4113         $all_zeros || return 0
4114
4115         # Write four bytes
4116         echo foo > $DIR/$tdir/bar
4117         # Really write them
4118         sync
4119
4120         # Total up write_bytes after writing.  We'd better find non-zeros.
4121         for ostnum in $(seq $OSTCOUNT); do
4122                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4123                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4124                               obdfilter/$ostname/stats |
4125                               awk '/^write_bytes/ {print $7}' )
4126                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4127                 if (( ${write_bytes:-0} > 0 )); then
4128                         all_zeros=false
4129                         break
4130                 fi
4131         done
4132
4133         if $all_zeros; then
4134                 for ostnum in $(seq $OSTCOUNT); do
4135                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4136                         echo "Check write_bytes is in obdfilter.*.stats:"
4137                         do_facet ost$ostnum lctl get_param -n \
4138                                 obdfilter.$ostname.stats
4139                 done
4140                 error "OST not keeping write_bytes stats (b=22312)"
4141         fi
4142 }
4143 run_test 33c "test write_bytes stats"
4144
4145 test_33d() {
4146         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4148
4149         local MDTIDX=1
4150         local remote_dir=$DIR/$tdir/remote_dir
4151
4152         test_mkdir $DIR/$tdir
4153         $LFS mkdir -i $MDTIDX $remote_dir ||
4154                 error "create remote directory failed"
4155
4156         touch $remote_dir/$tfile
4157         chmod 444 $remote_dir/$tfile
4158         chown $RUNAS_ID $remote_dir/$tfile
4159
4160         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4161
4162         chown $RUNAS_ID $remote_dir
4163         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4164                                         error "create" || true
4165         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4166                                     error "open RDWR" || true
4167         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4168 }
4169 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4170
4171 test_33e() {
4172         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4173
4174         mkdir $DIR/$tdir
4175
4176         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4177         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4178         mkdir $DIR/$tdir/local_dir
4179
4180         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4181         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4182         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4183
4184         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4185                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4186
4187         rmdir $DIR/$tdir/* || error "rmdir failed"
4188
4189         umask 777
4190         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4191         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4192         mkdir $DIR/$tdir/local_dir
4193
4194         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4195         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4196         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4197
4198         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4199                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4200
4201         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4202
4203         umask 000
4204         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4205         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4206         mkdir $DIR/$tdir/local_dir
4207
4208         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4209         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4210         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4211
4212         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4213                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4214 }
4215 run_test 33e "mkdir and striped directory should have same mode"
4216
4217 cleanup_33f() {
4218         trap 0
4219         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4220 }
4221
4222 test_33f() {
4223         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4224         remote_mds_nodsh && skip "remote MDS with nodsh"
4225
4226         mkdir $DIR/$tdir
4227         chmod go+rwx $DIR/$tdir
4228         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4229         trap cleanup_33f EXIT
4230
4231         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4232                 error "cannot create striped directory"
4233
4234         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4235                 error "cannot create files in striped directory"
4236
4237         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4238                 error "cannot remove files in striped directory"
4239
4240         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4241                 error "cannot remove striped directory"
4242
4243         cleanup_33f
4244 }
4245 run_test 33f "nonroot user can create, access, and remove a striped directory"
4246
4247 test_33g() {
4248         mkdir -p $DIR/$tdir/dir2
4249
4250         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4251         echo $err
4252         [[ $err =~ "exists" ]] || error "Not exists error"
4253 }
4254 run_test 33g "nonroot user create already existing root created file"
4255
4256 test_33h() {
4257         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4258         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4259                 skip "Need MDS version at least 2.13.50"
4260
4261         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4262                 error "mkdir $tdir failed"
4263         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4264
4265         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4266         local index2
4267
4268         for fname in $DIR/$tdir/$tfile.bak \
4269                      $DIR/$tdir/$tfile.SAV \
4270                      $DIR/$tdir/$tfile.orig \
4271                      $DIR/$tdir/$tfile~; do
4272                 touch $fname  || error "touch $fname failed"
4273                 index2=$($LFS getstripe -m $fname)
4274                 [ $index -eq $index2 ] ||
4275                         error "$fname MDT index mismatch $index != $index2"
4276         done
4277
4278         local failed=0
4279         for i in {1..250}; do
4280                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4281                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4282                         touch $fname  || error "touch $fname failed"
4283                         index2=$($LFS getstripe -m $fname)
4284                         if [[ $index != $index2 ]]; then
4285                                 failed=$((failed + 1))
4286                                 echo "$fname MDT index mismatch $index != $index2"
4287                         fi
4288                 done
4289         done
4290         echo "$failed MDT index mismatches"
4291         (( failed < 20 )) || error "MDT index mismatch $failed times"
4292
4293 }
4294 run_test 33h "temp file is located on the same MDT as target"
4295
4296 test_33i()
4297 {
4298         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4299
4300         local FNAME=$(str_repeat 'f' 250)
4301
4302         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4303         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4304
4305         local count
4306         local total
4307
4308         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4309
4310         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4311
4312         lctl --device %$MDC deactivate
4313         stack_trap "lctl --device %$MDC activate"
4314         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4315         total=$(\ls -l $DIR/$tdir | wc -l)
4316         # "ls -l" will list total in the first line
4317         total=$((total - 1))
4318         (( total + count == 1000 )) ||
4319                 error "ls list $total files, $count files on MDT1"
4320 }
4321 run_test 33i "striped directory can be accessed when one MDT is down"
4322
4323 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4324 test_34a() {
4325         rm -f $DIR/f34
4326         $MCREATE $DIR/f34 || error "mcreate failed"
4327         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4328                 error "getstripe failed"
4329         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4330         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4331                 error "getstripe failed"
4332         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4333                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4334 }
4335 run_test 34a "truncate file that has not been opened ==========="
4336
4337 test_34b() {
4338         [ ! -f $DIR/f34 ] && test_34a
4339         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4340                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4341         $OPENFILE -f O_RDONLY $DIR/f34
4342         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4343                 error "getstripe failed"
4344         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4345                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4346 }
4347 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4348
4349 test_34c() {
4350         [ ! -f $DIR/f34 ] && test_34a
4351         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4352                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4353         $OPENFILE -f O_RDWR $DIR/f34
4354         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4355                 error "$LFS getstripe failed"
4356         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4357                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4358 }
4359 run_test 34c "O_RDWR opening file-with-size works =============="
4360
4361 test_34d() {
4362         [ ! -f $DIR/f34 ] && test_34a
4363         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4364                 error "dd failed"
4365         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4366                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4367         rm $DIR/f34
4368 }
4369 run_test 34d "write to sparse file ============================="
4370
4371 test_34e() {
4372         rm -f $DIR/f34e
4373         $MCREATE $DIR/f34e || error "mcreate failed"
4374         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4375         $CHECKSTAT -s 1000 $DIR/f34e ||
4376                 error "Size of $DIR/f34e not equal to 1000 bytes"
4377         $OPENFILE -f O_RDWR $DIR/f34e
4378         $CHECKSTAT -s 1000 $DIR/f34e ||
4379                 error "Size of $DIR/f34e not equal to 1000 bytes"
4380 }
4381 run_test 34e "create objects, some with size and some without =="
4382
4383 test_34f() { # bug 6242, 6243
4384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4385
4386         SIZE34F=48000
4387         rm -f $DIR/f34f
4388         $MCREATE $DIR/f34f || error "mcreate failed"
4389         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4390         dd if=$DIR/f34f of=$TMP/f34f
4391         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4392         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4393         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4394         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4395         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4396 }
4397 run_test 34f "read from a file with no objects until EOF ======="
4398
4399 test_34g() {
4400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4401
4402         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4403                 error "dd failed"
4404         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4405         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4406                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4407         cancel_lru_locks osc
4408         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4409                 error "wrong size after lock cancel"
4410
4411         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4412         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4413                 error "expanding truncate failed"
4414         cancel_lru_locks osc
4415         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4416                 error "wrong expanded size after lock cancel"
4417 }
4418 run_test 34g "truncate long file ==============================="
4419
4420 test_34h() {
4421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4422
4423         local gid=10
4424         local sz=1000
4425
4426         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4427         sync # Flush the cache so that multiop below does not block on cache
4428              # flush when getting the group lock
4429         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4430         MULTIPID=$!
4431
4432         # Since just timed wait is not good enough, let's do a sync write
4433         # that way we are sure enough time for a roundtrip + processing
4434         # passed + 2 seconds of extra margin.
4435         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4436         rm $DIR/${tfile}-1
4437         sleep 2
4438
4439         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4440                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4441                 kill -9 $MULTIPID
4442         fi
4443         wait $MULTIPID
4444         local nsz=`stat -c %s $DIR/$tfile`
4445         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4446 }
4447 run_test 34h "ftruncate file under grouplock should not block"
4448
4449 test_35a() {
4450         cp /bin/sh $DIR/f35a
4451         chmod 444 $DIR/f35a
4452         chown $RUNAS_ID $DIR/f35a
4453         $RUNAS $DIR/f35a && error || true
4454         rm $DIR/f35a
4455 }
4456 run_test 35a "exec file with mode 444 (should return and not leak)"
4457
4458 test_36a() {
4459         rm -f $DIR/f36
4460         utime $DIR/f36 || error "utime failed for MDS"
4461 }
4462 run_test 36a "MDS utime check (mknod, utime)"
4463
4464 test_36b() {
4465         echo "" > $DIR/f36
4466         utime $DIR/f36 || error "utime failed for OST"
4467 }
4468 run_test 36b "OST utime check (open, utime)"
4469
4470 test_36c() {
4471         rm -f $DIR/d36/f36
4472         test_mkdir $DIR/d36
4473         chown $RUNAS_ID $DIR/d36
4474         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4475 }
4476 run_test 36c "non-root MDS utime check (mknod, utime)"
4477
4478 test_36d() {
4479         [ ! -d $DIR/d36 ] && test_36c
4480         echo "" > $DIR/d36/f36
4481         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4482 }
4483 run_test 36d "non-root OST utime check (open, utime)"
4484
4485 test_36e() {
4486         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4487
4488         test_mkdir $DIR/$tdir
4489         touch $DIR/$tdir/$tfile
4490         $RUNAS utime $DIR/$tdir/$tfile &&
4491                 error "utime worked, expected failure" || true
4492 }
4493 run_test 36e "utime on non-owned file (should return error)"
4494
4495 subr_36fh() {
4496         local fl="$1"
4497         local LANG_SAVE=$LANG
4498         local LC_LANG_SAVE=$LC_LANG
4499         export LANG=C LC_LANG=C # for date language
4500
4501         DATESTR="Dec 20  2000"
4502         test_mkdir $DIR/$tdir
4503         lctl set_param fail_loc=$fl
4504         date; date +%s
4505         cp /etc/hosts $DIR/$tdir/$tfile
4506         sync & # write RPC generated with "current" inode timestamp, but delayed
4507         sleep 1
4508         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4509         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4510         cancel_lru_locks $OSC
4511         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4512         date; date +%s
4513         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4514                 echo "BEFORE: $LS_BEFORE" && \
4515                 echo "AFTER : $LS_AFTER" && \
4516                 echo "WANT  : $DATESTR" && \
4517                 error "$DIR/$tdir/$tfile timestamps changed" || true
4518
4519         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4520 }
4521
4522 test_36f() {
4523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4524
4525         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4526         subr_36fh "0x80000214"
4527 }
4528 run_test 36f "utime on file racing with OST BRW write =========="
4529
4530 test_36g() {
4531         remote_ost_nodsh && skip "remote OST with nodsh"
4532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4533         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4534                 skip "Need MDS version at least 2.12.51"
4535
4536         local fmd_max_age
4537         local fmd
4538         local facet="ost1"
4539         local tgt="obdfilter"
4540
4541         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4542
4543         test_mkdir $DIR/$tdir
4544         fmd_max_age=$(do_facet $facet \
4545                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4546                 head -n 1")
4547
4548         echo "FMD max age: ${fmd_max_age}s"
4549         touch $DIR/$tdir/$tfile
4550         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4551                 gawk '{cnt=cnt+$1}  END{print cnt}')
4552         echo "FMD before: $fmd"
4553         [[ $fmd == 0 ]] &&
4554                 error "FMD wasn't create by touch"
4555         sleep $((fmd_max_age + 12))
4556         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4557                 gawk '{cnt=cnt+$1}  END{print cnt}')
4558         echo "FMD after: $fmd"
4559         [[ $fmd == 0 ]] ||
4560                 error "FMD wasn't expired by ping"
4561 }
4562 run_test 36g "FMD cache expiry ====================="
4563
4564 test_36h() {
4565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4566
4567         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4568         subr_36fh "0x80000227"
4569 }
4570 run_test 36h "utime on file racing with OST BRW write =========="
4571
4572 test_36i() {
4573         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4574
4575         test_mkdir $DIR/$tdir
4576         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4577
4578         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4579         local new_mtime=$((mtime + 200))
4580
4581         #change Modify time of striped dir
4582         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4583                         error "change mtime failed"
4584
4585         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4586
4587         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4588 }
4589 run_test 36i "change mtime on striped directory"
4590
4591 # test_37 - duplicate with tests 32q 32r
4592
4593 test_38() {
4594         local file=$DIR/$tfile
4595         touch $file
4596         openfile -f O_DIRECTORY $file
4597         local RC=$?
4598         local ENOTDIR=20
4599         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4600         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4601 }
4602 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4603
4604 test_39a() { # was test_39
4605         touch $DIR/$tfile
4606         touch $DIR/${tfile}2
4607 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4608 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4609 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4610         sleep 2
4611         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4612         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4613                 echo "mtime"
4614                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4615                 echo "atime"
4616                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4617                 echo "ctime"
4618                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4619                 error "O_TRUNC didn't change timestamps"
4620         fi
4621 }
4622 run_test 39a "mtime changed on create"
4623
4624 test_39b() {
4625         test_mkdir -c1 $DIR/$tdir
4626         cp -p /etc/passwd $DIR/$tdir/fopen
4627         cp -p /etc/passwd $DIR/$tdir/flink
4628         cp -p /etc/passwd $DIR/$tdir/funlink
4629         cp -p /etc/passwd $DIR/$tdir/frename
4630         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4631
4632         sleep 1
4633         echo "aaaaaa" >> $DIR/$tdir/fopen
4634         echo "aaaaaa" >> $DIR/$tdir/flink
4635         echo "aaaaaa" >> $DIR/$tdir/funlink
4636         echo "aaaaaa" >> $DIR/$tdir/frename
4637
4638         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4639         local link_new=`stat -c %Y $DIR/$tdir/flink`
4640         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4641         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4642
4643         cat $DIR/$tdir/fopen > /dev/null
4644         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4645         rm -f $DIR/$tdir/funlink2
4646         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4647
4648         for (( i=0; i < 2; i++ )) ; do
4649                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4650                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4651                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4652                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4653
4654                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4655                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4656                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4657                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4658
4659                 cancel_lru_locks $OSC
4660                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4661         done
4662 }
4663 run_test 39b "mtime change on open, link, unlink, rename  ======"
4664
4665 # this should be set to past
4666 TEST_39_MTIME=`date -d "1 year ago" +%s`
4667
4668 # bug 11063
4669 test_39c() {
4670         touch $DIR1/$tfile
4671         sleep 2
4672         local mtime0=`stat -c %Y $DIR1/$tfile`
4673
4674         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4675         local mtime1=`stat -c %Y $DIR1/$tfile`
4676         [ "$mtime1" = $TEST_39_MTIME ] || \
4677                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4678
4679         local d1=`date +%s`
4680         echo hello >> $DIR1/$tfile
4681         local d2=`date +%s`
4682         local mtime2=`stat -c %Y $DIR1/$tfile`
4683         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4684                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4685
4686         mv $DIR1/$tfile $DIR1/$tfile-1
4687
4688         for (( i=0; i < 2; i++ )) ; do
4689                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4690                 [ "$mtime2" = "$mtime3" ] || \
4691                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4692
4693                 cancel_lru_locks $OSC
4694                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4695         done
4696 }
4697 run_test 39c "mtime change on rename ==========================="
4698
4699 # bug 21114
4700 test_39d() {
4701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4702
4703         touch $DIR1/$tfile
4704         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4705
4706         for (( i=0; i < 2; i++ )) ; do
4707                 local mtime=`stat -c %Y $DIR1/$tfile`
4708                 [ $mtime = $TEST_39_MTIME ] || \
4709                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4710
4711                 cancel_lru_locks $OSC
4712                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4713         done
4714 }
4715 run_test 39d "create, utime, stat =============================="
4716
4717 # bug 21114
4718 test_39e() {
4719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4720
4721         touch $DIR1/$tfile
4722         local mtime1=`stat -c %Y $DIR1/$tfile`
4723
4724         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4725
4726         for (( i=0; i < 2; i++ )) ; do
4727                 local mtime2=`stat -c %Y $DIR1/$tfile`
4728                 [ $mtime2 = $TEST_39_MTIME ] || \
4729                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4730
4731                 cancel_lru_locks $OSC
4732                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4733         done
4734 }
4735 run_test 39e "create, stat, utime, stat ========================"
4736
4737 # bug 21114
4738 test_39f() {
4739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4740
4741         touch $DIR1/$tfile
4742         mtime1=`stat -c %Y $DIR1/$tfile`
4743
4744         sleep 2
4745         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4746
4747         for (( i=0; i < 2; i++ )) ; do
4748                 local mtime2=`stat -c %Y $DIR1/$tfile`
4749                 [ $mtime2 = $TEST_39_MTIME ] || \
4750                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4751
4752                 cancel_lru_locks $OSC
4753                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4754         done
4755 }
4756 run_test 39f "create, stat, sleep, utime, stat ================="
4757
4758 # bug 11063
4759 test_39g() {
4760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4761
4762         echo hello >> $DIR1/$tfile
4763         local mtime1=`stat -c %Y $DIR1/$tfile`
4764
4765         sleep 2
4766         chmod o+r $DIR1/$tfile
4767
4768         for (( i=0; i < 2; i++ )) ; do
4769                 local mtime2=`stat -c %Y $DIR1/$tfile`
4770                 [ "$mtime1" = "$mtime2" ] || \
4771                         error "lost mtime: $mtime2, should be $mtime1"
4772
4773                 cancel_lru_locks $OSC
4774                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4775         done
4776 }
4777 run_test 39g "write, chmod, stat ==============================="
4778
4779 # bug 11063
4780 test_39h() {
4781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4782
4783         touch $DIR1/$tfile
4784         sleep 1
4785
4786         local d1=`date`
4787         echo hello >> $DIR1/$tfile
4788         local mtime1=`stat -c %Y $DIR1/$tfile`
4789
4790         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4791         local d2=`date`
4792         if [ "$d1" != "$d2" ]; then
4793                 echo "write and touch not within one second"
4794         else
4795                 for (( i=0; i < 2; i++ )) ; do
4796                         local mtime2=`stat -c %Y $DIR1/$tfile`
4797                         [ "$mtime2" = $TEST_39_MTIME ] || \
4798                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4799
4800                         cancel_lru_locks $OSC
4801                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4802                 done
4803         fi
4804 }
4805 run_test 39h "write, utime within one second, stat ============="
4806
4807 test_39i() {
4808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4809
4810         touch $DIR1/$tfile
4811         sleep 1
4812
4813         echo hello >> $DIR1/$tfile
4814         local mtime1=`stat -c %Y $DIR1/$tfile`
4815
4816         mv $DIR1/$tfile $DIR1/$tfile-1
4817
4818         for (( i=0; i < 2; i++ )) ; do
4819                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4820
4821                 [ "$mtime1" = "$mtime2" ] || \
4822                         error "lost mtime: $mtime2, should be $mtime1"
4823
4824                 cancel_lru_locks $OSC
4825                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4826         done
4827 }
4828 run_test 39i "write, rename, stat =============================="
4829
4830 test_39j() {
4831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4832
4833         start_full_debug_logging
4834         touch $DIR1/$tfile
4835         sleep 1
4836
4837         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4838         lctl set_param fail_loc=0x80000412
4839         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4840                 error "multiop failed"
4841         local multipid=$!
4842         local mtime1=`stat -c %Y $DIR1/$tfile`
4843
4844         mv $DIR1/$tfile $DIR1/$tfile-1
4845
4846         kill -USR1 $multipid
4847         wait $multipid || error "multiop close failed"
4848
4849         for (( i=0; i < 2; i++ )) ; do
4850                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4851                 [ "$mtime1" = "$mtime2" ] ||
4852                         error "mtime is lost on close: $mtime2, " \
4853                               "should be $mtime1"
4854
4855                 cancel_lru_locks
4856                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4857         done
4858         lctl set_param fail_loc=0
4859         stop_full_debug_logging
4860 }
4861 run_test 39j "write, rename, close, stat ======================="
4862
4863 test_39k() {
4864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4865
4866         touch $DIR1/$tfile
4867         sleep 1
4868
4869         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4870         local multipid=$!
4871         local mtime1=`stat -c %Y $DIR1/$tfile`
4872
4873         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4874
4875         kill -USR1 $multipid
4876         wait $multipid || error "multiop close failed"
4877
4878         for (( i=0; i < 2; i++ )) ; do
4879                 local mtime2=`stat -c %Y $DIR1/$tfile`
4880
4881                 [ "$mtime2" = $TEST_39_MTIME ] || \
4882                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4883
4884                 cancel_lru_locks
4885                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4886         done
4887 }
4888 run_test 39k "write, utime, close, stat ========================"
4889
4890 # this should be set to future
4891 TEST_39_ATIME=`date -d "1 year" +%s`
4892
4893 test_39l() {
4894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4895         remote_mds_nodsh && skip "remote MDS with nodsh"
4896
4897         local atime_diff=$(do_facet $SINGLEMDS \
4898                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4899         rm -rf $DIR/$tdir
4900         mkdir_on_mdt0 $DIR/$tdir
4901
4902         # test setting directory atime to future
4903         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4904         local atime=$(stat -c %X $DIR/$tdir)
4905         [ "$atime" = $TEST_39_ATIME ] ||
4906                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4907
4908         # test setting directory atime from future to now
4909         local now=$(date +%s)
4910         touch -a -d @$now $DIR/$tdir
4911
4912         atime=$(stat -c %X $DIR/$tdir)
4913         [ "$atime" -eq "$now"  ] ||
4914                 error "atime is not updated from future: $atime, $now"
4915
4916         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4917         sleep 3
4918
4919         # test setting directory atime when now > dir atime + atime_diff
4920         local d1=$(date +%s)
4921         ls $DIR/$tdir
4922         local d2=$(date +%s)
4923         cancel_lru_locks mdc
4924         atime=$(stat -c %X $DIR/$tdir)
4925         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4926                 error "atime is not updated  : $atime, should be $d2"
4927
4928         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4929         sleep 3
4930
4931         # test not setting directory atime when now < dir atime + atime_diff
4932         ls $DIR/$tdir
4933         cancel_lru_locks mdc
4934         atime=$(stat -c %X $DIR/$tdir)
4935         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4936                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4937
4938         do_facet $SINGLEMDS \
4939                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4940 }
4941 run_test 39l "directory atime update ==========================="
4942
4943 test_39m() {
4944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4945
4946         touch $DIR1/$tfile
4947         sleep 2
4948         local far_past_mtime=$(date -d "May 29 1953" +%s)
4949         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4950
4951         touch -m -d @$far_past_mtime $DIR1/$tfile
4952         touch -a -d @$far_past_atime $DIR1/$tfile
4953
4954         for (( i=0; i < 2; i++ )) ; do
4955                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4956                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4957                         error "atime or mtime set incorrectly"
4958
4959                 cancel_lru_locks $OSC
4960                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4961         done
4962 }
4963 run_test 39m "test atime and mtime before 1970"
4964
4965 test_39n() { # LU-3832
4966         remote_mds_nodsh && skip "remote MDS with nodsh"
4967
4968         local atime_diff=$(do_facet $SINGLEMDS \
4969                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4970         local atime0
4971         local atime1
4972         local atime2
4973
4974         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4975
4976         rm -rf $DIR/$tfile
4977         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4978         atime0=$(stat -c %X $DIR/$tfile)
4979
4980         sleep 5
4981         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4982         atime1=$(stat -c %X $DIR/$tfile)
4983
4984         sleep 5
4985         cancel_lru_locks mdc
4986         cancel_lru_locks osc
4987         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4988         atime2=$(stat -c %X $DIR/$tfile)
4989
4990         do_facet $SINGLEMDS \
4991                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4992
4993         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4994         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4995 }
4996 run_test 39n "check that O_NOATIME is honored"
4997
4998 test_39o() {
4999         TESTDIR=$DIR/$tdir/$tfile
5000         [ -e $TESTDIR ] && rm -rf $TESTDIR
5001         mkdir -p $TESTDIR
5002         cd $TESTDIR
5003         links1=2
5004         ls
5005         mkdir a b
5006         ls
5007         links2=$(stat -c %h .)
5008         [ $(($links1 + 2)) != $links2 ] &&
5009                 error "wrong links count $(($links1 + 2)) != $links2"
5010         rmdir b
5011         links3=$(stat -c %h .)
5012         [ $(($links1 + 1)) != $links3 ] &&
5013                 error "wrong links count $links1 != $links3"
5014         return 0
5015 }
5016 run_test 39o "directory cached attributes updated after create"
5017
5018 test_39p() {
5019         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5020
5021         local MDTIDX=1
5022         TESTDIR=$DIR/$tdir/$tdir
5023         [ -e $TESTDIR ] && rm -rf $TESTDIR
5024         test_mkdir -p $TESTDIR
5025         cd $TESTDIR
5026         links1=2
5027         ls
5028         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5029         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5030         ls
5031         links2=$(stat -c %h .)
5032         [ $(($links1 + 2)) != $links2 ] &&
5033                 error "wrong links count $(($links1 + 2)) != $links2"
5034         rmdir remote_dir2
5035         links3=$(stat -c %h .)
5036         [ $(($links1 + 1)) != $links3 ] &&
5037                 error "wrong links count $links1 != $links3"
5038         return 0
5039 }
5040 run_test 39p "remote directory cached attributes updated after create ========"
5041
5042 test_39r() {
5043         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5044                 skip "no atime update on old OST"
5045         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5046                 skip_env "ldiskfs only test"
5047         fi
5048
5049         local saved_adiff
5050         saved_adiff=$(do_facet ost1 \
5051                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5052         stack_trap "do_facet ost1 \
5053                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5054
5055         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5056
5057         $LFS setstripe -i 0 $DIR/$tfile
5058         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5059                 error "can't write initial file"
5060         cancel_lru_locks osc
5061
5062         # exceed atime_diff and access file
5063         sleep 6
5064         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5065                 error "can't udpate atime"
5066
5067         local atime_cli=$(stat -c %X $DIR/$tfile)
5068         echo "client atime: $atime_cli"
5069         # allow atime update to be written to device
5070         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5071         sleep 5
5072
5073         local ostdev=$(ostdevname 1)
5074         local fid=($(lfs getstripe -y $DIR/$tfile |
5075                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5076         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5077         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5078
5079         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5080         local atime_ost=$(do_facet ost1 "$cmd" |&
5081                           awk -F'[: ]' '/atime:/ { print $4 }')
5082         (( atime_cli == atime_ost )) ||
5083                 error "atime on client $atime_cli != ost $atime_ost"
5084 }
5085 run_test 39r "lazy atime update on OST"
5086
5087 test_39q() { # LU-8041
5088         local testdir=$DIR/$tdir
5089         mkdir -p $testdir
5090         multiop_bg_pause $testdir D_c || error "multiop failed"
5091         local multipid=$!
5092         cancel_lru_locks mdc
5093         kill -USR1 $multipid
5094         local atime=$(stat -c %X $testdir)
5095         [ "$atime" -ne 0 ] || error "atime is zero"
5096 }
5097 run_test 39q "close won't zero out atime"
5098
5099 test_40() {
5100         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5101         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5102                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5103         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5104                 error "$tfile is not 4096 bytes in size"
5105 }
5106 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5107
5108 test_41() {
5109         # bug 1553
5110         small_write $DIR/f41 18
5111 }
5112 run_test 41 "test small file write + fstat ====================="
5113
5114 count_ost_writes() {
5115         lctl get_param -n ${OSC}.*.stats |
5116                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5117                         END { printf("%0.0f", writes) }'
5118 }
5119
5120 # decent default
5121 WRITEBACK_SAVE=500
5122 DIRTY_RATIO_SAVE=40
5123 MAX_DIRTY_RATIO=50
5124 BG_DIRTY_RATIO_SAVE=10
5125 MAX_BG_DIRTY_RATIO=25
5126
5127 start_writeback() {
5128         trap 0
5129         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5130         # dirty_ratio, dirty_background_ratio
5131         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5132                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5133                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5134                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5135         else
5136                 # if file not here, we are a 2.4 kernel
5137                 kill -CONT `pidof kupdated`
5138         fi
5139 }
5140
5141 stop_writeback() {
5142         # setup the trap first, so someone cannot exit the test at the
5143         # exact wrong time and mess up a machine
5144         trap start_writeback EXIT
5145         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5146         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5147                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5148                 sysctl -w vm.dirty_writeback_centisecs=0
5149                 sysctl -w vm.dirty_writeback_centisecs=0
5150                 # save and increase /proc/sys/vm/dirty_ratio
5151                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5152                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5153                 # save and increase /proc/sys/vm/dirty_background_ratio
5154                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5155                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5156         else
5157                 # if file not here, we are a 2.4 kernel
5158                 kill -STOP `pidof kupdated`
5159         fi
5160 }
5161
5162 # ensure that all stripes have some grant before we test client-side cache
5163 setup_test42() {
5164         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5165                 dd if=/dev/zero of=$i bs=4k count=1
5166                 rm $i
5167         done
5168 }
5169
5170 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5171 # file truncation, and file removal.
5172 test_42a() {
5173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5174
5175         setup_test42
5176         cancel_lru_locks $OSC
5177         stop_writeback
5178         sync; sleep 1; sync # just to be safe
5179         BEFOREWRITES=`count_ost_writes`
5180         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5181         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5182         AFTERWRITES=`count_ost_writes`
5183         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5184                 error "$BEFOREWRITES < $AFTERWRITES"
5185         start_writeback
5186 }
5187 run_test 42a "ensure that we don't flush on close"
5188
5189 test_42b() {
5190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5191
5192         setup_test42
5193         cancel_lru_locks $OSC
5194         stop_writeback
5195         sync
5196         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5197         BEFOREWRITES=$(count_ost_writes)
5198         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5199         AFTERWRITES=$(count_ost_writes)
5200         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5201                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5202         fi
5203         BEFOREWRITES=$(count_ost_writes)
5204         sync || error "sync: $?"
5205         AFTERWRITES=$(count_ost_writes)
5206         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5207                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5208         fi
5209         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5210         start_writeback
5211         return 0
5212 }
5213 run_test 42b "test destroy of file with cached dirty data ======"
5214
5215 # if these tests just want to test the effect of truncation,
5216 # they have to be very careful.  consider:
5217 # - the first open gets a {0,EOF}PR lock
5218 # - the first write conflicts and gets a {0, count-1}PW
5219 # - the rest of the writes are under {count,EOF}PW
5220 # - the open for truncate tries to match a {0,EOF}PR
5221 #   for the filesize and cancels the PWs.
5222 # any number of fixes (don't get {0,EOF} on open, match
5223 # composite locks, do smarter file size management) fix
5224 # this, but for now we want these tests to verify that
5225 # the cancellation with truncate intent works, so we
5226 # start the file with a full-file pw lock to match against
5227 # until the truncate.
5228 trunc_test() {
5229         test=$1
5230         file=$DIR/$test
5231         offset=$2
5232         cancel_lru_locks $OSC
5233         stop_writeback
5234         # prime the file with 0,EOF PW to match
5235         touch $file
5236         $TRUNCATE $file 0
5237         sync; sync
5238         # now the real test..
5239         dd if=/dev/zero of=$file bs=1024 count=100
5240         BEFOREWRITES=`count_ost_writes`
5241         $TRUNCATE $file $offset
5242         cancel_lru_locks $OSC
5243         AFTERWRITES=`count_ost_writes`
5244         start_writeback
5245 }
5246
5247 test_42c() {
5248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5249
5250         trunc_test 42c 1024
5251         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5252                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5253         rm $file
5254 }
5255 run_test 42c "test partial truncate of file with cached dirty data"
5256
5257 test_42d() {
5258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5259
5260         trunc_test 42d 0
5261         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5262                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5263         rm $file
5264 }
5265 run_test 42d "test complete truncate of file with cached dirty data"
5266
5267 test_42e() { # bug22074
5268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5269
5270         local TDIR=$DIR/${tdir}e
5271         local pages=16 # hardcoded 16 pages, don't change it.
5272         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5273         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5274         local max_dirty_mb
5275         local warmup_files
5276
5277         test_mkdir $DIR/${tdir}e
5278         $LFS setstripe -c 1 $TDIR
5279         createmany -o $TDIR/f $files
5280
5281         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5282
5283         # we assume that with $OSTCOUNT files, at least one of them will
5284         # be allocated on OST0.
5285         warmup_files=$((OSTCOUNT * max_dirty_mb))
5286         createmany -o $TDIR/w $warmup_files
5287
5288         # write a large amount of data into one file and sync, to get good
5289         # avail_grant number from OST.
5290         for ((i=0; i<$warmup_files; i++)); do
5291                 idx=$($LFS getstripe -i $TDIR/w$i)
5292                 [ $idx -ne 0 ] && continue
5293                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5294                 break
5295         done
5296         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5297         sync
5298         $LCTL get_param $proc_osc0/cur_dirty_bytes
5299         $LCTL get_param $proc_osc0/cur_grant_bytes
5300
5301         # create as much dirty pages as we can while not to trigger the actual
5302         # RPCs directly. but depends on the env, VFS may trigger flush during this
5303         # period, hopefully we are good.
5304         for ((i=0; i<$warmup_files; i++)); do
5305                 idx=$($LFS getstripe -i $TDIR/w$i)
5306                 [ $idx -ne 0 ] && continue
5307                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5308         done
5309         $LCTL get_param $proc_osc0/cur_dirty_bytes
5310         $LCTL get_param $proc_osc0/cur_grant_bytes
5311
5312         # perform the real test
5313         $LCTL set_param $proc_osc0/rpc_stats 0
5314         for ((;i<$files; i++)); do
5315                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5316                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5317         done
5318         sync
5319         $LCTL get_param $proc_osc0/rpc_stats
5320
5321         local percent=0
5322         local have_ppr=false
5323         $LCTL get_param $proc_osc0/rpc_stats |
5324                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5325                         # skip lines until we are at the RPC histogram data
5326                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5327                         $have_ppr || continue
5328
5329                         # we only want the percent stat for < 16 pages
5330                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5331
5332                         percent=$((percent + WPCT))
5333                         if [[ $percent -gt 15 ]]; then
5334                                 error "less than 16-pages write RPCs" \
5335                                       "$percent% > 15%"
5336                                 break
5337                         fi
5338                 done
5339         rm -rf $TDIR
5340 }
5341 run_test 42e "verify sub-RPC writes are not done synchronously"
5342
5343 test_43A() { # was test_43
5344         test_mkdir $DIR/$tdir
5345         cp -p /bin/ls $DIR/$tdir/$tfile
5346         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5347         pid=$!
5348         # give multiop a chance to open
5349         sleep 1
5350
5351         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5352         kill -USR1 $pid
5353         # Wait for multiop to exit
5354         wait $pid
5355 }
5356 run_test 43A "execution of file opened for write should return -ETXTBSY"
5357
5358 test_43a() {
5359         test_mkdir $DIR/$tdir
5360         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5361         $DIR/$tdir/sleep 60 &
5362         SLEEP_PID=$!
5363         # Make sure exec of $tdir/sleep wins race with truncate
5364         sleep 1
5365         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5366         kill $SLEEP_PID
5367 }
5368 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5369
5370 test_43b() {
5371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5372
5373         test_mkdir $DIR/$tdir
5374         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5375         $DIR/$tdir/sleep 60 &
5376         SLEEP_PID=$!
5377         # Make sure exec of $tdir/sleep wins race with truncate
5378         sleep 1
5379         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5380         kill $SLEEP_PID
5381 }
5382 run_test 43b "truncate of file being executed should return -ETXTBSY"
5383
5384 test_43c() {
5385         local testdir="$DIR/$tdir"
5386         test_mkdir $testdir
5387         cp $SHELL $testdir/
5388         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5389                 ( cd $testdir && md5sum -c )
5390 }
5391 run_test 43c "md5sum of copy into lustre"
5392
5393 test_44A() { # was test_44
5394         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5395
5396         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5397         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5398 }
5399 run_test 44A "zero length read from a sparse stripe"
5400
5401 test_44a() {
5402         local nstripe=$($LFS getstripe -c -d $DIR)
5403         [ -z "$nstripe" ] && skip "can't get stripe info"
5404         [[ $nstripe -gt $OSTCOUNT ]] &&
5405                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5406
5407         local stride=$($LFS getstripe -S -d $DIR)
5408         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5409                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5410         fi
5411
5412         OFFSETS="0 $((stride/2)) $((stride-1))"
5413         for offset in $OFFSETS; do
5414                 for i in $(seq 0 $((nstripe-1))); do
5415                         local GLOBALOFFSETS=""
5416                         # size in Bytes
5417                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5418                         local myfn=$DIR/d44a-$size
5419                         echo "--------writing $myfn at $size"
5420                         ll_sparseness_write $myfn $size ||
5421                                 error "ll_sparseness_write"
5422                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5423                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5424                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5425
5426                         for j in $(seq 0 $((nstripe-1))); do
5427                                 # size in Bytes
5428                                 size=$((((j + $nstripe )*$stride + $offset)))
5429                                 ll_sparseness_write $myfn $size ||
5430                                         error "ll_sparseness_write"
5431                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5432                         done
5433                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5434                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5435                         rm -f $myfn
5436                 done
5437         done
5438 }
5439 run_test 44a "test sparse pwrite ==============================="
5440
5441 dirty_osc_total() {
5442         tot=0
5443         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5444                 tot=$(($tot + $d))
5445         done
5446         echo $tot
5447 }
5448 do_dirty_record() {
5449         before=`dirty_osc_total`
5450         echo executing "\"$*\""
5451         eval $*
5452         after=`dirty_osc_total`
5453         echo before $before, after $after
5454 }
5455 test_45() {
5456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5457
5458         f="$DIR/f45"
5459         # Obtain grants from OST if it supports it
5460         echo blah > ${f}_grant
5461         stop_writeback
5462         sync
5463         do_dirty_record "echo blah > $f"
5464         [[ $before -eq $after ]] && error "write wasn't cached"
5465         do_dirty_record "> $f"
5466         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5467         do_dirty_record "echo blah > $f"
5468         [[ $before -eq $after ]] && error "write wasn't cached"
5469         do_dirty_record "sync"
5470         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5471         do_dirty_record "echo blah > $f"
5472         [[ $before -eq $after ]] && error "write wasn't cached"
5473         do_dirty_record "cancel_lru_locks osc"
5474         [[ $before -gt $after ]] ||
5475                 error "lock cancellation didn't lower dirty count"
5476         start_writeback
5477 }
5478 run_test 45 "osc io page accounting ============================"
5479
5480 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5481 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5482 # objects offset and an assert hit when an rpc was built with 1023's mapped
5483 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5484 test_46() {
5485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5486
5487         f="$DIR/f46"
5488         stop_writeback
5489         sync
5490         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5491         sync
5492         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5493         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5494         sync
5495         start_writeback
5496 }
5497 run_test 46 "dirtying a previously written page ================"
5498
5499 # test_47 is removed "Device nodes check" is moved to test_28
5500
5501 test_48a() { # bug 2399
5502         [ "$mds1_FSTYPE" = "zfs" ] &&
5503         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5504                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5505
5506         test_mkdir $DIR/$tdir
5507         cd $DIR/$tdir
5508         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5509         test_mkdir $DIR/$tdir
5510         touch foo || error "'touch foo' failed after recreating cwd"
5511         test_mkdir bar
5512         touch .foo || error "'touch .foo' failed after recreating cwd"
5513         test_mkdir .bar
5514         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5515         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5516         cd . || error "'cd .' failed after recreating cwd"
5517         mkdir . && error "'mkdir .' worked after recreating cwd"
5518         rmdir . && error "'rmdir .' worked after recreating cwd"
5519         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5520         cd .. || error "'cd ..' failed after recreating cwd"
5521 }
5522 run_test 48a "Access renamed working dir (should return errors)="
5523
5524 test_48b() { # bug 2399
5525         rm -rf $DIR/$tdir
5526         test_mkdir $DIR/$tdir
5527         cd $DIR/$tdir
5528         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5529         touch foo && error "'touch foo' worked after removing cwd"
5530         mkdir foo && error "'mkdir foo' worked after removing cwd"
5531         touch .foo && error "'touch .foo' worked after removing cwd"
5532         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5533         ls . > /dev/null && error "'ls .' worked after removing cwd"
5534         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5535         mkdir . && error "'mkdir .' worked after removing cwd"
5536         rmdir . && error "'rmdir .' worked after removing cwd"
5537         ln -s . foo && error "'ln -s .' worked after removing cwd"
5538         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5539 }
5540 run_test 48b "Access removed working dir (should return errors)="
5541
5542 test_48c() { # bug 2350
5543         #lctl set_param debug=-1
5544         #set -vx
5545         rm -rf $DIR/$tdir
5546         test_mkdir -p $DIR/$tdir/dir
5547         cd $DIR/$tdir/dir
5548         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5549         $TRACE touch foo && error "touch foo worked after removing cwd"
5550         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5551         touch .foo && error "touch .foo worked after removing cwd"
5552         mkdir .foo && error "mkdir .foo worked after removing cwd"
5553         $TRACE ls . && error "'ls .' worked after removing cwd"
5554         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5555         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5556         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5557         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5558         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5559 }
5560 run_test 48c "Access removed working subdir (should return errors)"
5561
5562 test_48d() { # bug 2350
5563         #lctl set_param debug=-1
5564         #set -vx
5565         rm -rf $DIR/$tdir
5566         test_mkdir -p $DIR/$tdir/dir
5567         cd $DIR/$tdir/dir
5568         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5569         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5570         $TRACE touch foo && error "'touch foo' worked after removing parent"
5571         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5572         touch .foo && error "'touch .foo' worked after removing parent"
5573         mkdir .foo && error "mkdir .foo worked after removing parent"
5574         $TRACE ls . && error "'ls .' worked after removing parent"
5575         $TRACE ls .. && error "'ls ..' worked after removing parent"
5576         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5577         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5578         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5579         true
5580 }
5581 run_test 48d "Access removed parent subdir (should return errors)"
5582
5583 test_48e() { # bug 4134
5584         #lctl set_param debug=-1
5585         #set -vx
5586         rm -rf $DIR/$tdir
5587         test_mkdir -p $DIR/$tdir/dir
5588         cd $DIR/$tdir/dir
5589         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5590         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5591         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5592         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5593         # On a buggy kernel addition of "touch foo" after cd .. will
5594         # produce kernel oops in lookup_hash_it
5595         touch ../foo && error "'cd ..' worked after recreate parent"
5596         cd $DIR
5597         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5598 }
5599 run_test 48e "Access to recreated parent subdir (should return errors)"
5600
5601 test_48f() {
5602         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5603                 skip "need MDS >= 2.13.55"
5604         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5605         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5606                 skip "needs different host for mdt1 mdt2"
5607         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5608
5609         $LFS mkdir -i0 $DIR/$tdir
5610         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5611
5612         for d in sub1 sub2 sub3; do
5613                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5614                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5615                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5616         done
5617
5618         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5619 }
5620 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5621
5622 test_49() { # LU-1030
5623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5624         remote_ost_nodsh && skip "remote OST with nodsh"
5625
5626         # get ost1 size - $FSNAME-OST0000
5627         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5628                 awk '{ print $4 }')
5629         # write 800M at maximum
5630         [[ $ost1_size -lt 2 ]] && ost1_size=2
5631         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5632
5633         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5634         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5635         local dd_pid=$!
5636
5637         # change max_pages_per_rpc while writing the file
5638         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5639         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5640         # loop until dd process exits
5641         while ps ax -opid | grep -wq $dd_pid; do
5642                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5643                 sleep $((RANDOM % 5 + 1))
5644         done
5645         # restore original max_pages_per_rpc
5646         $LCTL set_param $osc1_mppc=$orig_mppc
5647         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5648 }
5649 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5650
5651 test_50() {
5652         # bug 1485
5653         test_mkdir $DIR/$tdir
5654         cd $DIR/$tdir
5655         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5656 }
5657 run_test 50 "special situations: /proc symlinks  ==============="
5658
5659 test_51a() {    # was test_51
5660         # bug 1516 - create an empty entry right after ".." then split dir
5661         test_mkdir -c1 $DIR/$tdir
5662         touch $DIR/$tdir/foo
5663         $MCREATE $DIR/$tdir/bar
5664         rm $DIR/$tdir/foo
5665         createmany -m $DIR/$tdir/longfile 201
5666         FNUM=202
5667         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5668                 $MCREATE $DIR/$tdir/longfile$FNUM
5669                 FNUM=$(($FNUM + 1))
5670                 echo -n "+"
5671         done
5672         echo
5673         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5674 }
5675 run_test 51a "special situations: split htree with empty entry =="
5676
5677 cleanup_print_lfs_df () {
5678         trap 0
5679         $LFS df
5680         $LFS df -i
5681 }
5682
5683 test_51b() {
5684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5685
5686         local dir=$DIR/$tdir
5687         local nrdirs=$((65536 + 100))
5688
5689         # cleanup the directory
5690         rm -fr $dir
5691
5692         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5693
5694         $LFS df
5695         $LFS df -i
5696         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5697         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5698         [[ $numfree -lt $nrdirs ]] &&
5699                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5700
5701         # need to check free space for the directories as well
5702         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5703         numfree=$(( blkfree / $(fs_inode_ksize) ))
5704         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5705
5706         trap cleanup_print_lfs_df EXIT
5707
5708         # create files
5709         createmany -d $dir/d $nrdirs || {
5710                 unlinkmany $dir/d $nrdirs
5711                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5712         }
5713
5714         # really created :
5715         nrdirs=$(ls -U $dir | wc -l)
5716
5717         # unlink all but 100 subdirectories, then check it still works
5718         local left=100
5719         local delete=$((nrdirs - left))
5720
5721         $LFS df
5722         $LFS df -i
5723
5724         # for ldiskfs the nlink count should be 1, but this is OSD specific
5725         # and so this is listed for informational purposes only
5726         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5727         unlinkmany -d $dir/d $delete ||
5728                 error "unlink of first $delete subdirs failed"
5729
5730         echo "nlink between: $(stat -c %h $dir)"
5731         local found=$(ls -U $dir | wc -l)
5732         [ $found -ne $left ] &&
5733                 error "can't find subdirs: found only $found, expected $left"
5734
5735         unlinkmany -d $dir/d $delete $left ||
5736                 error "unlink of second $left subdirs failed"
5737         # regardless of whether the backing filesystem tracks nlink accurately
5738         # or not, the nlink count shouldn't be more than "." and ".." here
5739         local after=$(stat -c %h $dir)
5740         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5741                 echo "nlink after: $after"
5742
5743         cleanup_print_lfs_df
5744 }
5745 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5746
5747 test_51d() {
5748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5749         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5750         local qos_old
5751
5752         test_mkdir $DIR/$tdir
5753         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5754
5755         qos_old=$(do_facet mds1 \
5756                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5757         do_nodes $(comma_list $(mdts_nodes)) \
5758                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5759         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5760                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5761
5762         createmany -o $DIR/$tdir/t- 1000
5763         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5764         for ((n = 0; n < $OSTCOUNT; n++)); do
5765                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5766                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5767                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5768                             '($1 == '$n') { objs += 1 } \
5769                             END { printf("%0.0f", objs) }')
5770                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5771         done
5772         unlinkmany $DIR/$tdir/t- 1000
5773
5774         nlast=0
5775         for ((n = 0; n < $OSTCOUNT; n++)); do
5776                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5777                         { $LFS df && $LFS df -i &&
5778                         error "OST $n has fewer objects vs. OST $nlast" \
5779                               " (${objs[$n]} < ${objs[$nlast]}"; }
5780                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5781                         { $LFS df && $LFS df -i &&
5782                         error "OST $n has fewer objects vs. OST $nlast" \
5783                               " (${objs[$n]} < ${objs[$nlast]}"; }
5784
5785                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5786                         { $LFS df && $LFS df -i &&
5787                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5788                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5789                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5790                         { $LFS df && $LFS df -i &&
5791                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5792                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5793                 nlast=$n
5794         done
5795 }
5796 run_test 51d "check object distribution"
5797
5798 test_51e() {
5799         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5800                 skip_env "ldiskfs only test"
5801         fi
5802
5803         test_mkdir -c1 $DIR/$tdir
5804         test_mkdir -c1 $DIR/$tdir/d0
5805
5806         touch $DIR/$tdir/d0/foo
5807         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5808                 error "file exceed 65000 nlink limit!"
5809         unlinkmany $DIR/$tdir/d0/f- 65001
5810         return 0
5811 }
5812 run_test 51e "check file nlink limit"
5813
5814 test_51f() {
5815         test_mkdir $DIR/$tdir
5816
5817         local max=100000
5818         local ulimit_old=$(ulimit -n)
5819         local spare=20 # number of spare fd's for scripts/libraries, etc.
5820         local mdt=$($LFS getstripe -m $DIR/$tdir)
5821         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5822
5823         echo "MDT$mdt numfree=$numfree, max=$max"
5824         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5825         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5826                 while ! ulimit -n $((numfree + spare)); do
5827                         numfree=$((numfree * 3 / 4))
5828                 done
5829                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5830         else
5831                 echo "left ulimit at $ulimit_old"
5832         fi
5833
5834         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5835                 unlinkmany $DIR/$tdir/f $numfree
5836                 error "create+open $numfree files in $DIR/$tdir failed"
5837         }
5838         ulimit -n $ulimit_old
5839
5840         # if createmany exits at 120s there will be fewer than $numfree files
5841         unlinkmany $DIR/$tdir/f $numfree || true
5842 }
5843 run_test 51f "check many open files limit"
5844
5845 test_52a() {
5846         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5847         test_mkdir $DIR/$tdir
5848         touch $DIR/$tdir/foo
5849         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5850         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5851         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5852         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5853         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5854                                         error "link worked"
5855         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5856         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5857         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5858                                                      error "lsattr"
5859         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5860         cp -r $DIR/$tdir $TMP/
5861         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5862 }
5863 run_test 52a "append-only flag test (should return errors)"
5864
5865 test_52b() {
5866         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5867         test_mkdir $DIR/$tdir
5868         touch $DIR/$tdir/foo
5869         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5870         cat test > $DIR/$tdir/foo && error "cat test worked"
5871         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5872         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5873         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5874                                         error "link worked"
5875         echo foo >> $DIR/$tdir/foo && error "echo worked"
5876         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5877         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5878         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5879         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5880                                                         error "lsattr"
5881         chattr -i $DIR/$tdir/foo || error "chattr failed"
5882
5883         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5884 }
5885 run_test 52b "immutable flag test (should return errors) ======="
5886
5887 test_53() {
5888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5889         remote_mds_nodsh && skip "remote MDS with nodsh"
5890         remote_ost_nodsh && skip "remote OST with nodsh"
5891
5892         local param
5893         local param_seq
5894         local ostname
5895         local mds_last
5896         local mds_last_seq
5897         local ost_last
5898         local ost_last_seq
5899         local ost_last_id
5900         local ostnum
5901         local node
5902         local found=false
5903         local support_last_seq=true
5904
5905         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5906                 support_last_seq=false
5907
5908         # only test MDT0000
5909         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5910         local value
5911         for value in $(do_facet $SINGLEMDS \
5912                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5913                 param=$(echo ${value[0]} | cut -d "=" -f1)
5914                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5915
5916                 if $support_last_seq; then
5917                         param_seq=$(echo $param |
5918                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5919                         mds_last_seq=$(do_facet $SINGLEMDS \
5920                                        $LCTL get_param -n $param_seq)
5921                 fi
5922                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5923
5924                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5925                 node=$(facet_active_host ost$((ostnum+1)))
5926                 param="obdfilter.$ostname.last_id"
5927                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5928                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5929                         ost_last_id=$ost_last
5930
5931                         if $support_last_seq; then
5932                                 ost_last_id=$(echo $ost_last |
5933                                               awk -F':' '{print $2}' |
5934                                               sed -e "s/^0x//g")
5935                                 ost_last_seq=$(echo $ost_last |
5936                                                awk -F':' '{print $1}')
5937                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5938                         fi
5939
5940                         if [[ $ost_last_id != $mds_last ]]; then
5941                                 error "$ost_last_id != $mds_last"
5942                         else
5943                                 found=true
5944                                 break
5945                         fi
5946                 done
5947         done
5948         $found || error "can not match last_seq/last_id for $mdtosc"
5949         return 0
5950 }
5951 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5952
5953 test_54a() {
5954         perl -MSocket -e ';' || skip "no Socket perl module installed"
5955
5956         $SOCKETSERVER $DIR/socket ||
5957                 error "$SOCKETSERVER $DIR/socket failed: $?"
5958         $SOCKETCLIENT $DIR/socket ||
5959                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5960         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5961 }
5962 run_test 54a "unix domain socket test =========================="
5963
5964 test_54b() {
5965         f="$DIR/f54b"
5966         mknod $f c 1 3
5967         chmod 0666 $f
5968         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5969 }
5970 run_test 54b "char device works in lustre ======================"
5971
5972 find_loop_dev() {
5973         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5974         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5975         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5976
5977         for i in $(seq 3 7); do
5978                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5979                 LOOPDEV=$LOOPBASE$i
5980                 LOOPNUM=$i
5981                 break
5982         done
5983 }
5984
5985 cleanup_54c() {
5986         local rc=0
5987         loopdev="$DIR/loop54c"
5988
5989         trap 0
5990         $UMOUNT $DIR/$tdir || rc=$?
5991         losetup -d $loopdev || true
5992         losetup -d $LOOPDEV || true
5993         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5994         return $rc
5995 }
5996
5997 test_54c() {
5998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5999
6000         loopdev="$DIR/loop54c"
6001
6002         find_loop_dev
6003         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6004         trap cleanup_54c EXIT
6005         mknod $loopdev b 7 $LOOPNUM
6006         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6007         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6008         losetup $loopdev $DIR/$tfile ||
6009                 error "can't set up $loopdev for $DIR/$tfile"
6010         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6011         test_mkdir $DIR/$tdir
6012         mount -t ext2 $loopdev $DIR/$tdir ||
6013                 error "error mounting $loopdev on $DIR/$tdir"
6014         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6015                 error "dd write"
6016         df $DIR/$tdir
6017         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6018                 error "dd read"
6019         cleanup_54c
6020 }
6021 run_test 54c "block device works in lustre ====================="
6022
6023 test_54d() {
6024         f="$DIR/f54d"
6025         string="aaaaaa"
6026         mknod $f p
6027         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
6028 }
6029 run_test 54d "fifo device works in lustre ======================"
6030
6031 test_54e() {
6032         f="$DIR/f54e"
6033         string="aaaaaa"
6034         cp -aL /dev/console $f
6035         echo $string > $f || error "echo $string to $f failed"
6036 }
6037 run_test 54e "console/tty device works in lustre ======================"
6038
6039 test_56a() {
6040         local numfiles=3
6041         local numdirs=2
6042         local dir=$DIR/$tdir
6043
6044         rm -rf $dir
6045         test_mkdir -p $dir/dir
6046         for i in $(seq $numfiles); do
6047                 touch $dir/file$i
6048                 touch $dir/dir/file$i
6049         done
6050
6051         local numcomp=$($LFS getstripe --component-count $dir)
6052
6053         [[ $numcomp == 0 ]] && numcomp=1
6054
6055         # test lfs getstripe with --recursive
6056         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6057
6058         [[ $filenum -eq $((numfiles * 2)) ]] ||
6059                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6060         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6061         [[ $filenum -eq $numfiles ]] ||
6062                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6063         echo "$LFS getstripe showed obdidx or l_ost_idx"
6064
6065         # test lfs getstripe with file instead of dir
6066         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6067         [[ $filenum -eq 1 ]] ||
6068                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6069         echo "$LFS getstripe file1 passed"
6070
6071         #test lfs getstripe with --verbose
6072         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6073         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6074                 error "$LFS getstripe --verbose $dir: "\
6075                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6076         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6077                 error "$LFS getstripe $dir: showed lmm_magic"
6078
6079         #test lfs getstripe with -v prints lmm_fid
6080         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6081         local countfids=$((numdirs + numfiles * numcomp))
6082         [[ $filenum -eq $countfids ]] ||
6083                 error "$LFS getstripe -v $dir: "\
6084                       "got $filenum want $countfids lmm_fid"
6085         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6086                 error "$LFS getstripe $dir: showed lmm_fid by default"
6087         echo "$LFS getstripe --verbose passed"
6088
6089         #check for FID information
6090         local fid1=$($LFS getstripe --fid $dir/file1)
6091         local fid2=$($LFS getstripe --verbose $dir/file1 |
6092                      awk '/lmm_fid: / { print $2; exit; }')
6093         local fid3=$($LFS path2fid $dir/file1)
6094
6095         [ "$fid1" != "$fid2" ] &&
6096                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6097         [ "$fid1" != "$fid3" ] &&
6098                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6099         echo "$LFS getstripe --fid passed"
6100
6101         #test lfs getstripe with --obd
6102         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6103                 error "$LFS getstripe --obd wrong_uuid: should return error"
6104
6105         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6106
6107         local ostidx=1
6108         local obduuid=$(ostuuid_from_index $ostidx)
6109         local found=$($LFS getstripe -r --obd $obduuid $dir |
6110                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6111
6112         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6113         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6114                 ((filenum--))
6115         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6116                 ((filenum--))
6117
6118         [[ $found -eq $filenum ]] ||
6119                 error "$LFS getstripe --obd: found $found expect $filenum"
6120         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6121                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6122                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6123                 error "$LFS getstripe --obd: should not show file on other obd"
6124         echo "$LFS getstripe --obd passed"
6125 }
6126 run_test 56a "check $LFS getstripe"
6127
6128 test_56b() {
6129         local dir=$DIR/$tdir
6130         local numdirs=3
6131
6132         test_mkdir $dir
6133         for i in $(seq $numdirs); do
6134                 test_mkdir $dir/dir$i
6135         done
6136
6137         # test lfs getdirstripe default mode is non-recursion, which is
6138         # different from lfs getstripe
6139         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6140
6141         [[ $dircnt -eq 1 ]] ||
6142                 error "$LFS getdirstripe: found $dircnt, not 1"
6143         dircnt=$($LFS getdirstripe --recursive $dir |
6144                 grep -c lmv_stripe_count)
6145         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6146                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6147 }
6148 run_test 56b "check $LFS getdirstripe"
6149
6150 test_56c() {
6151         remote_ost_nodsh && skip "remote OST with nodsh"
6152
6153         local ost_idx=0
6154         local ost_name=$(ostname_from_index $ost_idx)
6155         local old_status=$(ost_dev_status $ost_idx)
6156         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6157
6158         [[ -z "$old_status" ]] ||
6159                 skip_env "OST $ost_name is in $old_status status"
6160
6161         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6162         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6163                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6164         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6165                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6166                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6167         fi
6168
6169         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6170                 error "$LFS df -v showing inactive devices"
6171         sleep_maxage
6172
6173         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6174
6175         [[ "$new_status" =~ "D" ]] ||
6176                 error "$ost_name status is '$new_status', missing 'D'"
6177         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6178                 [[ "$new_status" =~ "N" ]] ||
6179                         error "$ost_name status is '$new_status', missing 'N'"
6180         fi
6181         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6182                 [[ "$new_status" =~ "f" ]] ||
6183                         error "$ost_name status is '$new_status', missing 'f'"
6184         fi
6185
6186         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6187         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6188                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6189         [[ -z "$p" ]] && restore_lustre_params < $p || true
6190         sleep_maxage
6191
6192         new_status=$(ost_dev_status $ost_idx)
6193         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6194                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6195         # can't check 'f' as devices may actually be on flash
6196 }
6197 run_test 56c "check 'lfs df' showing device status"
6198
6199 test_56d() {
6200         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6201         local osts=$($LFS df -v $MOUNT | grep -c OST)
6202
6203         $LFS df $MOUNT
6204
6205         (( mdts == MDSCOUNT )) ||
6206                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6207         (( osts == OSTCOUNT )) ||
6208                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6209 }
6210 run_test 56d "'lfs df -v' prints only configured devices"
6211
6212 test_56e() {
6213         err_enoent=2 # No such file or directory
6214         err_eopnotsupp=95 # Operation not supported
6215
6216         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6217         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6218
6219         # Check for handling of path not exists
6220         output=$($LFS df $enoent_mnt 2>&1)
6221         ret=$?
6222
6223         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6224         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6225                 error "expect failure $err_enoent, not $ret"
6226
6227         # Check for handling of non-Lustre FS
6228         output=$($LFS df $notsup_mnt)
6229         ret=$?
6230
6231         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6232         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6233                 error "expect success $err_eopnotsupp, not $ret"
6234
6235         # Check for multiple LustreFS argument
6236         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6237         ret=$?
6238
6239         [[ $output -eq 3 && $ret -eq 0 ]] ||
6240                 error "expect success 3, not $output, rc = $ret"
6241
6242         # Check for correct non-Lustre FS handling among multiple
6243         # LustreFS argument
6244         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6245                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6246         ret=$?
6247
6248         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6249                 error "expect success 2, not $output, rc = $ret"
6250 }
6251 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6252
6253 NUMFILES=3
6254 NUMDIRS=3
6255 setup_56() {
6256         local local_tdir="$1"
6257         local local_numfiles="$2"
6258         local local_numdirs="$3"
6259         local dir_params="$4"
6260         local dir_stripe_params="$5"
6261
6262         if [ ! -d "$local_tdir" ] ; then
6263                 test_mkdir -p $dir_stripe_params $local_tdir
6264                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6265                 for i in $(seq $local_numfiles) ; do
6266                         touch $local_tdir/file$i
6267                 done
6268                 for i in $(seq $local_numdirs) ; do
6269                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6270                         for j in $(seq $local_numfiles) ; do
6271                                 touch $local_tdir/dir$i/file$j
6272                         done
6273                 done
6274         fi
6275 }
6276
6277 setup_56_special() {
6278         local local_tdir=$1
6279         local local_numfiles=$2
6280         local local_numdirs=$3
6281
6282         setup_56 $local_tdir $local_numfiles $local_numdirs
6283
6284         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6285                 for i in $(seq $local_numfiles) ; do
6286                         mknod $local_tdir/loop${i}b b 7 $i
6287                         mknod $local_tdir/null${i}c c 1 3
6288                         ln -s $local_tdir/file1 $local_tdir/link${i}
6289                 done
6290                 for i in $(seq $local_numdirs) ; do
6291                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6292                         mknod $local_tdir/dir$i/null${i}c c 1 3
6293                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6294                 done
6295         fi
6296 }
6297
6298 test_56g() {
6299         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6300         local expected=$(($NUMDIRS + 2))
6301
6302         setup_56 $dir $NUMFILES $NUMDIRS
6303
6304         # test lfs find with -name
6305         for i in $(seq $NUMFILES) ; do
6306                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6307
6308                 [ $nums -eq $expected ] ||
6309                         error "lfs find -name '*$i' $dir wrong: "\
6310                               "found $nums, expected $expected"
6311         done
6312 }
6313 run_test 56g "check lfs find -name"
6314
6315 test_56h() {
6316         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6317         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6318
6319         setup_56 $dir $NUMFILES $NUMDIRS
6320
6321         # test lfs find with ! -name
6322         for i in $(seq $NUMFILES) ; do
6323                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6324
6325                 [ $nums -eq $expected ] ||
6326                         error "lfs find ! -name '*$i' $dir wrong: "\
6327                               "found $nums, expected $expected"
6328         done
6329 }
6330 run_test 56h "check lfs find ! -name"
6331
6332 test_56i() {
6333         local dir=$DIR/$tdir
6334
6335         test_mkdir $dir
6336
6337         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6338         local out=$($cmd)
6339
6340         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6341 }
6342 run_test 56i "check 'lfs find -ost UUID' skips directories"
6343
6344 test_56j() {
6345         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6346
6347         setup_56_special $dir $NUMFILES $NUMDIRS
6348
6349         local expected=$((NUMDIRS + 1))
6350         local cmd="$LFS find -type d $dir"
6351         local nums=$($cmd | wc -l)
6352
6353         [ $nums -eq $expected ] ||
6354                 error "'$cmd' wrong: found $nums, expected $expected"
6355 }
6356 run_test 56j "check lfs find -type d"
6357
6358 test_56k() {
6359         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6360
6361         setup_56_special $dir $NUMFILES $NUMDIRS
6362
6363         local expected=$(((NUMDIRS + 1) * NUMFILES))
6364         local cmd="$LFS find -type f $dir"
6365         local nums=$($cmd | wc -l)
6366
6367         [ $nums -eq $expected ] ||
6368                 error "'$cmd' wrong: found $nums, expected $expected"
6369 }
6370 run_test 56k "check lfs find -type f"
6371
6372 test_56l() {
6373         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6374
6375         setup_56_special $dir $NUMFILES $NUMDIRS
6376
6377         local expected=$((NUMDIRS + NUMFILES))
6378         local cmd="$LFS find -type b $dir"
6379         local nums=$($cmd | wc -l)
6380
6381         [ $nums -eq $expected ] ||
6382                 error "'$cmd' wrong: found $nums, expected $expected"
6383 }
6384 run_test 56l "check lfs find -type b"
6385
6386 test_56m() {
6387         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6388
6389         setup_56_special $dir $NUMFILES $NUMDIRS
6390
6391         local expected=$((NUMDIRS + NUMFILES))
6392         local cmd="$LFS find -type c $dir"
6393         local nums=$($cmd | wc -l)
6394         [ $nums -eq $expected ] ||
6395                 error "'$cmd' wrong: found $nums, expected $expected"
6396 }
6397 run_test 56m "check lfs find -type c"
6398
6399 test_56n() {
6400         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6401         setup_56_special $dir $NUMFILES $NUMDIRS
6402
6403         local expected=$((NUMDIRS + NUMFILES))
6404         local cmd="$LFS find -type l $dir"
6405         local nums=$($cmd | wc -l)
6406
6407         [ $nums -eq $expected ] ||
6408                 error "'$cmd' wrong: found $nums, expected $expected"
6409 }
6410 run_test 56n "check lfs find -type l"
6411
6412 test_56o() {
6413         local dir=$DIR/$tdir
6414
6415         setup_56 $dir $NUMFILES $NUMDIRS
6416         utime $dir/file1 > /dev/null || error "utime (1)"
6417         utime $dir/file2 > /dev/null || error "utime (2)"
6418         utime $dir/dir1 > /dev/null || error "utime (3)"
6419         utime $dir/dir2 > /dev/null || error "utime (4)"
6420         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6421         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6422
6423         local expected=4
6424         local nums=$($LFS find -mtime +0 $dir | wc -l)
6425
6426         [ $nums -eq $expected ] ||
6427                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6428
6429         expected=12
6430         cmd="$LFS find -mtime 0 $dir"
6431         nums=$($cmd | wc -l)
6432         [ $nums -eq $expected ] ||
6433                 error "'$cmd' wrong: found $nums, expected $expected"
6434 }
6435 run_test 56o "check lfs find -mtime for old files"
6436
6437 test_56ob() {
6438         local dir=$DIR/$tdir
6439         local expected=1
6440         local count=0
6441
6442         # just to make sure there is something that won't be found
6443         test_mkdir $dir
6444         touch $dir/$tfile.now
6445
6446         for age in year week day hour min; do
6447                 count=$((count + 1))
6448
6449                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6450                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6451                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6452
6453                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6454                 local nums=$($cmd | wc -l)
6455                 [ $nums -eq $expected ] ||
6456                         error "'$cmd' wrong: found $nums, expected $expected"
6457
6458                 cmd="$LFS find $dir -atime $count${age:0:1}"
6459                 nums=$($cmd | wc -l)
6460                 [ $nums -eq $expected ] ||
6461                         error "'$cmd' wrong: found $nums, expected $expected"
6462         done
6463
6464         sleep 2
6465         cmd="$LFS find $dir -ctime +1s -type f"
6466         nums=$($cmd | wc -l)
6467         (( $nums == $count * 2 + 1)) ||
6468                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6469 }
6470 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6471
6472 test_newerXY_base() {
6473         local x=$1
6474         local y=$2
6475         local dir=$DIR/$tdir
6476         local ref
6477         local negref
6478
6479         if [ $y == "t" ]; then
6480                 if [ $x == "b" ]; then
6481                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6482                 else
6483                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6484                 fi
6485         else
6486                 ref=$DIR/$tfile.newer.$x$y
6487                 touch $ref || error "touch $ref failed"
6488         fi
6489
6490         echo "before = $ref"
6491         sleep 2
6492         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6493         sleep 2
6494         if [ $y == "t" ]; then
6495                 if [ $x == "b" ]; then
6496                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6497                 else
6498                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6499                 fi
6500         else
6501                 negref=$DIR/$tfile.negnewer.$x$y
6502                 touch $negref || error "touch $negref failed"
6503         fi
6504
6505         echo "after = $negref"
6506         local cmd="$LFS find $dir -newer$x$y $ref"
6507         local nums=$(eval $cmd | wc -l)
6508         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6509
6510         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6511                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6512
6513         cmd="$LFS find $dir ! -newer$x$y $negref"
6514         nums=$(eval $cmd | wc -l)
6515         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6516                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6517
6518         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6519         nums=$(eval $cmd | wc -l)
6520         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6521                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6522
6523         rm -rf $DIR/*
6524 }
6525
6526 test_56oc() {
6527         test_newerXY_base "a" "a"
6528         test_newerXY_base "a" "m"
6529         test_newerXY_base "a" "c"
6530         test_newerXY_base "m" "a"
6531         test_newerXY_base "m" "m"
6532         test_newerXY_base "m" "c"
6533         test_newerXY_base "c" "a"
6534         test_newerXY_base "c" "m"
6535         test_newerXY_base "c" "c"
6536
6537         [[ -n "$sles_version" ]] &&
6538                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6539
6540         test_newerXY_base "a" "t"
6541         test_newerXY_base "m" "t"
6542         test_newerXY_base "c" "t"
6543
6544         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6545            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6546                 ! btime_supported && echo "btime unsupported" && return 0
6547
6548         test_newerXY_base "b" "b"
6549         test_newerXY_base "b" "t"
6550 }
6551 run_test 56oc "check lfs find -newerXY work"
6552
6553 btime_supported() {
6554         local dir=$DIR/$tdir
6555         local rc
6556
6557         mkdir -p $dir
6558         touch $dir/$tfile
6559         $LFS find $dir -btime -1d -type f
6560         rc=$?
6561         rm -rf $dir
6562         return $rc
6563 }
6564
6565 test_56od() {
6566         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6567                 ! btime_supported && skip "btime unsupported on MDS"
6568
6569         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6570                 ! btime_supported && skip "btime unsupported on clients"
6571
6572         local dir=$DIR/$tdir
6573         local ref=$DIR/$tfile.ref
6574         local negref=$DIR/$tfile.negref
6575
6576         mkdir $dir || error "mkdir $dir failed"
6577         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6578         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6579         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6580         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6581         touch $ref || error "touch $ref failed"
6582         # sleep 3 seconds at least
6583         sleep 3
6584
6585         local before=$(do_facet mds1 date +%s)
6586         local skew=$(($(date +%s) - before + 1))
6587
6588         if (( skew < 0 && skew > -5 )); then
6589                 sleep $((0 - skew + 1))
6590                 skew=0
6591         fi
6592
6593         # Set the dir stripe params to limit files all on MDT0,
6594         # otherwise we need to calc the max clock skew between
6595         # the client and MDTs.
6596         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6597         sleep 2
6598         touch $negref || error "touch $negref failed"
6599
6600         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6601         local nums=$($cmd | wc -l)
6602         local expected=$(((NUMFILES + 1) * NUMDIRS))
6603
6604         [ $nums -eq $expected ] ||
6605                 error "'$cmd' wrong: found $nums, expected $expected"
6606
6607         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6608         nums=$($cmd | wc -l)
6609         expected=$((NUMFILES + 1))
6610         [ $nums -eq $expected ] ||
6611                 error "'$cmd' wrong: found $nums, expected $expected"
6612
6613         [ $skew -lt 0 ] && return
6614
6615         local after=$(do_facet mds1 date +%s)
6616         local age=$((after - before + 1 + skew))
6617
6618         cmd="$LFS find $dir -btime -${age}s -type f"
6619         nums=$($cmd | wc -l)
6620         expected=$(((NUMFILES + 1) * NUMDIRS))
6621
6622         echo "Clock skew between client and server: $skew, age:$age"
6623         [ $nums -eq $expected ] ||
6624                 error "'$cmd' wrong: found $nums, expected $expected"
6625
6626         expected=$(($NUMDIRS + 1))
6627         cmd="$LFS find $dir -btime -${age}s -type d"
6628         nums=$($cmd | wc -l)
6629         [ $nums -eq $expected ] ||
6630                 error "'$cmd' wrong: found $nums, expected $expected"
6631         rm -f $ref $negref || error "Failed to remove $ref $negref"
6632 }
6633 run_test 56od "check lfs find -btime with units"
6634
6635 test_56p() {
6636         [ $RUNAS_ID -eq $UID ] &&
6637                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6638
6639         local dir=$DIR/$tdir
6640
6641         setup_56 $dir $NUMFILES $NUMDIRS
6642         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6643
6644         local expected=$NUMFILES
6645         local cmd="$LFS find -uid $RUNAS_ID $dir"
6646         local nums=$($cmd | wc -l)
6647
6648         [ $nums -eq $expected ] ||
6649                 error "'$cmd' wrong: found $nums, expected $expected"
6650
6651         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6652         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6653         nums=$($cmd | wc -l)
6654         [ $nums -eq $expected ] ||
6655                 error "'$cmd' wrong: found $nums, expected $expected"
6656 }
6657 run_test 56p "check lfs find -uid and ! -uid"
6658
6659 test_56q() {
6660         [ $RUNAS_ID -eq $UID ] &&
6661                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6662
6663         local dir=$DIR/$tdir
6664
6665         setup_56 $dir $NUMFILES $NUMDIRS
6666         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6667
6668         local expected=$NUMFILES
6669         local cmd="$LFS find -gid $RUNAS_GID $dir"
6670         local nums=$($cmd | wc -l)
6671
6672         [ $nums -eq $expected ] ||
6673                 error "'$cmd' wrong: found $nums, expected $expected"
6674
6675         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6676         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6677         nums=$($cmd | wc -l)
6678         [ $nums -eq $expected ] ||
6679                 error "'$cmd' wrong: found $nums, expected $expected"
6680 }
6681 run_test 56q "check lfs find -gid and ! -gid"
6682
6683 test_56r() {
6684         local dir=$DIR/$tdir
6685
6686         setup_56 $dir $NUMFILES $NUMDIRS
6687
6688         local expected=12
6689         local cmd="$LFS find -size 0 -type f -lazy $dir"
6690         local nums=$($cmd | wc -l)
6691
6692         [ $nums -eq $expected ] ||
6693                 error "'$cmd' wrong: found $nums, expected $expected"
6694         cmd="$LFS find -size 0 -type f $dir"
6695         nums=$($cmd | wc -l)
6696         [ $nums -eq $expected ] ||
6697                 error "'$cmd' wrong: found $nums, expected $expected"
6698
6699         expected=0
6700         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6701         nums=$($cmd | wc -l)
6702         [ $nums -eq $expected ] ||
6703                 error "'$cmd' wrong: found $nums, expected $expected"
6704         cmd="$LFS find ! -size 0 -type f $dir"
6705         nums=$($cmd | wc -l)
6706         [ $nums -eq $expected ] ||
6707                 error "'$cmd' wrong: found $nums, expected $expected"
6708
6709         echo "test" > $dir/$tfile
6710         echo "test2" > $dir/$tfile.2 && sync
6711         expected=1
6712         cmd="$LFS find -size 5 -type f -lazy $dir"
6713         nums=$($cmd | wc -l)
6714         [ $nums -eq $expected ] ||
6715                 error "'$cmd' wrong: found $nums, expected $expected"
6716         cmd="$LFS find -size 5 -type f $dir"
6717         nums=$($cmd | wc -l)
6718         [ $nums -eq $expected ] ||
6719                 error "'$cmd' wrong: found $nums, expected $expected"
6720
6721         expected=1
6722         cmd="$LFS find -size +5 -type f -lazy $dir"
6723         nums=$($cmd | wc -l)
6724         [ $nums -eq $expected ] ||
6725                 error "'$cmd' wrong: found $nums, expected $expected"
6726         cmd="$LFS find -size +5 -type f $dir"
6727         nums=$($cmd | wc -l)
6728         [ $nums -eq $expected ] ||
6729                 error "'$cmd' wrong: found $nums, expected $expected"
6730
6731         expected=2
6732         cmd="$LFS find -size +0 -type f -lazy $dir"
6733         nums=$($cmd | wc -l)
6734         [ $nums -eq $expected ] ||
6735                 error "'$cmd' wrong: found $nums, expected $expected"
6736         cmd="$LFS find -size +0 -type f $dir"
6737         nums=$($cmd | wc -l)
6738         [ $nums -eq $expected ] ||
6739                 error "'$cmd' wrong: found $nums, expected $expected"
6740
6741         expected=2
6742         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6743         nums=$($cmd | wc -l)
6744         [ $nums -eq $expected ] ||
6745                 error "'$cmd' wrong: found $nums, expected $expected"
6746         cmd="$LFS find ! -size -5 -type f $dir"
6747         nums=$($cmd | wc -l)
6748         [ $nums -eq $expected ] ||
6749                 error "'$cmd' wrong: found $nums, expected $expected"
6750
6751         expected=12
6752         cmd="$LFS find -size -5 -type f -lazy $dir"
6753         nums=$($cmd | wc -l)
6754         [ $nums -eq $expected ] ||
6755                 error "'$cmd' wrong: found $nums, expected $expected"
6756         cmd="$LFS find -size -5 -type f $dir"
6757         nums=$($cmd | wc -l)
6758         [ $nums -eq $expected ] ||
6759                 error "'$cmd' wrong: found $nums, expected $expected"
6760 }
6761 run_test 56r "check lfs find -size works"
6762
6763 test_56ra_sub() {
6764         local expected=$1
6765         local glimpses=$2
6766         local cmd="$3"
6767
6768         cancel_lru_locks $OSC
6769
6770         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6771         local nums=$($cmd | wc -l)
6772
6773         [ $nums -eq $expected ] ||
6774                 error "'$cmd' wrong: found $nums, expected $expected"
6775
6776         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6777
6778         if (( rpcs_before + glimpses != rpcs_after )); then
6779                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6780                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6781
6782                 if [[ $glimpses == 0 ]]; then
6783                         error "'$cmd' should not send glimpse RPCs to OST"
6784                 else
6785                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6786                 fi
6787         fi
6788 }
6789
6790 test_56ra() {
6791         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6792                 skip "MDS < 2.12.58 doesn't return LSOM data"
6793         local dir=$DIR/$tdir
6794         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6795
6796         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6797
6798         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6799         $LCTL set_param -n llite.*.statahead_agl=0
6800         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6801
6802         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6803         # open and close all files to ensure LSOM is updated
6804         cancel_lru_locks $OSC
6805         find $dir -type f | xargs cat > /dev/null
6806
6807         #   expect_found  glimpse_rpcs  command_to_run
6808         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6809         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6810         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6811         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6812
6813         echo "test" > $dir/$tfile
6814         echo "test2" > $dir/$tfile.2 && sync
6815         cancel_lru_locks $OSC
6816         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6817
6818         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6819         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6820         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6821         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6822
6823         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6824         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6825         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6826         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6827         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6828         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6829 }
6830 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6831
6832 test_56rb() {
6833         local dir=$DIR/$tdir
6834         local tmp=$TMP/$tfile.log
6835         local mdt_idx;
6836
6837         test_mkdir -p $dir || error "failed to mkdir $dir"
6838         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6839                 error "failed to setstripe $dir/$tfile"
6840         mdt_idx=$($LFS getdirstripe -i $dir)
6841         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6842
6843         stack_trap "rm -f $tmp" EXIT
6844         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6845         ! grep -q obd_uuid $tmp ||
6846                 error "failed to find --size +100K --ost 0 $dir"
6847         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6848         ! grep -q obd_uuid $tmp ||
6849                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6850 }
6851 run_test 56rb "check lfs find --size --ost/--mdt works"
6852
6853 test_56rc() {
6854         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6855         local dir=$DIR/$tdir
6856         local found
6857
6858         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6859         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6860         (( $MDSCOUNT > 2 )) &&
6861                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6862         mkdir $dir/$tdir-{1..10}
6863         touch $dir/$tfile-{1..10}
6864
6865         found=$($LFS find $dir --mdt-count 2 | wc -l)
6866         expect=11
6867         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6868
6869         found=$($LFS find $dir -T +1 | wc -l)
6870         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6871         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6872
6873         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6874         expect=11
6875         (( $found == $expect )) || error "found $found all_char, expect $expect"
6876
6877         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6878         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6879         (( $found == $expect )) || error "found $found all_char, expect $expect"
6880 }
6881 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6882
6883 test_56s() { # LU-611 #LU-9369
6884         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6885
6886         local dir=$DIR/$tdir
6887         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6888
6889         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6890         for i in $(seq $NUMDIRS); do
6891                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6892         done
6893
6894         local expected=$NUMDIRS
6895         local cmd="$LFS find -c $OSTCOUNT $dir"
6896         local nums=$($cmd | wc -l)
6897
6898         [ $nums -eq $expected ] || {
6899                 $LFS getstripe -R $dir
6900                 error "'$cmd' wrong: found $nums, expected $expected"
6901         }
6902
6903         expected=$((NUMDIRS + onestripe))
6904         cmd="$LFS find -stripe-count +0 -type f $dir"
6905         nums=$($cmd | wc -l)
6906         [ $nums -eq $expected ] || {
6907                 $LFS getstripe -R $dir
6908                 error "'$cmd' wrong: found $nums, expected $expected"
6909         }
6910
6911         expected=$onestripe
6912         cmd="$LFS find -stripe-count 1 -type f $dir"
6913         nums=$($cmd | wc -l)
6914         [ $nums -eq $expected ] || {
6915                 $LFS getstripe -R $dir
6916                 error "'$cmd' wrong: found $nums, expected $expected"
6917         }
6918
6919         cmd="$LFS find -stripe-count -2 -type f $dir"
6920         nums=$($cmd | wc -l)
6921         [ $nums -eq $expected ] || {
6922                 $LFS getstripe -R $dir
6923                 error "'$cmd' wrong: found $nums, expected $expected"
6924         }
6925
6926         expected=0
6927         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6928         nums=$($cmd | wc -l)
6929         [ $nums -eq $expected ] || {
6930                 $LFS getstripe -R $dir
6931                 error "'$cmd' wrong: found $nums, expected $expected"
6932         }
6933 }
6934 run_test 56s "check lfs find -stripe-count works"
6935
6936 test_56t() { # LU-611 #LU-9369
6937         local dir=$DIR/$tdir
6938
6939         setup_56 $dir 0 $NUMDIRS
6940         for i in $(seq $NUMDIRS); do
6941                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6942         done
6943
6944         local expected=$NUMDIRS
6945         local cmd="$LFS find -S 8M $dir"
6946         local nums=$($cmd | wc -l)
6947
6948         [ $nums -eq $expected ] || {
6949                 $LFS getstripe -R $dir
6950                 error "'$cmd' wrong: found $nums, expected $expected"
6951         }
6952         rm -rf $dir
6953
6954         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6955
6956         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6957
6958         expected=$(((NUMDIRS + 1) * NUMFILES))
6959         cmd="$LFS find -stripe-size 512k -type f $dir"
6960         nums=$($cmd | wc -l)
6961         [ $nums -eq $expected ] ||
6962                 error "'$cmd' wrong: found $nums, expected $expected"
6963
6964         cmd="$LFS find -stripe-size +320k -type f $dir"
6965         nums=$($cmd | wc -l)
6966         [ $nums -eq $expected ] ||
6967                 error "'$cmd' wrong: found $nums, expected $expected"
6968
6969         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6970         cmd="$LFS find -stripe-size +200k -type f $dir"
6971         nums=$($cmd | wc -l)
6972         [ $nums -eq $expected ] ||
6973                 error "'$cmd' wrong: found $nums, expected $expected"
6974
6975         cmd="$LFS find -stripe-size -640k -type f $dir"
6976         nums=$($cmd | wc -l)
6977         [ $nums -eq $expected ] ||
6978                 error "'$cmd' wrong: found $nums, expected $expected"
6979
6980         expected=4
6981         cmd="$LFS find -stripe-size 256k -type f $dir"
6982         nums=$($cmd | wc -l)
6983         [ $nums -eq $expected ] ||
6984                 error "'$cmd' wrong: found $nums, expected $expected"
6985
6986         cmd="$LFS find -stripe-size -320k -type f $dir"
6987         nums=$($cmd | wc -l)
6988         [ $nums -eq $expected ] ||
6989                 error "'$cmd' wrong: found $nums, expected $expected"
6990
6991         expected=0
6992         cmd="$LFS find -stripe-size 1024k -type f $dir"
6993         nums=$($cmd | wc -l)
6994         [ $nums -eq $expected ] ||
6995                 error "'$cmd' wrong: found $nums, expected $expected"
6996 }
6997 run_test 56t "check lfs find -stripe-size works"
6998
6999 test_56u() { # LU-611
7000         local dir=$DIR/$tdir
7001
7002         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7003
7004         if [[ $OSTCOUNT -gt 1 ]]; then
7005                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7006                 onestripe=4
7007         else
7008                 onestripe=0
7009         fi
7010
7011         local expected=$(((NUMDIRS + 1) * NUMFILES))
7012         local cmd="$LFS find -stripe-index 0 -type f $dir"
7013         local nums=$($cmd | wc -l)
7014
7015         [ $nums -eq $expected ] ||
7016                 error "'$cmd' wrong: found $nums, expected $expected"
7017
7018         expected=$onestripe
7019         cmd="$LFS find -stripe-index 1 -type f $dir"
7020         nums=$($cmd | wc -l)
7021         [ $nums -eq $expected ] ||
7022                 error "'$cmd' wrong: found $nums, expected $expected"
7023
7024         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7025         nums=$($cmd | wc -l)
7026         [ $nums -eq $expected ] ||
7027                 error "'$cmd' wrong: found $nums, expected $expected"
7028
7029         expected=0
7030         # This should produce an error and not return any files
7031         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7032         nums=$($cmd 2>/dev/null | wc -l)
7033         [ $nums -eq $expected ] ||
7034                 error "'$cmd' wrong: found $nums, expected $expected"
7035
7036         if [[ $OSTCOUNT -gt 1 ]]; then
7037                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7038                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7039                 nums=$($cmd | wc -l)
7040                 [ $nums -eq $expected ] ||
7041                         error "'$cmd' wrong: found $nums, expected $expected"
7042         fi
7043 }
7044 run_test 56u "check lfs find -stripe-index works"
7045
7046 test_56v() {
7047         local mdt_idx=0
7048         local dir=$DIR/$tdir
7049
7050         setup_56 $dir $NUMFILES $NUMDIRS
7051
7052         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7053         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7054
7055         for file in $($LFS find -m $UUID $dir); do
7056                 file_midx=$($LFS getstripe -m $file)
7057                 [ $file_midx -eq $mdt_idx ] ||
7058                         error "lfs find -m $UUID != getstripe -m $file_midx"
7059         done
7060 }
7061 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7062
7063 test_56w() {
7064         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7066
7067         local dir=$DIR/$tdir
7068
7069         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7070
7071         local stripe_size=$($LFS getstripe -S -d $dir) ||
7072                 error "$LFS getstripe -S -d $dir failed"
7073         stripe_size=${stripe_size%% *}
7074
7075         local file_size=$((stripe_size * OSTCOUNT))
7076         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7077         local required_space=$((file_num * file_size))
7078         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7079                            head -n1)
7080         [[ $free_space -le $((required_space / 1024)) ]] &&
7081                 skip_env "need $required_space, have $free_space kbytes"
7082
7083         local dd_bs=65536
7084         local dd_count=$((file_size / dd_bs))
7085
7086         # write data into the files
7087         local i
7088         local j
7089         local file
7090
7091         for i in $(seq $NUMFILES); do
7092                 file=$dir/file$i
7093                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7094                         error "write data into $file failed"
7095         done
7096         for i in $(seq $NUMDIRS); do
7097                 for j in $(seq $NUMFILES); do
7098                         file=$dir/dir$i/file$j
7099                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7100                                 error "write data into $file failed"
7101                 done
7102         done
7103
7104         # $LFS_MIGRATE will fail if hard link migration is unsupported
7105         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7106                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7107                         error "creating links to $dir/dir1/file1 failed"
7108         fi
7109
7110         local expected=-1
7111
7112         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7113
7114         # lfs_migrate file
7115         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7116
7117         echo "$cmd"
7118         eval $cmd || error "$cmd failed"
7119
7120         check_stripe_count $dir/file1 $expected
7121
7122         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7123         then
7124                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7125                 # OST 1 if it is on OST 0. This file is small enough to
7126                 # be on only one stripe.
7127                 file=$dir/migr_1_ost
7128                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7129                         error "write data into $file failed"
7130                 local obdidx=$($LFS getstripe -i $file)
7131                 local oldmd5=$(md5sum $file)
7132                 local newobdidx=0
7133
7134                 [[ $obdidx -eq 0 ]] && newobdidx=1
7135                 cmd="$LFS migrate -i $newobdidx $file"
7136                 echo $cmd
7137                 eval $cmd || error "$cmd failed"
7138
7139                 local realobdix=$($LFS getstripe -i $file)
7140                 local newmd5=$(md5sum $file)
7141
7142                 [[ $newobdidx -ne $realobdix ]] &&
7143                         error "new OST is different (was=$obdidx, "\
7144                               "wanted=$newobdidx, got=$realobdix)"
7145                 [[ "$oldmd5" != "$newmd5" ]] &&
7146                         error "md5sum differ: $oldmd5, $newmd5"
7147         fi
7148
7149         # lfs_migrate dir
7150         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7151         echo "$cmd"
7152         eval $cmd || error "$cmd failed"
7153
7154         for j in $(seq $NUMFILES); do
7155                 check_stripe_count $dir/dir1/file$j $expected
7156         done
7157
7158         # lfs_migrate works with lfs find
7159         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7160              $LFS_MIGRATE -y -c $expected"
7161         echo "$cmd"
7162         eval $cmd || error "$cmd failed"
7163
7164         for i in $(seq 2 $NUMFILES); do
7165                 check_stripe_count $dir/file$i $expected
7166         done
7167         for i in $(seq 2 $NUMDIRS); do
7168                 for j in $(seq $NUMFILES); do
7169                 check_stripe_count $dir/dir$i/file$j $expected
7170                 done
7171         done
7172 }
7173 run_test 56w "check lfs_migrate -c stripe_count works"
7174
7175 test_56wb() {
7176         local file1=$DIR/$tdir/file1
7177         local create_pool=false
7178         local initial_pool=$($LFS getstripe -p $DIR)
7179         local pool_list=()
7180         local pool=""
7181
7182         echo -n "Creating test dir..."
7183         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7184         echo "done."
7185
7186         echo -n "Creating test file..."
7187         touch $file1 || error "cannot create file"
7188         echo "done."
7189
7190         echo -n "Detecting existing pools..."
7191         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7192
7193         if [ ${#pool_list[@]} -gt 0 ]; then
7194                 echo "${pool_list[@]}"
7195                 for thispool in "${pool_list[@]}"; do
7196                         if [[ -z "$initial_pool" ||
7197                               "$initial_pool" != "$thispool" ]]; then
7198                                 pool="$thispool"
7199                                 echo "Using existing pool '$pool'"
7200                                 break
7201                         fi
7202                 done
7203         else
7204                 echo "none detected."
7205         fi
7206         if [ -z "$pool" ]; then
7207                 pool=${POOL:-testpool}
7208                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7209                 echo -n "Creating pool '$pool'..."
7210                 create_pool=true
7211                 pool_add $pool &> /dev/null ||
7212                         error "pool_add failed"
7213                 echo "done."
7214
7215                 echo -n "Adding target to pool..."
7216                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7217                         error "pool_add_targets failed"
7218                 echo "done."
7219         fi
7220
7221         echo -n "Setting pool using -p option..."
7222         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7223                 error "migrate failed rc = $?"
7224         echo "done."
7225
7226         echo -n "Verifying test file is in pool after migrating..."
7227         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7228                 error "file was not migrated to pool $pool"
7229         echo "done."
7230
7231         echo -n "Removing test file from pool '$pool'..."
7232         # "lfs migrate $file" won't remove the file from the pool
7233         # until some striping information is changed.
7234         $LFS migrate -c 1 $file1 &> /dev/null ||
7235                 error "cannot remove from pool"
7236         [ "$($LFS getstripe -p $file1)" ] &&
7237                 error "pool still set"
7238         echo "done."
7239
7240         echo -n "Setting pool using --pool option..."
7241         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7242                 error "migrate failed rc = $?"
7243         echo "done."
7244
7245         # Clean up
7246         rm -f $file1
7247         if $create_pool; then
7248                 destroy_test_pools 2> /dev/null ||
7249                         error "destroy test pools failed"
7250         fi
7251 }
7252 run_test 56wb "check lfs_migrate pool support"
7253
7254 test_56wc() {
7255         local file1="$DIR/$tdir/file1"
7256         local parent_ssize
7257         local parent_scount
7258         local cur_ssize
7259         local cur_scount
7260         local orig_ssize
7261
7262         echo -n "Creating test dir..."
7263         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7264         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7265                 error "cannot set stripe by '-S 1M -c 1'"
7266         echo "done"
7267
7268         echo -n "Setting initial stripe for test file..."
7269         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7270                 error "cannot set stripe"
7271         cur_ssize=$($LFS getstripe -S "$file1")
7272         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7273         echo "done."
7274
7275         # File currently set to -S 512K -c 1
7276
7277         # Ensure -c and -S options are rejected when -R is set
7278         echo -n "Verifying incompatible options are detected..."
7279         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7280                 error "incompatible -c and -R options not detected"
7281         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7282                 error "incompatible -S and -R options not detected"
7283         echo "done."
7284
7285         # Ensure unrecognized options are passed through to 'lfs migrate'
7286         echo -n "Verifying -S option is passed through to lfs migrate..."
7287         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7288                 error "migration failed"
7289         cur_ssize=$($LFS getstripe -S "$file1")
7290         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7291         echo "done."
7292
7293         # File currently set to -S 1M -c 1
7294
7295         # Ensure long options are supported
7296         echo -n "Verifying long options supported..."
7297         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7298                 error "long option without argument not supported"
7299         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7300                 error "long option with argument not supported"
7301         cur_ssize=$($LFS getstripe -S "$file1")
7302         [ $cur_ssize -eq 524288 ] ||
7303                 error "migrate --stripe-size $cur_ssize != 524288"
7304         echo "done."
7305
7306         # File currently set to -S 512K -c 1
7307
7308         if [ "$OSTCOUNT" -gt 1 ]; then
7309                 echo -n "Verifying explicit stripe count can be set..."
7310                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7311                         error "migrate failed"
7312                 cur_scount=$($LFS getstripe -c "$file1")
7313                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7314                 echo "done."
7315         fi
7316
7317         # File currently set to -S 512K -c 1 or -S 512K -c 2
7318
7319         # Ensure parent striping is used if -R is set, and no stripe
7320         # count or size is specified
7321         echo -n "Setting stripe for parent directory..."
7322         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7323                 error "cannot set stripe '-S 2M -c 1'"
7324         echo "done."
7325
7326         echo -n "Verifying restripe option uses parent stripe settings..."
7327         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7328         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7329         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7330                 error "migrate failed"
7331         cur_ssize=$($LFS getstripe -S "$file1")
7332         [ $cur_ssize -eq $parent_ssize ] ||
7333                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7334         cur_scount=$($LFS getstripe -c "$file1")
7335         [ $cur_scount -eq $parent_scount ] ||
7336                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7337         echo "done."
7338
7339         # File currently set to -S 1M -c 1
7340
7341         # Ensure striping is preserved if -R is not set, and no stripe
7342         # count or size is specified
7343         echo -n "Verifying striping size preserved when not specified..."
7344         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7345         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7346                 error "cannot set stripe on parent directory"
7347         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7348                 error "migrate failed"
7349         cur_ssize=$($LFS getstripe -S "$file1")
7350         [ $cur_ssize -eq $orig_ssize ] ||
7351                 error "migrate by default $cur_ssize != $orig_ssize"
7352         echo "done."
7353
7354         # Ensure file name properly detected when final option has no argument
7355         echo -n "Verifying file name properly detected..."
7356         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7357                 error "file name interpreted as option argument"
7358         echo "done."
7359
7360         # Clean up
7361         rm -f "$file1"
7362 }
7363 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7364
7365 test_56wd() {
7366         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7367
7368         local file1=$DIR/$tdir/file1
7369
7370         echo -n "Creating test dir..."
7371         test_mkdir $DIR/$tdir || error "cannot create dir"
7372         echo "done."
7373
7374         echo -n "Creating test file..."
7375         touch $file1
7376         echo "done."
7377
7378         # Ensure 'lfs migrate' will fail by using a non-existent option,
7379         # and make sure rsync is not called to recover
7380         echo -n "Make sure --no-rsync option works..."
7381         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7382                 grep -q 'refusing to fall back to rsync' ||
7383                 error "rsync was called with --no-rsync set"
7384         echo "done."
7385
7386         # Ensure rsync is called without trying 'lfs migrate' first
7387         echo -n "Make sure --rsync option works..."
7388         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7389                 grep -q 'falling back to rsync' &&
7390                 error "lfs migrate was called with --rsync set"
7391         echo "done."
7392
7393         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7394         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7395                 grep -q 'at the same time' ||
7396                 error "--rsync and --no-rsync accepted concurrently"
7397         echo "done."
7398
7399         # Clean up
7400         rm -f $file1
7401 }
7402 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7403
7404 test_56we() {
7405         local td=$DIR/$tdir
7406         local tf=$td/$tfile
7407
7408         test_mkdir $td || error "cannot create $td"
7409         touch $tf || error "cannot touch $tf"
7410
7411         echo -n "Make sure --non-direct|-D works..."
7412         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7413                 grep -q "lfs migrate --non-direct" ||
7414                 error "--non-direct option cannot work correctly"
7415         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7416                 grep -q "lfs migrate -D" ||
7417                 error "-D option cannot work correctly"
7418         echo "done."
7419 }
7420 run_test 56we "check lfs_migrate --non-direct|-D support"
7421
7422 test_56x() {
7423         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7424         check_swap_layouts_support
7425
7426         local dir=$DIR/$tdir
7427         local ref1=/etc/passwd
7428         local file1=$dir/file1
7429
7430         test_mkdir $dir || error "creating dir $dir"
7431         $LFS setstripe -c 2 $file1
7432         cp $ref1 $file1
7433         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7434         stripe=$($LFS getstripe -c $file1)
7435         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7436         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7437
7438         # clean up
7439         rm -f $file1
7440 }
7441 run_test 56x "lfs migration support"
7442
7443 test_56xa() {
7444         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7445         check_swap_layouts_support
7446
7447         local dir=$DIR/$tdir/$testnum
7448
7449         test_mkdir -p $dir
7450
7451         local ref1=/etc/passwd
7452         local file1=$dir/file1
7453
7454         $LFS setstripe -c 2 $file1
7455         cp $ref1 $file1
7456         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7457
7458         local stripe=$($LFS getstripe -c $file1)
7459
7460         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7461         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7462
7463         # clean up
7464         rm -f $file1
7465 }
7466 run_test 56xa "lfs migration --block support"
7467
7468 check_migrate_links() {
7469         local dir="$1"
7470         local file1="$dir/file1"
7471         local begin="$2"
7472         local count="$3"
7473         local runas="$4"
7474         local total_count=$(($begin + $count - 1))
7475         local symlink_count=10
7476         local uniq_count=10
7477
7478         if [ ! -f "$file1" ]; then
7479                 echo -n "creating initial file..."
7480                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7481                         error "cannot setstripe initial file"
7482                 echo "done"
7483
7484                 echo -n "creating symlinks..."
7485                 for s in $(seq 1 $symlink_count); do
7486                         ln -s "$file1" "$dir/slink$s" ||
7487                                 error "cannot create symlinks"
7488                 done
7489                 echo "done"
7490
7491                 echo -n "creating nonlinked files..."
7492                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7493                         error "cannot create nonlinked files"
7494                 echo "done"
7495         fi
7496
7497         # create hard links
7498         if [ ! -f "$dir/file$total_count" ]; then
7499                 echo -n "creating hard links $begin:$total_count..."
7500                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7501                         /dev/null || error "cannot create hard links"
7502                 echo "done"
7503         fi
7504
7505         echo -n "checking number of hard links listed in xattrs..."
7506         local fid=$($LFS getstripe -F "$file1")
7507         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7508
7509         echo "${#paths[*]}"
7510         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7511                         skip "hard link list has unexpected size, skipping test"
7512         fi
7513         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7514                         error "link names should exceed xattrs size"
7515         fi
7516
7517         echo -n "migrating files..."
7518         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7519         local rc=$?
7520         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7521         echo "done"
7522
7523         # make sure all links have been properly migrated
7524         echo -n "verifying files..."
7525         fid=$($LFS getstripe -F "$file1") ||
7526                 error "cannot get fid for file $file1"
7527         for i in $(seq 2 $total_count); do
7528                 local fid2=$($LFS getstripe -F $dir/file$i)
7529
7530                 [ "$fid2" == "$fid" ] ||
7531                         error "migrated hard link has mismatched FID"
7532         done
7533
7534         # make sure hard links were properly detected, and migration was
7535         # performed only once for the entire link set; nonlinked files should
7536         # also be migrated
7537         local actual=$(grep -c 'done' <<< "$migrate_out")
7538         local expected=$(($uniq_count + 1))
7539
7540         [ "$actual" -eq  "$expected" ] ||
7541                 error "hard links individually migrated ($actual != $expected)"
7542
7543         # make sure the correct number of hard links are present
7544         local hardlinks=$(stat -c '%h' "$file1")
7545
7546         [ $hardlinks -eq $total_count ] ||
7547                 error "num hard links $hardlinks != $total_count"
7548         echo "done"
7549
7550         return 0
7551 }
7552
7553 test_56xb() {
7554         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7555                 skip "Need MDS version at least 2.10.55"
7556
7557         local dir="$DIR/$tdir"
7558
7559         test_mkdir "$dir" || error "cannot create dir $dir"
7560
7561         echo "testing lfs migrate mode when all links fit within xattrs"
7562         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7563
7564         echo "testing rsync mode when all links fit within xattrs"
7565         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7566
7567         echo "testing lfs migrate mode when all links do not fit within xattrs"
7568         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7569
7570         echo "testing rsync mode when all links do not fit within xattrs"
7571         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7572
7573         chown -R $RUNAS_ID $dir
7574         echo "testing non-root lfs migrate mode when not all links are in xattr"
7575         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7576
7577         # clean up
7578         rm -rf $dir
7579 }
7580 run_test 56xb "lfs migration hard link support"
7581
7582 test_56xc() {
7583         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7584
7585         local dir="$DIR/$tdir"
7586
7587         test_mkdir "$dir" || error "cannot create dir $dir"
7588
7589         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7590         echo -n "Setting initial stripe for 20MB test file..."
7591         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7592                 error "cannot setstripe 20MB file"
7593         echo "done"
7594         echo -n "Sizing 20MB test file..."
7595         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7596         echo "done"
7597         echo -n "Verifying small file autostripe count is 1..."
7598         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7599                 error "cannot migrate 20MB file"
7600         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7601                 error "cannot get stripe for $dir/20mb"
7602         [ $stripe_count -eq 1 ] ||
7603                 error "unexpected stripe count $stripe_count for 20MB file"
7604         rm -f "$dir/20mb"
7605         echo "done"
7606
7607         # Test 2: File is small enough to fit within the available space on
7608         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7609         # have at least an additional 1KB for each desired stripe for test 3
7610         echo -n "Setting stripe for 1GB test file..."
7611         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7612         echo "done"
7613         echo -n "Sizing 1GB test file..."
7614         # File size is 1GB + 3KB
7615         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7616         echo "done"
7617
7618         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7619         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7620         if (( avail > 524288 * OSTCOUNT )); then
7621                 echo -n "Migrating 1GB file..."
7622                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7623                         error "cannot migrate 1GB file"
7624                 echo "done"
7625                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7626                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7627                         error "cannot getstripe for 1GB file"
7628                 [ $stripe_count -eq 2 ] ||
7629                         error "unexpected stripe count $stripe_count != 2"
7630                 echo "done"
7631         fi
7632
7633         # Test 3: File is too large to fit within the available space on
7634         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7635         if [ $OSTCOUNT -ge 3 ]; then
7636                 # The required available space is calculated as
7637                 # file size (1GB + 3KB) / OST count (3).
7638                 local kb_per_ost=349526
7639
7640                 echo -n "Migrating 1GB file with limit..."
7641                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7642                         error "cannot migrate 1GB file with limit"
7643                 echo "done"
7644
7645                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7646                 echo -n "Verifying 1GB autostripe count with limited space..."
7647                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7648                         error "unexpected stripe count $stripe_count (min 3)"
7649                 echo "done"
7650         fi
7651
7652         # clean up
7653         rm -rf $dir
7654 }
7655 run_test 56xc "lfs migration autostripe"
7656
7657 test_56xd() {
7658         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7659
7660         local dir=$DIR/$tdir
7661         local f_mgrt=$dir/$tfile.mgrt
7662         local f_yaml=$dir/$tfile.yaml
7663         local f_copy=$dir/$tfile.copy
7664         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7665         local layout_copy="-c 2 -S 2M -i 1"
7666         local yamlfile=$dir/yamlfile
7667         local layout_before;
7668         local layout_after;
7669
7670         test_mkdir "$dir" || error "cannot create dir $dir"
7671         $LFS setstripe $layout_yaml $f_yaml ||
7672                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7673         $LFS getstripe --yaml $f_yaml > $yamlfile
7674         $LFS setstripe $layout_copy $f_copy ||
7675                 error "cannot setstripe $f_copy with layout $layout_copy"
7676         touch $f_mgrt
7677         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7678
7679         # 1. test option --yaml
7680         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7681                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7682         layout_before=$(get_layout_param $f_yaml)
7683         layout_after=$(get_layout_param $f_mgrt)
7684         [ "$layout_after" == "$layout_before" ] ||
7685                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7686
7687         # 2. test option --copy
7688         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7689                 error "cannot migrate $f_mgrt with --copy $f_copy"
7690         layout_before=$(get_layout_param $f_copy)
7691         layout_after=$(get_layout_param $f_mgrt)
7692         [ "$layout_after" == "$layout_before" ] ||
7693                 error "lfs_migrate --copy: $layout_after != $layout_before"
7694 }
7695 run_test 56xd "check lfs_migrate --yaml and --copy support"
7696
7697 test_56xe() {
7698         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7699
7700         local dir=$DIR/$tdir
7701         local f_comp=$dir/$tfile
7702         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7703         local layout_before=""
7704         local layout_after=""
7705
7706         test_mkdir "$dir" || error "cannot create dir $dir"
7707         $LFS setstripe $layout $f_comp ||
7708                 error "cannot setstripe $f_comp with layout $layout"
7709         layout_before=$(get_layout_param $f_comp)
7710         dd if=/dev/zero of=$f_comp bs=1M count=4
7711
7712         # 1. migrate a comp layout file by lfs_migrate
7713         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7714         layout_after=$(get_layout_param $f_comp)
7715         [ "$layout_before" == "$layout_after" ] ||
7716                 error "lfs_migrate: $layout_before != $layout_after"
7717
7718         # 2. migrate a comp layout file by lfs migrate
7719         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7720         layout_after=$(get_layout_param $f_comp)
7721         [ "$layout_before" == "$layout_after" ] ||
7722                 error "lfs migrate: $layout_before != $layout_after"
7723 }
7724 run_test 56xe "migrate a composite layout file"
7725
7726 test_56xf() {
7727         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7728
7729         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7730                 skip "Need server version at least 2.13.53"
7731
7732         local dir=$DIR/$tdir
7733         local f_comp=$dir/$tfile
7734         local layout="-E 1M -c1 -E -1 -c2"
7735         local fid_before=""
7736         local fid_after=""
7737
7738         test_mkdir "$dir" || error "cannot create dir $dir"
7739         $LFS setstripe $layout $f_comp ||
7740                 error "cannot setstripe $f_comp with layout $layout"
7741         fid_before=$($LFS getstripe --fid $f_comp)
7742         dd if=/dev/zero of=$f_comp bs=1M count=4
7743
7744         # 1. migrate a comp layout file to a comp layout
7745         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7746         fid_after=$($LFS getstripe --fid $f_comp)
7747         [ "$fid_before" == "$fid_after" ] ||
7748                 error "comp-to-comp migrate: $fid_before != $fid_after"
7749
7750         # 2. migrate a comp layout file to a plain layout
7751         $LFS migrate -c2 $f_comp ||
7752                 error "cannot migrate $f_comp by lfs migrate"
7753         fid_after=$($LFS getstripe --fid $f_comp)
7754         [ "$fid_before" == "$fid_after" ] ||
7755                 error "comp-to-plain migrate: $fid_before != $fid_after"
7756
7757         # 3. migrate a plain layout file to a comp layout
7758         $LFS migrate $layout $f_comp ||
7759                 error "cannot migrate $f_comp by lfs migrate"
7760         fid_after=$($LFS getstripe --fid $f_comp)
7761         [ "$fid_before" == "$fid_after" ] ||
7762                 error "plain-to-comp migrate: $fid_before != $fid_after"
7763 }
7764 run_test 56xf "FID is not lost during migration of a composite layout file"
7765
7766 check_file_ost_range() {
7767         local file="$1"
7768         shift
7769         local range="$*"
7770         local -a file_range
7771         local idx
7772
7773         file_range=($($LFS getstripe -y "$file" |
7774                 awk '/l_ost_idx:/ { print $NF }'))
7775
7776         if [[ "${#file_range[@]}" = 0 ]]; then
7777                 echo "No osts found for $file"
7778                 return 1
7779         fi
7780
7781         for idx in "${file_range[@]}"; do
7782                 [[ " $range " =~ " $idx " ]] ||
7783                         return 1
7784         done
7785
7786         return 0
7787 }
7788
7789 sub_test_56xg() {
7790         local stripe_opt="$1"
7791         local pool="$2"
7792         shift 2
7793         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7794
7795         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7796                 error "Fail to migrate $tfile on $pool"
7797         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7798                 error "$tfile is not in pool $pool"
7799         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7800                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7801 }
7802
7803 test_56xg() {
7804         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7805         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7806         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7807                 skip "Need MDS version newer than 2.14.52"
7808
7809         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7810         local -a pool_ranges=("0 0" "1 1" "0 1")
7811
7812         # init pools
7813         for i in "${!pool_names[@]}"; do
7814                 pool_add ${pool_names[$i]} ||
7815                         error "pool_add failed (pool: ${pool_names[$i]})"
7816                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7817                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7818         done
7819
7820         # init the file to migrate
7821         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7822                 error "Unable to create $tfile on OST1"
7823         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7824                 error "Unable to write on $tfile"
7825
7826         echo "1. migrate $tfile on pool ${pool_names[0]}"
7827         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7828
7829         echo "2. migrate $tfile on pool ${pool_names[2]}"
7830         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7831
7832         echo "3. migrate $tfile on pool ${pool_names[1]}"
7833         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7834
7835         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7836         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7837         echo
7838
7839         # Clean pools
7840         destroy_test_pools ||
7841                 error "pool_destroy failed"
7842 }
7843 run_test 56xg "lfs migrate pool support"
7844
7845 test_56y() {
7846         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7847                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7848
7849         local res=""
7850         local dir=$DIR/$tdir
7851         local f1=$dir/file1
7852         local f2=$dir/file2
7853
7854         test_mkdir -p $dir || error "creating dir $dir"
7855         touch $f1 || error "creating std file $f1"
7856         $MULTIOP $f2 H2c || error "creating released file $f2"
7857
7858         # a directory can be raid0, so ask only for files
7859         res=$($LFS find $dir -L raid0 -type f | wc -l)
7860         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7861
7862         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7863         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7864
7865         # only files can be released, so no need to force file search
7866         res=$($LFS find $dir -L released)
7867         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7868
7869         res=$($LFS find $dir -type f \! -L released)
7870         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7871 }
7872 run_test 56y "lfs find -L raid0|released"
7873
7874 test_56z() { # LU-4824
7875         # This checks to make sure 'lfs find' continues after errors
7876         # There are two classes of errors that should be caught:
7877         # - If multiple paths are provided, all should be searched even if one
7878         #   errors out
7879         # - If errors are encountered during the search, it should not terminate
7880         #   early
7881         local dir=$DIR/$tdir
7882         local i
7883
7884         test_mkdir $dir
7885         for i in d{0..9}; do
7886                 test_mkdir $dir/$i
7887                 touch $dir/$i/$tfile
7888         done
7889         $LFS find $DIR/non_existent_dir $dir &&
7890                 error "$LFS find did not return an error"
7891         # Make a directory unsearchable. This should NOT be the last entry in
7892         # directory order.  Arbitrarily pick the 6th entry
7893         chmod 700 $($LFS find $dir -type d | sed '6!d')
7894
7895         $RUNAS $LFS find $DIR/non_existent $dir
7896         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7897
7898         # The user should be able to see 10 directories and 9 files
7899         (( count == 19 )) ||
7900                 error "$LFS find found $count != 19 entries after error"
7901 }
7902 run_test 56z "lfs find should continue after an error"
7903
7904 test_56aa() { # LU-5937
7905         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7906
7907         local dir=$DIR/$tdir
7908
7909         mkdir $dir
7910         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7911
7912         createmany -o $dir/striped_dir/${tfile}- 1024
7913         local dirs=$($LFS find --size +8k $dir/)
7914
7915         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7916 }
7917 run_test 56aa "lfs find --size under striped dir"
7918
7919 test_56ab() { # LU-10705
7920         test_mkdir $DIR/$tdir
7921         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7922         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7923         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7924         # Flush writes to ensure valid blocks.  Need to be more thorough for
7925         # ZFS, since blocks are not allocated/returned to client immediately.
7926         sync_all_data
7927         wait_zfs_commit ost1 2
7928         cancel_lru_locks osc
7929         ls -ls $DIR/$tdir
7930
7931         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7932
7933         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7934
7935         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7936         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7937
7938         rm -f $DIR/$tdir/$tfile.[123]
7939 }
7940 run_test 56ab "lfs find --blocks"
7941
7942 # LU-11188
7943 test_56aca() {
7944         local dir="$DIR/$tdir"
7945         local perms=(001 002 003 004 005 006 007
7946                      010 020 030 040 050 060 070
7947                      100 200 300 400 500 600 700
7948                      111 222 333 444 555 666 777)
7949         local perm_minus=(8 8 4 8 4 4 2
7950                           8 8 4 8 4 4 2
7951                           8 8 4 8 4 4 2
7952                           4 4 2 4 2 2 1)
7953         local perm_slash=(8  8 12  8 12 12 14
7954                           8  8 12  8 12 12 14
7955                           8  8 12  8 12 12 14
7956                          16 16 24 16 24 24 28)
7957
7958         test_mkdir "$dir"
7959         for perm in ${perms[*]}; do
7960                 touch "$dir/$tfile.$perm"
7961                 chmod $perm "$dir/$tfile.$perm"
7962         done
7963
7964         for ((i = 0; i < ${#perms[*]}; i++)); do
7965                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7966                 (( $num == 1 )) ||
7967                         error "lfs find -perm ${perms[i]}:"\
7968                               "$num != 1"
7969
7970                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7971                 (( $num == ${perm_minus[i]} )) ||
7972                         error "lfs find -perm -${perms[i]}:"\
7973                               "$num != ${perm_minus[i]}"
7974
7975                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7976                 (( $num == ${perm_slash[i]} )) ||
7977                         error "lfs find -perm /${perms[i]}:"\
7978                               "$num != ${perm_slash[i]}"
7979         done
7980 }
7981 run_test 56aca "check lfs find -perm with octal representation"
7982
7983 test_56acb() {
7984         local dir=$DIR/$tdir
7985         # p is the permission of write and execute for user, group and other
7986         # without the umask. It is used to test +wx.
7987         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7988         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7989         local symbolic=(+t  a+t u+t g+t o+t
7990                         g+s u+s o+s +s o+sr
7991                         o=r,ug+o,u+w
7992                         u+ g+ o+ a+ ugo+
7993                         u- g- o- a- ugo-
7994                         u= g= o= a= ugo=
7995                         o=r,ug+o,u+w u=r,a+u,u+w
7996                         g=r,ugo=g,u+w u+x,+X +X
7997                         u+x,u+X u+X u+x,g+X o+r,+X
7998                         u+x,go+X +wx +rwx)
7999
8000         test_mkdir $dir
8001         for perm in ${perms[*]}; do
8002                 touch "$dir/$tfile.$perm"
8003                 chmod $perm "$dir/$tfile.$perm"
8004         done
8005
8006         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8007                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8008
8009                 (( $num == 1 )) ||
8010                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8011         done
8012 }
8013 run_test 56acb "check lfs find -perm with symbolic representation"
8014
8015 test_56acc() {
8016         local dir=$DIR/$tdir
8017         local tests="17777 787 789 abcd
8018                 ug=uu ug=a ug=gu uo=ou urw
8019                 u+xg+x a=r,u+x,"
8020
8021         test_mkdir $dir
8022         for err in $tests; do
8023                 if $LFS find $dir -perm $err 2>/dev/null; then
8024                         error "lfs find -perm $err: parsing should have failed"
8025                 fi
8026         done
8027 }
8028 run_test 56acc "check parsing error for lfs find -perm"
8029
8030 test_56ba() {
8031         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8032                 skip "Need MDS version at least 2.10.50"
8033
8034         # Create composite files with one component
8035         local dir=$DIR/$tdir
8036
8037         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8038         # Create composite files with three components
8039         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8040         # Create non-composite files
8041         createmany -o $dir/${tfile}- 10
8042
8043         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8044
8045         [[ $nfiles == 10 ]] ||
8046                 error "lfs find -E 1M found $nfiles != 10 files"
8047
8048         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8049         [[ $nfiles == 25 ]] ||
8050                 error "lfs find ! -E 1M found $nfiles != 25 files"
8051
8052         # All files have a component that starts at 0
8053         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8054         [[ $nfiles == 35 ]] ||
8055                 error "lfs find --component-start 0 - $nfiles != 35 files"
8056
8057         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8058         [[ $nfiles == 15 ]] ||
8059                 error "lfs find --component-start 2M - $nfiles != 15 files"
8060
8061         # All files created here have a componenet that does not starts at 2M
8062         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8063         [[ $nfiles == 35 ]] ||
8064                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8065
8066         # Find files with a specified number of components
8067         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8068         [[ $nfiles == 15 ]] ||
8069                 error "lfs find --component-count 3 - $nfiles != 15 files"
8070
8071         # Remember non-composite files have a component count of zero
8072         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8073         [[ $nfiles == 10 ]] ||
8074                 error "lfs find --component-count 0 - $nfiles != 10 files"
8075
8076         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8077         [[ $nfiles == 20 ]] ||
8078                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8079
8080         # All files have a flag called "init"
8081         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8082         [[ $nfiles == 35 ]] ||
8083                 error "lfs find --component-flags init - $nfiles != 35 files"
8084
8085         # Multi-component files will have a component not initialized
8086         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8087         [[ $nfiles == 15 ]] ||
8088                 error "lfs find !--component-flags init - $nfiles != 15 files"
8089
8090         rm -rf $dir
8091
8092 }
8093 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8094
8095 test_56ca() {
8096         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8097                 skip "Need MDS version at least 2.10.57"
8098
8099         local td=$DIR/$tdir
8100         local tf=$td/$tfile
8101         local dir
8102         local nfiles
8103         local cmd
8104         local i
8105         local j
8106
8107         # create mirrored directories and mirrored files
8108         mkdir $td || error "mkdir $td failed"
8109         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8110         createmany -o $tf- 10 || error "create $tf- failed"
8111
8112         for i in $(seq 2); do
8113                 dir=$td/dir$i
8114                 mkdir $dir || error "mkdir $dir failed"
8115                 $LFS mirror create -N$((3 + i)) $dir ||
8116                         error "create mirrored dir $dir failed"
8117                 createmany -o $dir/$tfile- 10 ||
8118                         error "create $dir/$tfile- failed"
8119         done
8120
8121         # change the states of some mirrored files
8122         echo foo > $tf-6
8123         for i in $(seq 2); do
8124                 dir=$td/dir$i
8125                 for j in $(seq 4 9); do
8126                         echo foo > $dir/$tfile-$j
8127                 done
8128         done
8129
8130         # find mirrored files with specific mirror count
8131         cmd="$LFS find --mirror-count 3 --type f $td"
8132         nfiles=$($cmd | wc -l)
8133         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8134
8135         cmd="$LFS find ! --mirror-count 3 --type f $td"
8136         nfiles=$($cmd | wc -l)
8137         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8138
8139         cmd="$LFS find --mirror-count +2 --type f $td"
8140         nfiles=$($cmd | wc -l)
8141         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8142
8143         cmd="$LFS find --mirror-count -6 --type f $td"
8144         nfiles=$($cmd | wc -l)
8145         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8146
8147         # find mirrored files with specific file state
8148         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8149         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8150
8151         cmd="$LFS find --mirror-state=ro --type f $td"
8152         nfiles=$($cmd | wc -l)
8153         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8154
8155         cmd="$LFS find ! --mirror-state=ro --type f $td"
8156         nfiles=$($cmd | wc -l)
8157         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8158
8159         cmd="$LFS find --mirror-state=wp --type f $td"
8160         nfiles=$($cmd | wc -l)
8161         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8162
8163         cmd="$LFS find ! --mirror-state=sp --type f $td"
8164         nfiles=$($cmd | wc -l)
8165         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8166 }
8167 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8168
8169 test_56da() { # LU-14179
8170         local path=$DIR/$tdir
8171
8172         test_mkdir $path
8173         cd $path
8174
8175         local longdir=$(str_repeat 'a' 255)
8176
8177         for i in {1..15}; do
8178                 path=$path/$longdir
8179                 test_mkdir $longdir
8180                 cd $longdir
8181         done
8182
8183         local len=${#path}
8184         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8185
8186         test_mkdir $lastdir
8187         cd $lastdir
8188         # PATH_MAX-1
8189         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8190
8191         # NAME_MAX
8192         touch $(str_repeat 'f' 255)
8193
8194         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8195                 error "lfs find reported an error"
8196
8197         rm -rf $DIR/$tdir
8198 }
8199 run_test 56da "test lfs find with long paths"
8200
8201 test_56ea() { #LU-10378
8202         local path=$DIR/$tdir
8203         local pool=$TESTNAME
8204
8205         # Create ost pool
8206         pool_add $pool || error "pool_add $pool failed"
8207         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8208                 error "adding targets to $pool failed"
8209
8210         # Set default pool on directory before creating file
8211         mkdir $path || error "mkdir $path failed"
8212         $LFS setstripe -p $pool $path ||
8213                 error "set OST pool on $pool failed"
8214         touch $path/$tfile || error "touch $path/$tfile failed"
8215
8216         # Compare basic file attributes from -printf and stat
8217         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8218         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8219
8220         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8221                 error "Attrs from lfs find and stat don't match"
8222
8223         # Compare Lustre attributes from lfs find and lfs getstripe
8224         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8225         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8226         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8227         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8228         local fpool=$($LFS getstripe --pool $path/$tfile)
8229         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8230
8231         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8232                 error "Attrs from lfs find and lfs getstripe don't match"
8233
8234         # Verify behavior for unknown escape/format sequences
8235         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8236
8237         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8238                 error "Escape/format codes don't match"
8239 }
8240 run_test 56ea "test lfs find -printf option"
8241
8242 test_57a() {
8243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8244         # note test will not do anything if MDS is not local
8245         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8246                 skip_env "ldiskfs only test"
8247         fi
8248         remote_mds_nodsh && skip "remote MDS with nodsh"
8249
8250         local MNTDEV="osd*.*MDT*.mntdev"
8251         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8252         [ -z "$DEV" ] && error "can't access $MNTDEV"
8253         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8254                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8255                         error "can't access $DEV"
8256                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8257                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8258                 rm $TMP/t57a.dump
8259         done
8260 }
8261 run_test 57a "verify MDS filesystem created with large inodes =="
8262
8263 test_57b() {
8264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8265         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8266                 skip_env "ldiskfs only test"
8267         fi
8268         remote_mds_nodsh && skip "remote MDS with nodsh"
8269
8270         local dir=$DIR/$tdir
8271         local filecount=100
8272         local file1=$dir/f1
8273         local fileN=$dir/f$filecount
8274
8275         rm -rf $dir || error "removing $dir"
8276         test_mkdir -c1 $dir
8277         local mdtidx=$($LFS getstripe -m $dir)
8278         local mdtname=MDT$(printf %04x $mdtidx)
8279         local facet=mds$((mdtidx + 1))
8280
8281         echo "mcreating $filecount files"
8282         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8283
8284         # verify that files do not have EAs yet
8285         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8286                 error "$file1 has an EA"
8287         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8288                 error "$fileN has an EA"
8289
8290         sync
8291         sleep 1
8292         df $dir  #make sure we get new statfs data
8293         local mdsfree=$(do_facet $facet \
8294                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8295         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8296         local file
8297
8298         echo "opening files to create objects/EAs"
8299         for file in $(seq -f $dir/f%g 1 $filecount); do
8300                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8301                         error "opening $file"
8302         done
8303
8304         # verify that files have EAs now
8305         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8306         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8307
8308         sleep 1  #make sure we get new statfs data
8309         df $dir
8310         local mdsfree2=$(do_facet $facet \
8311                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8312         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8313
8314         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8315                 if [ "$mdsfree" != "$mdsfree2" ]; then
8316                         error "MDC before $mdcfree != after $mdcfree2"
8317                 else
8318                         echo "MDC before $mdcfree != after $mdcfree2"
8319                         echo "unable to confirm if MDS has large inodes"
8320                 fi
8321         fi
8322         rm -rf $dir
8323 }
8324 run_test 57b "default LOV EAs are stored inside large inodes ==="
8325
8326 test_58() {
8327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8328         [ -z "$(which wiretest 2>/dev/null)" ] &&
8329                         skip_env "could not find wiretest"
8330
8331         wiretest
8332 }
8333 run_test 58 "verify cross-platform wire constants =============="
8334
8335 test_59() {
8336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8337
8338         echo "touch 130 files"
8339         createmany -o $DIR/f59- 130
8340         echo "rm 130 files"
8341         unlinkmany $DIR/f59- 130
8342         sync
8343         # wait for commitment of removal
8344         wait_delete_completed
8345 }
8346 run_test 59 "verify cancellation of llog records async ========="
8347
8348 TEST60_HEAD="test_60 run $RANDOM"
8349 test_60a() {
8350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8351         remote_mgs_nodsh && skip "remote MGS with nodsh"
8352         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8353                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8354                         skip_env "missing subtest run-llog.sh"
8355
8356         log "$TEST60_HEAD - from kernel mode"
8357         do_facet mgs "$LCTL dk > /dev/null"
8358         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8359         do_facet mgs $LCTL dk > $TMP/$tfile
8360
8361         # LU-6388: test llog_reader
8362         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8363         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8364         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8365                         skip_env "missing llog_reader"
8366         local fstype=$(facet_fstype mgs)
8367         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8368                 skip_env "Only for ldiskfs or zfs type mgs"
8369
8370         local mntpt=$(facet_mntpt mgs)
8371         local mgsdev=$(mgsdevname 1)
8372         local fid_list
8373         local fid
8374         local rec_list
8375         local rec
8376         local rec_type
8377         local obj_file
8378         local path
8379         local seq
8380         local oid
8381         local pass=true
8382
8383         #get fid and record list
8384         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8385                 tail -n 4))
8386         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8387                 tail -n 4))
8388         #remount mgs as ldiskfs or zfs type
8389         stop mgs || error "stop mgs failed"
8390         mount_fstype mgs || error "remount mgs failed"
8391         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8392                 fid=${fid_list[i]}
8393                 rec=${rec_list[i]}
8394                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8395                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8396                 oid=$((16#$oid))
8397
8398                 case $fstype in
8399                         ldiskfs )
8400                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8401                         zfs )
8402                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8403                 esac
8404                 echo "obj_file is $obj_file"
8405                 do_facet mgs $llog_reader $obj_file
8406
8407                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8408                         awk '{ print $3 }' | sed -e "s/^type=//g")
8409                 if [ $rec_type != $rec ]; then
8410                         echo "FAILED test_60a wrong record type $rec_type," \
8411                               "should be $rec"
8412                         pass=false
8413                         break
8414                 fi
8415
8416                 #check obj path if record type is LLOG_LOGID_MAGIC
8417                 if [ "$rec" == "1064553b" ]; then
8418                         path=$(do_facet mgs $llog_reader $obj_file |
8419                                 grep "path=" | awk '{ print $NF }' |
8420                                 sed -e "s/^path=//g")
8421                         if [ $obj_file != $mntpt/$path ]; then
8422                                 echo "FAILED test_60a wrong obj path" \
8423                                       "$montpt/$path, should be $obj_file"
8424                                 pass=false
8425                                 break
8426                         fi
8427                 fi
8428         done
8429         rm -f $TMP/$tfile
8430         #restart mgs before "error", otherwise it will block the next test
8431         stop mgs || error "stop mgs failed"
8432         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8433         $pass || error "test failed, see FAILED test_60a messages for specifics"
8434 }
8435 run_test 60a "llog_test run from kernel module and test llog_reader"
8436
8437 test_60b() { # bug 6411
8438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8439
8440         dmesg > $DIR/$tfile
8441         LLOG_COUNT=$(do_facet mgs dmesg |
8442                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8443                           /llog_[a-z]*.c:[0-9]/ {
8444                                 if (marker)
8445                                         from_marker++
8446                                 from_begin++
8447                           }
8448                           END {
8449                                 if (marker)
8450                                         print from_marker
8451                                 else
8452                                         print from_begin
8453                           }")
8454
8455         [[ $LLOG_COUNT -gt 120 ]] &&
8456                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8457 }
8458 run_test 60b "limit repeated messages from CERROR/CWARN"
8459
8460 test_60c() {
8461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8462
8463         echo "create 5000 files"
8464         createmany -o $DIR/f60c- 5000
8465 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8466         lctl set_param fail_loc=0x80000137
8467         unlinkmany $DIR/f60c- 5000
8468         lctl set_param fail_loc=0
8469 }
8470 run_test 60c "unlink file when mds full"
8471
8472 test_60d() {
8473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8474
8475         SAVEPRINTK=$(lctl get_param -n printk)
8476         # verify "lctl mark" is even working"
8477         MESSAGE="test message ID $RANDOM $$"
8478         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8479         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8480
8481         lctl set_param printk=0 || error "set lnet.printk failed"
8482         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8483         MESSAGE="new test message ID $RANDOM $$"
8484         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8485         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8486         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8487
8488         lctl set_param -n printk="$SAVEPRINTK"
8489 }
8490 run_test 60d "test printk console message masking"
8491
8492 test_60e() {
8493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8494         remote_mds_nodsh && skip "remote MDS with nodsh"
8495
8496         touch $DIR/$tfile
8497 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8498         do_facet mds1 lctl set_param fail_loc=0x15b
8499         rm $DIR/$tfile
8500 }
8501 run_test 60e "no space while new llog is being created"
8502
8503 test_60f() {
8504         local old_path=$($LCTL get_param -n debug_path)
8505
8506         stack_trap "$LCTL set_param debug_path=$old_path"
8507         stack_trap "rm -f $TMP/$tfile*"
8508         rm -f $TMP/$tfile* 2> /dev/null
8509         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8510         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8511         test_mkdir $DIR/$tdir
8512         # retry in case the open is cached and not released
8513         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8514                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8515                 sleep 0.1
8516         done
8517         ls $TMP/$tfile*
8518         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8519 }
8520 run_test 60f "change debug_path works"
8521
8522 test_60g() {
8523         local pid
8524         local i
8525
8526         test_mkdir -c $MDSCOUNT $DIR/$tdir
8527
8528         (
8529                 local index=0
8530                 while true; do
8531                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8532                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8533                                 2>/dev/null
8534                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8535                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8536                         index=$((index + 1))
8537                 done
8538         ) &
8539
8540         pid=$!
8541
8542         for i in {0..100}; do
8543                 # define OBD_FAIL_OSD_TXN_START    0x19a
8544                 local index=$((i % MDSCOUNT + 1))
8545
8546                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8547                         > /dev/null
8548                 sleep 0.01
8549         done
8550
8551         kill -9 $pid
8552
8553         for i in $(seq $MDSCOUNT); do
8554                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8555         done
8556
8557         mkdir $DIR/$tdir/new || error "mkdir failed"
8558         rmdir $DIR/$tdir/new || error "rmdir failed"
8559
8560         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8561                 -t namespace
8562         for i in $(seq $MDSCOUNT); do
8563                 wait_update_facet mds$i "$LCTL get_param -n \
8564                         mdd.$(facet_svc mds$i).lfsck_namespace |
8565                         awk '/^status/ { print \\\$2 }'" "completed"
8566         done
8567
8568         ls -R $DIR/$tdir
8569         rm -rf $DIR/$tdir || error "rmdir failed"
8570 }
8571 run_test 60g "transaction abort won't cause MDT hung"
8572
8573 test_60h() {
8574         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8575                 skip "Need MDS version at least 2.12.52"
8576         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8577
8578         local f
8579
8580         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8581         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8582         for fail_loc in 0x80000188 0x80000189; do
8583                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8584                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8585                         error "mkdir $dir-$fail_loc failed"
8586                 for i in {0..10}; do
8587                         # create may fail on missing stripe
8588                         echo $i > $DIR/$tdir-$fail_loc/$i
8589                 done
8590                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8591                         error "getdirstripe $tdir-$fail_loc failed"
8592                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8593                         error "migrate $tdir-$fail_loc failed"
8594                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8595                         error "getdirstripe $tdir-$fail_loc failed"
8596                 pushd $DIR/$tdir-$fail_loc
8597                 for f in *; do
8598                         echo $f | cmp $f - || error "$f data mismatch"
8599                 done
8600                 popd
8601                 rm -rf $DIR/$tdir-$fail_loc
8602         done
8603 }
8604 run_test 60h "striped directory with missing stripes can be accessed"
8605
8606 function t60i_load() {
8607         mkdir $DIR/$tdir
8608         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8609         $LCTL set_param fail_loc=0x131c fail_val=1
8610         for ((i=0; i<5000; i++)); do
8611                 touch $DIR/$tdir/f$i
8612         done
8613 }
8614
8615 test_60i() {
8616         changelog_register || error "changelog_register failed"
8617         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8618         changelog_users $SINGLEMDS | grep -q $cl_user ||
8619                 error "User $cl_user not found in changelog_users"
8620         changelog_chmask "ALL"
8621         t60i_load &
8622         local PID=$!
8623         for((i=0; i<100; i++)); do
8624                 changelog_dump >/dev/null ||
8625                         error "can't read changelog"
8626         done
8627         kill $PID
8628         wait $PID
8629         changelog_deregister || error "changelog_deregister failed"
8630         $LCTL set_param fail_loc=0
8631 }
8632 run_test 60i "llog: new record vs reader race"
8633
8634 test_61a() {
8635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8636
8637         f="$DIR/f61"
8638         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8639         cancel_lru_locks osc
8640         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8641         sync
8642 }
8643 run_test 61a "mmap() writes don't make sync hang ================"
8644
8645 test_61b() {
8646         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8647 }
8648 run_test 61b "mmap() of unstriped file is successful"
8649
8650 # bug 2330 - insufficient obd_match error checking causes LBUG
8651 test_62() {
8652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8653
8654         f="$DIR/f62"
8655         echo foo > $f
8656         cancel_lru_locks osc
8657         lctl set_param fail_loc=0x405
8658         cat $f && error "cat succeeded, expect -EIO"
8659         lctl set_param fail_loc=0
8660 }
8661 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8662 # match every page all of the time.
8663 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8664
8665 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8666 # Though this test is irrelevant anymore, it helped to reveal some
8667 # other grant bugs (LU-4482), let's keep it.
8668 test_63a() {   # was test_63
8669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8670
8671         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8672
8673         for i in `seq 10` ; do
8674                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8675                 sleep 5
8676                 kill $!
8677                 sleep 1
8678         done
8679
8680         rm -f $DIR/f63 || true
8681 }
8682 run_test 63a "Verify oig_wait interruption does not crash ======="
8683
8684 # bug 2248 - async write errors didn't return to application on sync
8685 # bug 3677 - async write errors left page locked
8686 test_63b() {
8687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8688
8689         debugsave
8690         lctl set_param debug=-1
8691
8692         # ensure we have a grant to do async writes
8693         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8694         rm $DIR/$tfile
8695
8696         sync    # sync lest earlier test intercept the fail_loc
8697
8698         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8699         lctl set_param fail_loc=0x80000406
8700         $MULTIOP $DIR/$tfile Owy && \
8701                 error "sync didn't return ENOMEM"
8702         sync; sleep 2; sync     # do a real sync this time to flush page
8703         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8704                 error "locked page left in cache after async error" || true
8705         debugrestore
8706 }
8707 run_test 63b "async write errors should be returned to fsync ==="
8708
8709 test_64a () {
8710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8711
8712         lfs df $DIR
8713         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8714 }
8715 run_test 64a "verify filter grant calculations (in kernel) ====="
8716
8717 test_64b () {
8718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8719
8720         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8721 }
8722 run_test 64b "check out-of-space detection on client"
8723
8724 test_64c() {
8725         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8726 }
8727 run_test 64c "verify grant shrink"
8728
8729 import_param() {
8730         local tgt=$1
8731         local param=$2
8732
8733         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8734 }
8735
8736 # this does exactly what osc_request.c:osc_announce_cached() does in
8737 # order to calculate max amount of grants to ask from server
8738 want_grant() {
8739         local tgt=$1
8740
8741         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8742         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8743
8744         ((rpc_in_flight++));
8745         nrpages=$((nrpages * rpc_in_flight))
8746
8747         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8748
8749         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8750
8751         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8752         local undirty=$((nrpages * PAGE_SIZE))
8753
8754         local max_extent_pages
8755         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8756         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8757         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8758         local grant_extent_tax
8759         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8760
8761         undirty=$((undirty + nrextents * grant_extent_tax))
8762
8763         echo $undirty
8764 }
8765
8766 # this is size of unit for grant allocation. It should be equal to
8767 # what tgt_grant.c:tgt_grant_chunk() calculates
8768 grant_chunk() {
8769         local tgt=$1
8770         local max_brw_size
8771         local grant_extent_tax
8772
8773         max_brw_size=$(import_param $tgt max_brw_size)
8774
8775         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8776
8777         echo $(((max_brw_size + grant_extent_tax) * 2))
8778 }
8779
8780 test_64d() {
8781         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8782                 skip "OST < 2.10.55 doesn't limit grants enough"
8783
8784         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8785
8786         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8787                 skip "no grant_param connect flag"
8788
8789         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8790
8791         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8792         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8793
8794
8795         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8796         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8797
8798         $LFS setstripe $DIR/$tfile -i 0 -c 1
8799         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8800         ddpid=$!
8801
8802         while kill -0 $ddpid; do
8803                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8804
8805                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8806                         kill $ddpid
8807                         error "cur_grant $cur_grant > $max_cur_granted"
8808                 fi
8809
8810                 sleep 1
8811         done
8812 }
8813 run_test 64d "check grant limit exceed"
8814
8815 check_grants() {
8816         local tgt=$1
8817         local expected=$2
8818         local msg=$3
8819         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8820
8821         ((cur_grants == expected)) ||
8822                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8823 }
8824
8825 round_up_p2() {
8826         echo $((($1 + $2 - 1) & ~($2 - 1)))
8827 }
8828
8829 test_64e() {
8830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8831         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8832                 skip "Need OSS version at least 2.11.56"
8833
8834         # Remount client to reset grant
8835         remount_client $MOUNT || error "failed to remount client"
8836         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8837
8838         local init_grants=$(import_param $osc_tgt initial_grant)
8839
8840         check_grants $osc_tgt $init_grants "init grants"
8841
8842         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8843         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8844         local gbs=$(import_param $osc_tgt grant_block_size)
8845
8846         # write random number of bytes from max_brw_size / 4 to max_brw_size
8847         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8848         # align for direct io
8849         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8850         # round to grant consumption unit
8851         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8852
8853         local grants=$((wb_round_up + extent_tax))
8854
8855         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8856
8857         # define OBD_FAIL_TGT_NO_GRANT 0x725
8858         # make the server not grant more back
8859         do_facet ost1 $LCTL set_param fail_loc=0x725
8860         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8861
8862         do_facet ost1 $LCTL set_param fail_loc=0
8863
8864         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8865
8866         rm -f $DIR/$tfile || error "rm failed"
8867
8868         # Remount client to reset grant
8869         remount_client $MOUNT || error "failed to remount client"
8870         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8871
8872         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8873
8874         # define OBD_FAIL_TGT_NO_GRANT 0x725
8875         # make the server not grant more back
8876         do_facet ost1 $LCTL set_param fail_loc=0x725
8877         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8878         do_facet ost1 $LCTL set_param fail_loc=0
8879
8880         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8881 }
8882 run_test 64e "check grant consumption (no grant allocation)"
8883
8884 test_64f() {
8885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8886
8887         # Remount client to reset grant
8888         remount_client $MOUNT || error "failed to remount client"
8889         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8890
8891         local init_grants=$(import_param $osc_tgt initial_grant)
8892         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8893         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8894         local gbs=$(import_param $osc_tgt grant_block_size)
8895         local chunk=$(grant_chunk $osc_tgt)
8896
8897         # write random number of bytes from max_brw_size / 4 to max_brw_size
8898         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8899         # align for direct io
8900         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8901         # round to grant consumption unit
8902         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8903
8904         local grants=$((wb_round_up + extent_tax))
8905
8906         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8907         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8908                 error "error writing to $DIR/$tfile"
8909
8910         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8911                 "direct io with grant allocation"
8912
8913         rm -f $DIR/$tfile || error "rm failed"
8914
8915         # Remount client to reset grant
8916         remount_client $MOUNT || error "failed to remount client"
8917         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8918
8919         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8920
8921         local cmd="oO_WRONLY:w${write_bytes}_yc"
8922
8923         $MULTIOP $DIR/$tfile $cmd &
8924         MULTIPID=$!
8925         sleep 1
8926
8927         check_grants $osc_tgt $((init_grants - grants)) \
8928                 "buffered io, not write rpc"
8929
8930         kill -USR1 $MULTIPID
8931         wait
8932
8933         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8934                 "buffered io, one RPC"
8935 }
8936 run_test 64f "check grant consumption (with grant allocation)"
8937
8938 test_64g() {
8939         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
8940                 skip "Need MDS version at least 2.14.56"
8941
8942         local mdts=$(comma_list $(mdts_nodes))
8943
8944         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8945                         tr '\n' ' ')
8946         stack_trap "$LCTL set_param $old"
8947
8948         # generate dirty pages and increase dirty granted on MDT
8949         stack_trap "rm -f $DIR/$tfile-*"
8950         for (( i = 0; i < 10; i++)); do
8951                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8952                         error "can't set stripe"
8953                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8954                         error "can't dd"
8955                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8956                         $LFS getstripe $DIR/$tfile-$i
8957                         error "not DoM file"
8958                 }
8959         done
8960
8961         # flush dirty pages
8962         sync
8963
8964         # wait until grant shrink reset grant dirty on MDTs
8965         for ((i = 0; i < 120; i++)); do
8966                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8967                         awk '{sum=sum+$1} END {print sum}')
8968                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8969                 echo "$grant_dirty grants, $vm_dirty pages"
8970                 (( grant_dirty + vm_dirty == 0 )) && break
8971                 (( i == 3 )) && sync &&
8972                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8973                 sleep 1
8974         done
8975
8976         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8977                 awk '{sum=sum+$1} END {print sum}')
8978         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8979 }
8980 run_test 64g "grant shrink on MDT"
8981
8982 test_64h() {
8983         local instance=$($LFS getname -i $DIR)
8984         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8985         local num_exps=$(do_facet ost1 \
8986             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8987         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8988         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8989         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8990
8991         # 10MiB is for file to be written, max_brw_size * 16 *
8992         # num_exps is space reserve so that tgt_grant_shrink() decided
8993         # to not shrink
8994         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8995         (( avail * 1024 < expect )) &&
8996                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8997
8998         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8999         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9000         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9001         $LCTL set_param osc.*OST0000*.grant_shrink=1
9002         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9003
9004         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9005         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9006
9007         # drop cache so that coming read would do rpc
9008         cancel_lru_locks osc
9009
9010         # shrink interval is set to 10, pause for 7 seconds so that
9011         # grant thread did not wake up yet but coming read entered
9012         # shrink mode for rpc (osc_should_shrink_grant())
9013         sleep 7
9014
9015         declare -a cur_grant_bytes
9016         declare -a tot_granted
9017         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9018         tot_granted[0]=$(do_facet ost1 \
9019             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9020
9021         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9022
9023         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9024         tot_granted[1]=$(do_facet ost1 \
9025             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9026
9027         # grant change should be equal on both sides
9028         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9029                 tot_granted[0] - tot_granted[1])) ||
9030                 error "grant change mismatch, "                                \
9031                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9032                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9033 }
9034 run_test 64h "grant shrink on read"
9035
9036 test_64i() {
9037         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
9038                 skip "need OST at least 2.14.55 to avoid grant shrink on replay"
9039
9040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9041         remote_ost_nodsh && skip "remote OSTs with nodsh"
9042
9043         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9044
9045         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9046
9047         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9048         local instance=$($LFS getname -i $DIR)
9049
9050         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9051         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9052
9053         # shrink grants and simulate rpc loss
9054         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9055         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9056         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9057
9058         fail ost1
9059
9060         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9061
9062         local testid=$(echo $TESTNAME | tr '_' ' ')
9063
9064         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9065                 grep "GRANT, real grant" &&
9066                 error "client has more grants then it owns" || true
9067 }
9068 run_test 64i "shrink on reconnect"
9069
9070 # bug 1414 - set/get directories' stripe info
9071 test_65a() {
9072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9073
9074         test_mkdir $DIR/$tdir
9075         touch $DIR/$tdir/f1
9076         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9077 }
9078 run_test 65a "directory with no stripe info"
9079
9080 test_65b() {
9081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9082
9083         test_mkdir $DIR/$tdir
9084         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9085
9086         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9087                                                 error "setstripe"
9088         touch $DIR/$tdir/f2
9089         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9090 }
9091 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9092
9093 test_65c() {
9094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9095         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9096
9097         test_mkdir $DIR/$tdir
9098         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9099
9100         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9101                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9102         touch $DIR/$tdir/f3
9103         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9104 }
9105 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9106
9107 test_65d() {
9108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9109
9110         test_mkdir $DIR/$tdir
9111         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9112         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9113
9114         if [[ $STRIPECOUNT -le 0 ]]; then
9115                 sc=1
9116         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9117                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9118                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9119         else
9120                 sc=$(($STRIPECOUNT - 1))
9121         fi
9122         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9123         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9124         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9125                 error "lverify failed"
9126 }
9127 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9128
9129 test_65e() {
9130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9131
9132         test_mkdir $DIR/$tdir
9133
9134         $LFS setstripe $DIR/$tdir || error "setstripe"
9135         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9136                                         error "no stripe info failed"
9137         touch $DIR/$tdir/f6
9138         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9139 }
9140 run_test 65e "directory setstripe defaults"
9141
9142 test_65f() {
9143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9144
9145         test_mkdir $DIR/${tdir}f
9146         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9147                 error "setstripe succeeded" || true
9148 }
9149 run_test 65f "dir setstripe permission (should return error) ==="
9150
9151 test_65g() {
9152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9153
9154         test_mkdir $DIR/$tdir
9155         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9156
9157         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9158                 error "setstripe -S failed"
9159         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9160         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9161                 error "delete default stripe failed"
9162 }
9163 run_test 65g "directory setstripe -d"
9164
9165 test_65h() {
9166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9167
9168         test_mkdir $DIR/$tdir
9169         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9170
9171         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9172                 error "setstripe -S failed"
9173         test_mkdir $DIR/$tdir/dd1
9174         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9175                 error "stripe info inherit failed"
9176 }
9177 run_test 65h "directory stripe info inherit ===================="
9178
9179 test_65i() {
9180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9181
9182         save_layout_restore_at_exit $MOUNT
9183
9184         # bug6367: set non-default striping on root directory
9185         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9186
9187         # bug12836: getstripe on -1 default directory striping
9188         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9189
9190         # bug12836: getstripe -v on -1 default directory striping
9191         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9192
9193         # bug12836: new find on -1 default directory striping
9194         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9195 }
9196 run_test 65i "various tests to set root directory striping"
9197
9198 test_65j() { # bug6367
9199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9200
9201         sync; sleep 1
9202
9203         # if we aren't already remounting for each test, do so for this test
9204         if [ "$I_MOUNTED" = "yes" ]; then
9205                 cleanup || error "failed to unmount"
9206                 setup
9207         fi
9208
9209         save_layout_restore_at_exit $MOUNT
9210
9211         $LFS setstripe -d $MOUNT || error "setstripe failed"
9212 }
9213 run_test 65j "set default striping on root directory (bug 6367)="
9214
9215 cleanup_65k() {
9216         rm -rf $DIR/$tdir
9217         wait_delete_completed
9218         do_facet $SINGLEMDS "lctl set_param -n \
9219                 osp.$ost*MDT0000.max_create_count=$max_count"
9220         do_facet $SINGLEMDS "lctl set_param -n \
9221                 osp.$ost*MDT0000.create_count=$count"
9222         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9223         echo $INACTIVE_OSC "is Activate"
9224
9225         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9226 }
9227
9228 test_65k() { # bug11679
9229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9230         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9231         remote_mds_nodsh && skip "remote MDS with nodsh"
9232
9233         local disable_precreate=true
9234         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9235                 disable_precreate=false
9236
9237         echo "Check OST status: "
9238         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9239                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9240
9241         for OSC in $MDS_OSCS; do
9242                 echo $OSC "is active"
9243                 do_facet $SINGLEMDS lctl --device %$OSC activate
9244         done
9245
9246         for INACTIVE_OSC in $MDS_OSCS; do
9247                 local ost=$(osc_to_ost $INACTIVE_OSC)
9248                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9249                                lov.*md*.target_obd |
9250                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9251
9252                 mkdir -p $DIR/$tdir
9253                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9254                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9255
9256                 echo "Deactivate: " $INACTIVE_OSC
9257                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9258
9259                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9260                               osp.$ost*MDT0000.create_count")
9261                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9262                                   osp.$ost*MDT0000.max_create_count")
9263                 $disable_precreate &&
9264                         do_facet $SINGLEMDS "lctl set_param -n \
9265                                 osp.$ost*MDT0000.max_create_count=0"
9266
9267                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9268                         [ -f $DIR/$tdir/$idx ] && continue
9269                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9270                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9271                                 { cleanup_65k;
9272                                   error "setstripe $idx should succeed"; }
9273                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9274                 done
9275                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9276                 rmdir $DIR/$tdir
9277
9278                 do_facet $SINGLEMDS "lctl set_param -n \
9279                         osp.$ost*MDT0000.max_create_count=$max_count"
9280                 do_facet $SINGLEMDS "lctl set_param -n \
9281                         osp.$ost*MDT0000.create_count=$count"
9282                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9283                 echo $INACTIVE_OSC "is Activate"
9284
9285                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9286         done
9287 }
9288 run_test 65k "validate manual striping works properly with deactivated OSCs"
9289
9290 test_65l() { # bug 12836
9291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9292
9293         test_mkdir -p $DIR/$tdir/test_dir
9294         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9295         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9296 }
9297 run_test 65l "lfs find on -1 stripe dir ========================"
9298
9299 test_65m() {
9300         local layout=$(save_layout $MOUNT)
9301         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9302                 restore_layout $MOUNT $layout
9303                 error "setstripe should fail by non-root users"
9304         }
9305         true
9306 }
9307 run_test 65m "normal user can't set filesystem default stripe"
9308
9309 test_65n() {
9310         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9311         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9312                 skip "Need MDS version at least 2.12.50"
9313         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9314
9315         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9316         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9317         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9318
9319         save_layout_restore_at_exit $MOUNT
9320
9321         # new subdirectory under root directory should not inherit
9322         # the default layout from root
9323         local dir1=$MOUNT/$tdir-1
9324         mkdir $dir1 || error "mkdir $dir1 failed"
9325         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9326                 error "$dir1 shouldn't have LOV EA"
9327
9328         # delete the default layout on root directory
9329         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9330
9331         local dir2=$MOUNT/$tdir-2
9332         mkdir $dir2 || error "mkdir $dir2 failed"
9333         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9334                 error "$dir2 shouldn't have LOV EA"
9335
9336         # set a new striping pattern on root directory
9337         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9338         local new_def_stripe_size=$((def_stripe_size * 2))
9339         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9340                 error "set stripe size on $MOUNT failed"
9341
9342         # new file created in $dir2 should inherit the new stripe size from
9343         # the filesystem default
9344         local file2=$dir2/$tfile-2
9345         touch $file2 || error "touch $file2 failed"
9346
9347         local file2_stripe_size=$($LFS getstripe -S $file2)
9348         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9349         {
9350                 echo "file2_stripe_size: '$file2_stripe_size'"
9351                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9352                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9353         }
9354
9355         local dir3=$MOUNT/$tdir-3
9356         mkdir $dir3 || error "mkdir $dir3 failed"
9357         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9358         # the root layout, which is the actual default layout that will be used
9359         # when new files are created in $dir3.
9360         local dir3_layout=$(get_layout_param $dir3)
9361         local root_dir_layout=$(get_layout_param $MOUNT)
9362         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9363         {
9364                 echo "dir3_layout: '$dir3_layout'"
9365                 echo "root_dir_layout: '$root_dir_layout'"
9366                 error "$dir3 should show the default layout from $MOUNT"
9367         }
9368
9369         # set OST pool on root directory
9370         local pool=$TESTNAME
9371         pool_add $pool || error "add $pool failed"
9372         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9373                 error "add targets to $pool failed"
9374
9375         $LFS setstripe -p $pool $MOUNT ||
9376                 error "set OST pool on $MOUNT failed"
9377
9378         # new file created in $dir3 should inherit the pool from
9379         # the filesystem default
9380         local file3=$dir3/$tfile-3
9381         touch $file3 || error "touch $file3 failed"
9382
9383         local file3_pool=$($LFS getstripe -p $file3)
9384         [[ "$file3_pool" = "$pool" ]] ||
9385                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9386
9387         local dir4=$MOUNT/$tdir-4
9388         mkdir $dir4 || error "mkdir $dir4 failed"
9389         local dir4_layout=$(get_layout_param $dir4)
9390         root_dir_layout=$(get_layout_param $MOUNT)
9391         echo "$LFS getstripe -d $dir4"
9392         $LFS getstripe -d $dir4
9393         echo "$LFS getstripe -d $MOUNT"
9394         $LFS getstripe -d $MOUNT
9395         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9396         {
9397                 echo "dir4_layout: '$dir4_layout'"
9398                 echo "root_dir_layout: '$root_dir_layout'"
9399                 error "$dir4 should show the default layout from $MOUNT"
9400         }
9401
9402         # new file created in $dir4 should inherit the pool from
9403         # the filesystem default
9404         local file4=$dir4/$tfile-4
9405         touch $file4 || error "touch $file4 failed"
9406
9407         local file4_pool=$($LFS getstripe -p $file4)
9408         [[ "$file4_pool" = "$pool" ]] ||
9409                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9410
9411         # new subdirectory under non-root directory should inherit
9412         # the default layout from its parent directory
9413         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9414                 error "set directory layout on $dir4 failed"
9415
9416         local dir5=$dir4/$tdir-5
9417         mkdir $dir5 || error "mkdir $dir5 failed"
9418
9419         dir4_layout=$(get_layout_param $dir4)
9420         local dir5_layout=$(get_layout_param $dir5)
9421         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9422         {
9423                 echo "dir4_layout: '$dir4_layout'"
9424                 echo "dir5_layout: '$dir5_layout'"
9425                 error "$dir5 should inherit the default layout from $dir4"
9426         }
9427
9428         # though subdir under ROOT doesn't inherit default layout, but
9429         # its sub dir/file should be created with default layout.
9430         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9431         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9432                 skip "Need MDS version at least 2.12.59"
9433
9434         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9435         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9436         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9437
9438         if [ $default_lmv_hash == "none" ]; then
9439                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9440         else
9441                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9442                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9443         fi
9444
9445         $LFS setdirstripe -D -c 2 $MOUNT ||
9446                 error "setdirstripe -D -c 2 failed"
9447         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9448         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9449         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9450
9451         # $dir4 layout includes pool
9452         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9453         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9454                 error "pool lost on setstripe"
9455         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9456         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9457                 error "pool lost on compound layout setstripe"
9458 }
9459 run_test 65n "don't inherit default layout from root for new subdirectories"
9460
9461 # bug 2543 - update blocks count on client
9462 test_66() {
9463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9464
9465         COUNT=${COUNT:-8}
9466         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9467         sync; sync_all_data; sync; sync_all_data
9468         cancel_lru_locks osc
9469         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9470         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9471 }
9472 run_test 66 "update inode blocks count on client ==============="
9473
9474 meminfo() {
9475         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9476 }
9477
9478 swap_used() {
9479         swapon -s | awk '($1 == "'$1'") { print $4 }'
9480 }
9481
9482 # bug5265, obdfilter oa2dentry return -ENOENT
9483 # #define OBD_FAIL_SRV_ENOENT 0x217
9484 test_69() {
9485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9486         remote_ost_nodsh && skip "remote OST with nodsh"
9487
9488         f="$DIR/$tfile"
9489         $LFS setstripe -c 1 -i 0 $f
9490
9491         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9492
9493         do_facet ost1 lctl set_param fail_loc=0x217
9494         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9495         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9496
9497         do_facet ost1 lctl set_param fail_loc=0
9498         $DIRECTIO write $f 0 2 || error "write error"
9499
9500         cancel_lru_locks osc
9501         $DIRECTIO read $f 0 1 || error "read error"
9502
9503         do_facet ost1 lctl set_param fail_loc=0x217
9504         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9505
9506         do_facet ost1 lctl set_param fail_loc=0
9507         rm -f $f
9508 }
9509 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9510
9511 test_71() {
9512         test_mkdir $DIR/$tdir
9513         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9514         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9515 }
9516 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9517
9518 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9520         [ "$RUNAS_ID" = "$UID" ] &&
9521                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9522         # Check that testing environment is properly set up. Skip if not
9523         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9524                 skip_env "User $RUNAS_ID does not exist - skipping"
9525
9526         touch $DIR/$tfile
9527         chmod 777 $DIR/$tfile
9528         chmod ug+s $DIR/$tfile
9529         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9530                 error "$RUNAS dd $DIR/$tfile failed"
9531         # See if we are still setuid/sgid
9532         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9533                 error "S/gid is not dropped on write"
9534         # Now test that MDS is updated too
9535         cancel_lru_locks mdc
9536         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9537                 error "S/gid is not dropped on MDS"
9538         rm -f $DIR/$tfile
9539 }
9540 run_test 72a "Test that remove suid works properly (bug5695) ===="
9541
9542 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9543         local perm
9544
9545         [ "$RUNAS_ID" = "$UID" ] &&
9546                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9547         [ "$RUNAS_ID" -eq 0 ] &&
9548                 skip_env "RUNAS_ID = 0 -- skipping"
9549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9550         # Check that testing environment is properly set up. Skip if not
9551         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9552                 skip_env "User $RUNAS_ID does not exist - skipping"
9553
9554         touch $DIR/${tfile}-f{g,u}
9555         test_mkdir $DIR/${tfile}-dg
9556         test_mkdir $DIR/${tfile}-du
9557         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9558         chmod g+s $DIR/${tfile}-{f,d}g
9559         chmod u+s $DIR/${tfile}-{f,d}u
9560         for perm in 777 2777 4777; do
9561                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9562                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9563                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9564                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9565         done
9566         true
9567 }
9568 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9569
9570 # bug 3462 - multiple simultaneous MDC requests
9571 test_73() {
9572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9573
9574         test_mkdir $DIR/d73-1
9575         test_mkdir $DIR/d73-2
9576         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9577         pid1=$!
9578
9579         lctl set_param fail_loc=0x80000129
9580         $MULTIOP $DIR/d73-1/f73-2 Oc &
9581         sleep 1
9582         lctl set_param fail_loc=0
9583
9584         $MULTIOP $DIR/d73-2/f73-3 Oc &
9585         pid3=$!
9586
9587         kill -USR1 $pid1
9588         wait $pid1 || return 1
9589
9590         sleep 25
9591
9592         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9593         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9594         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9595
9596         rm -rf $DIR/d73-*
9597 }
9598 run_test 73 "multiple MDC requests (should not deadlock)"
9599
9600 test_74a() { # bug 6149, 6184
9601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9602
9603         touch $DIR/f74a
9604         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9605         #
9606         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9607         # will spin in a tight reconnection loop
9608         $LCTL set_param fail_loc=0x8000030e
9609         # get any lock that won't be difficult - lookup works.
9610         ls $DIR/f74a
9611         $LCTL set_param fail_loc=0
9612         rm -f $DIR/f74a
9613         true
9614 }
9615 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9616
9617 test_74b() { # bug 13310
9618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9619
9620         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9621         #
9622         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9623         # will spin in a tight reconnection loop
9624         $LCTL set_param fail_loc=0x8000030e
9625         # get a "difficult" lock
9626         touch $DIR/f74b
9627         $LCTL set_param fail_loc=0
9628         rm -f $DIR/f74b
9629         true
9630 }
9631 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9632
9633 test_74c() {
9634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9635
9636         #define OBD_FAIL_LDLM_NEW_LOCK
9637         $LCTL set_param fail_loc=0x319
9638         touch $DIR/$tfile && error "touch successful"
9639         $LCTL set_param fail_loc=0
9640         true
9641 }
9642 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9643
9644 slab_lic=/sys/kernel/slab/lustre_inode_cache
9645 num_objects() {
9646         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9647         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9648                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9649 }
9650
9651 test_76a() { # Now for b=20433, added originally in b=1443
9652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9653
9654         cancel_lru_locks osc
9655         # there may be some slab objects cached per core
9656         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9657         local before=$(num_objects)
9658         local count=$((512 * cpus))
9659         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9660         local margin=$((count / 10))
9661         if [[ -f $slab_lic/aliases ]]; then
9662                 local aliases=$(cat $slab_lic/aliases)
9663                 (( aliases > 0 )) && margin=$((margin * aliases))
9664         fi
9665
9666         echo "before slab objects: $before"
9667         for i in $(seq $count); do
9668                 touch $DIR/$tfile
9669                 rm -f $DIR/$tfile
9670         done
9671         cancel_lru_locks osc
9672         local after=$(num_objects)
9673         echo "created: $count, after slab objects: $after"
9674         # shared slab counts are not very accurate, allow significant margin
9675         # the main goal is that the cache growth is not permanently > $count
9676         while (( after > before + margin )); do
9677                 sleep 1
9678                 after=$(num_objects)
9679                 wait=$((wait + 1))
9680                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9681                 if (( wait > 60 )); then
9682                         error "inode slab grew from $before+$margin to $after"
9683                 fi
9684         done
9685 }
9686 run_test 76a "confirm clients recycle inodes properly ===="
9687
9688 test_76b() {
9689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9690         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9691
9692         local count=512
9693         local before=$(num_objects)
9694
9695         for i in $(seq $count); do
9696                 mkdir $DIR/$tdir
9697                 rmdir $DIR/$tdir
9698         done
9699
9700         local after=$(num_objects)
9701         local wait=0
9702
9703         while (( after > before )); do
9704                 sleep 1
9705                 after=$(num_objects)
9706                 wait=$((wait + 1))
9707                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9708                 if (( wait > 60 )); then
9709                         error "inode slab grew from $before to $after"
9710                 fi
9711         done
9712
9713         echo "slab objects before: $before, after: $after"
9714 }
9715 run_test 76b "confirm clients recycle directory inodes properly ===="
9716
9717 export ORIG_CSUM=""
9718 set_checksums()
9719 {
9720         # Note: in sptlrpc modes which enable its own bulk checksum, the
9721         # original crc32_le bulk checksum will be automatically disabled,
9722         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9723         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9724         # In this case set_checksums() will not be no-op, because sptlrpc
9725         # bulk checksum will be enabled all through the test.
9726
9727         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9728         lctl set_param -n osc.*.checksums $1
9729         return 0
9730 }
9731
9732 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9733                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9734 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9735                              tr -d [] | head -n1)}
9736 set_checksum_type()
9737 {
9738         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9739         rc=$?
9740         log "set checksum type to $1, rc = $rc"
9741         return $rc
9742 }
9743
9744 get_osc_checksum_type()
9745 {
9746         # arugment 1: OST name, like OST0000
9747         ost=$1
9748         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9749                         sed 's/.*\[\(.*\)\].*/\1/g')
9750         rc=$?
9751         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9752         echo $checksum_type
9753 }
9754
9755 F77_TMP=$TMP/f77-temp
9756 F77SZ=8
9757 setup_f77() {
9758         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9759                 error "error writing to $F77_TMP"
9760 }
9761
9762 test_77a() { # bug 10889
9763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9764         $GSS && skip_env "could not run with gss"
9765
9766         [ ! -f $F77_TMP ] && setup_f77
9767         set_checksums 1
9768         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9769         set_checksums 0
9770         rm -f $DIR/$tfile
9771 }
9772 run_test 77a "normal checksum read/write operation"
9773
9774 test_77b() { # bug 10889
9775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9776         $GSS && skip_env "could not run with gss"
9777
9778         [ ! -f $F77_TMP ] && setup_f77
9779         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9780         $LCTL set_param fail_loc=0x80000409
9781         set_checksums 1
9782
9783         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9784                 error "dd error: $?"
9785         $LCTL set_param fail_loc=0
9786
9787         for algo in $CKSUM_TYPES; do
9788                 cancel_lru_locks osc
9789                 set_checksum_type $algo
9790                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9791                 $LCTL set_param fail_loc=0x80000408
9792                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9793                 $LCTL set_param fail_loc=0
9794         done
9795         set_checksums 0
9796         set_checksum_type $ORIG_CSUM_TYPE
9797         rm -f $DIR/$tfile
9798 }
9799 run_test 77b "checksum error on client write, read"
9800
9801 cleanup_77c() {
9802         trap 0
9803         set_checksums 0
9804         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9805         $check_ost &&
9806                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9807         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9808         $check_ost && [ -n "$ost_file_prefix" ] &&
9809                 do_facet ost1 rm -f ${ost_file_prefix}\*
9810 }
9811
9812 test_77c() {
9813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9814         $GSS && skip_env "could not run with gss"
9815         remote_ost_nodsh && skip "remote OST with nodsh"
9816
9817         local bad1
9818         local osc_file_prefix
9819         local osc_file
9820         local check_ost=false
9821         local ost_file_prefix
9822         local ost_file
9823         local orig_cksum
9824         local dump_cksum
9825         local fid
9826
9827         # ensure corruption will occur on first OSS/OST
9828         $LFS setstripe -i 0 $DIR/$tfile
9829
9830         [ ! -f $F77_TMP ] && setup_f77
9831         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9832                 error "dd write error: $?"
9833         fid=$($LFS path2fid $DIR/$tfile)
9834
9835         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9836         then
9837                 check_ost=true
9838                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9839                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9840         else
9841                 echo "OSS do not support bulk pages dump upon error"
9842         fi
9843
9844         osc_file_prefix=$($LCTL get_param -n debug_path)
9845         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9846
9847         trap cleanup_77c EXIT
9848
9849         set_checksums 1
9850         # enable bulk pages dump upon error on Client
9851         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9852         # enable bulk pages dump upon error on OSS
9853         $check_ost &&
9854                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9855
9856         # flush Client cache to allow next read to reach OSS
9857         cancel_lru_locks osc
9858
9859         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9860         $LCTL set_param fail_loc=0x80000408
9861         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9862         $LCTL set_param fail_loc=0
9863
9864         rm -f $DIR/$tfile
9865
9866         # check cksum dump on Client
9867         osc_file=$(ls ${osc_file_prefix}*)
9868         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9869         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9870         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9871         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9872         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9873                      cksum)
9874         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9875         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9876                 error "dump content does not match on Client"
9877
9878         $check_ost || skip "No need to check cksum dump on OSS"
9879
9880         # check cksum dump on OSS
9881         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9882         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9883         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9884         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9885         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9886                 error "dump content does not match on OSS"
9887
9888         cleanup_77c
9889 }
9890 run_test 77c "checksum error on client read with debug"
9891
9892 test_77d() { # bug 10889
9893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9894         $GSS && skip_env "could not run with gss"
9895
9896         stack_trap "rm -f $DIR/$tfile"
9897         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9898         $LCTL set_param fail_loc=0x80000409
9899         set_checksums 1
9900         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9901                 error "direct write: rc=$?"
9902         $LCTL set_param fail_loc=0
9903         set_checksums 0
9904
9905         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9906         $LCTL set_param fail_loc=0x80000408
9907         set_checksums 1
9908         cancel_lru_locks osc
9909         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9910                 error "direct read: rc=$?"
9911         $LCTL set_param fail_loc=0
9912         set_checksums 0
9913 }
9914 run_test 77d "checksum error on OST direct write, read"
9915
9916 test_77f() { # bug 10889
9917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9918         $GSS && skip_env "could not run with gss"
9919
9920         set_checksums 1
9921         stack_trap "rm -f $DIR/$tfile"
9922         for algo in $CKSUM_TYPES; do
9923                 cancel_lru_locks osc
9924                 set_checksum_type $algo
9925                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9926                 $LCTL set_param fail_loc=0x409
9927                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9928                         error "direct write succeeded"
9929                 $LCTL set_param fail_loc=0
9930         done
9931         set_checksum_type $ORIG_CSUM_TYPE
9932         set_checksums 0
9933 }
9934 run_test 77f "repeat checksum error on write (expect error)"
9935
9936 test_77g() { # bug 10889
9937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9938         $GSS && skip_env "could not run with gss"
9939         remote_ost_nodsh && skip "remote OST with nodsh"
9940
9941         [ ! -f $F77_TMP ] && setup_f77
9942
9943         local file=$DIR/$tfile
9944         stack_trap "rm -f $file" EXIT
9945
9946         $LFS setstripe -c 1 -i 0 $file
9947         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9948         do_facet ost1 lctl set_param fail_loc=0x8000021a
9949         set_checksums 1
9950         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9951                 error "write error: rc=$?"
9952         do_facet ost1 lctl set_param fail_loc=0
9953         set_checksums 0
9954
9955         cancel_lru_locks osc
9956         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9957         do_facet ost1 lctl set_param fail_loc=0x8000021b
9958         set_checksums 1
9959         cmp $F77_TMP $file || error "file compare failed"
9960         do_facet ost1 lctl set_param fail_loc=0
9961         set_checksums 0
9962 }
9963 run_test 77g "checksum error on OST write, read"
9964
9965 test_77k() { # LU-10906
9966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9967         $GSS && skip_env "could not run with gss"
9968
9969         local cksum_param="osc.$FSNAME*.checksums"
9970         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9971         local checksum
9972         local i
9973
9974         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9975         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9976         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9977
9978         for i in 0 1; do
9979                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9980                         error "failed to set checksum=$i on MGS"
9981                 wait_update $HOSTNAME "$get_checksum" $i
9982                 #remount
9983                 echo "remount client, checksum should be $i"
9984                 remount_client $MOUNT || error "failed to remount client"
9985                 checksum=$(eval $get_checksum)
9986                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9987         done
9988         # remove persistent param to avoid races with checksum mountopt below
9989         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9990                 error "failed to delete checksum on MGS"
9991
9992         for opt in "checksum" "nochecksum"; do
9993                 #remount with mount option
9994                 echo "remount client with option $opt, checksum should be $i"
9995                 umount_client $MOUNT || error "failed to umount client"
9996                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9997                         error "failed to mount client with option '$opt'"
9998                 checksum=$(eval $get_checksum)
9999                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10000                 i=$((i - 1))
10001         done
10002
10003         remount_client $MOUNT || error "failed to remount client"
10004 }
10005 run_test 77k "enable/disable checksum correctly"
10006
10007 test_77l() {
10008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10009         $GSS && skip_env "could not run with gss"
10010
10011         set_checksums 1
10012         stack_trap "set_checksums $ORIG_CSUM" EXIT
10013         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10014
10015         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10016
10017         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10018         for algo in $CKSUM_TYPES; do
10019                 set_checksum_type $algo || error "fail to set checksum type $algo"
10020                 osc_algo=$(get_osc_checksum_type OST0000)
10021                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10022
10023                 # no locks, no reqs to let the connection idle
10024                 cancel_lru_locks osc
10025                 lru_resize_disable osc
10026                 wait_osc_import_state client ost1 IDLE
10027
10028                 # ensure ost1 is connected
10029                 stat $DIR/$tfile >/dev/null || error "can't stat"
10030                 wait_osc_import_state client ost1 FULL
10031
10032                 osc_algo=$(get_osc_checksum_type OST0000)
10033                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10034         done
10035         return 0
10036 }
10037 run_test 77l "preferred checksum type is remembered after reconnected"
10038
10039 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10040 rm -f $F77_TMP
10041 unset F77_TMP
10042
10043 test_77m() {
10044         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10045                 skip "Need at least version 2.14.52"
10046         local param=checksum_speed
10047
10048         $LCTL get_param $param || error "reading $param failed"
10049
10050         csum_speeds=$($LCTL get_param -n $param)
10051
10052         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10053                 error "known checksum types are missing"
10054 }
10055 run_test 77m "Verify checksum_speed is correctly read"
10056
10057 check_filefrag_77n() {
10058         local nr_ext=0
10059         local starts=()
10060         local ends=()
10061
10062         while read extidx a b start end rest; do
10063                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10064                         nr_ext=$(( $nr_ext + 1 ))
10065                         starts+=( ${start%..} )
10066                         ends+=( ${end%:} )
10067                 fi
10068         done < <( filefrag -sv $1 )
10069
10070         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10071         return 1
10072 }
10073
10074 test_77n() {
10075         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10076
10077         touch $DIR/$tfile
10078         $TRUNCATE $DIR/$tfile 0
10079         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10080         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10081         check_filefrag_77n $DIR/$tfile ||
10082                 skip "$tfile blocks not contiguous around hole"
10083
10084         set_checksums 1
10085         stack_trap "set_checksums $ORIG_CSUM" EXIT
10086         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10087         stack_trap "rm -f $DIR/$tfile"
10088
10089         for algo in $CKSUM_TYPES; do
10090                 if [[ "$algo" =~ ^t10 ]]; then
10091                         set_checksum_type $algo ||
10092                                 error "fail to set checksum type $algo"
10093                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10094                                 error "fail to read $tfile with $algo"
10095                 fi
10096         done
10097         rm -f $DIR/$tfile
10098         return 0
10099 }
10100 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10101
10102 test_77o() {
10103         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10104                 skip "Need MDS version at least 2.14.55"
10105         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10106                 skip "Need OST version at least 2.14.55"
10107         local ofd=obdfilter
10108         local mdt=mdt
10109
10110         # print OST checksum_type
10111         echo "$ofd.$FSNAME-*.checksum_type:"
10112         do_nodes $(comma_list $(osts_nodes)) \
10113                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10114
10115         # print MDT checksum_type
10116         echo "$mdt.$FSNAME-*.checksum_type:"
10117         do_nodes $(comma_list $(mdts_nodes)) \
10118                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10119
10120         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10121                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10122
10123         (( $o_count == $OSTCOUNT )) ||
10124                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10125
10126         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10127                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10128
10129         (( $m_count == $MDSCOUNT )) ||
10130                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10131 }
10132 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10133
10134 cleanup_test_78() {
10135         trap 0
10136         rm -f $DIR/$tfile
10137 }
10138
10139 test_78() { # bug 10901
10140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10141         remote_ost || skip_env "local OST"
10142
10143         NSEQ=5
10144         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10145         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10146         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10147         echo "MemTotal: $MEMTOTAL"
10148
10149         # reserve 256MB of memory for the kernel and other running processes,
10150         # and then take 1/2 of the remaining memory for the read/write buffers.
10151         if [ $MEMTOTAL -gt 512 ] ;then
10152                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10153         else
10154                 # for those poor memory-starved high-end clusters...
10155                 MEMTOTAL=$((MEMTOTAL / 2))
10156         fi
10157         echo "Mem to use for directio: $MEMTOTAL"
10158
10159         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10160         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10161         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10162         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10163                 head -n1)
10164         echo "Smallest OST: $SMALLESTOST"
10165         [[ $SMALLESTOST -lt 10240 ]] &&
10166                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10167
10168         trap cleanup_test_78 EXIT
10169
10170         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10171                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10172
10173         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10174         echo "File size: $F78SIZE"
10175         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10176         for i in $(seq 1 $NSEQ); do
10177                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10178                 echo directIO rdwr round $i of $NSEQ
10179                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10180         done
10181
10182         cleanup_test_78
10183 }
10184 run_test 78 "handle large O_DIRECT writes correctly ============"
10185
10186 test_79() { # bug 12743
10187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10188
10189         wait_delete_completed
10190
10191         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10192         BKFREE=$(calc_osc_kbytes kbytesfree)
10193         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10194
10195         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10196         DFTOTAL=`echo $STRING | cut -d, -f1`
10197         DFUSED=`echo $STRING  | cut -d, -f2`
10198         DFAVAIL=`echo $STRING | cut -d, -f3`
10199         DFFREE=$(($DFTOTAL - $DFUSED))
10200
10201         ALLOWANCE=$((64 * $OSTCOUNT))
10202
10203         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10204            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10205                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10206         fi
10207         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10208            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10209                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10210         fi
10211         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10212            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10213                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10214         fi
10215 }
10216 run_test 79 "df report consistency check ======================="
10217
10218 test_80() { # bug 10718
10219         remote_ost_nodsh && skip "remote OST with nodsh"
10220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10221
10222         # relax strong synchronous semantics for slow backends like ZFS
10223         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10224                 local soc="obdfilter.*.sync_lock_cancel"
10225                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10226
10227                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10228                 if [ -z "$save" ]; then
10229                         soc="obdfilter.*.sync_on_lock_cancel"
10230                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10231                 fi
10232
10233                 if [ "$save" != "never" ]; then
10234                         local hosts=$(comma_list $(osts_nodes))
10235
10236                         do_nodes $hosts $LCTL set_param $soc=never
10237                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10238                 fi
10239         fi
10240
10241         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10242         sync; sleep 1; sync
10243         local before=$(date +%s)
10244         cancel_lru_locks osc
10245         local after=$(date +%s)
10246         local diff=$((after - before))
10247         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10248
10249         rm -f $DIR/$tfile
10250 }
10251 run_test 80 "Page eviction is equally fast at high offsets too"
10252
10253 test_81a() { # LU-456
10254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10255         remote_ost_nodsh && skip "remote OST with nodsh"
10256
10257         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10258         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10259         do_facet ost1 lctl set_param fail_loc=0x80000228
10260
10261         # write should trigger a retry and success
10262         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10263         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10264         RC=$?
10265         if [ $RC -ne 0 ] ; then
10266                 error "write should success, but failed for $RC"
10267         fi
10268 }
10269 run_test 81a "OST should retry write when get -ENOSPC ==============="
10270
10271 test_81b() { # LU-456
10272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10273         remote_ost_nodsh && skip "remote OST with nodsh"
10274
10275         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10276         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10277         do_facet ost1 lctl set_param fail_loc=0x228
10278
10279         # write should retry several times and return -ENOSPC finally
10280         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10281         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10282         RC=$?
10283         ENOSPC=28
10284         if [ $RC -ne $ENOSPC ] ; then
10285                 error "dd should fail for -ENOSPC, but succeed."
10286         fi
10287 }
10288 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10289
10290 test_99() {
10291         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10292
10293         test_mkdir $DIR/$tdir.cvsroot
10294         chown $RUNAS_ID $DIR/$tdir.cvsroot
10295
10296         cd $TMP
10297         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10298
10299         cd /etc/init.d
10300         # some versions of cvs import exit(1) when asked to import links or
10301         # files they can't read.  ignore those files.
10302         local toignore=$(find . -type l -printf '-I %f\n' -o \
10303                          ! -perm /4 -printf '-I %f\n')
10304         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10305                 $tdir.reposname vtag rtag
10306
10307         cd $DIR
10308         test_mkdir $DIR/$tdir.reposname
10309         chown $RUNAS_ID $DIR/$tdir.reposname
10310         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10311
10312         cd $DIR/$tdir.reposname
10313         $RUNAS touch foo99
10314         $RUNAS cvs add -m 'addmsg' foo99
10315         $RUNAS cvs update
10316         $RUNAS cvs commit -m 'nomsg' foo99
10317         rm -fr $DIR/$tdir.cvsroot
10318 }
10319 run_test 99 "cvs strange file/directory operations"
10320
10321 test_100() {
10322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10323         [[ "$NETTYPE" =~ tcp ]] ||
10324                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10325         remote_ost_nodsh && skip "remote OST with nodsh"
10326         remote_mds_nodsh && skip "remote MDS with nodsh"
10327         remote_servers ||
10328                 skip "useless for local single node setup"
10329
10330         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10331                 [ "$PROT" != "tcp" ] && continue
10332                 RPORT=$(echo $REMOTE | cut -d: -f2)
10333                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10334
10335                 rc=0
10336                 LPORT=`echo $LOCAL | cut -d: -f2`
10337                 if [ $LPORT -ge 1024 ]; then
10338                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10339                         netstat -tna
10340                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10341                 fi
10342         done
10343         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10344 }
10345 run_test 100 "check local port using privileged port ==========="
10346
10347 function get_named_value()
10348 {
10349     local tag=$1
10350
10351     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10352 }
10353
10354 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10355                    awk '/^max_cached_mb/ { print $2 }')
10356
10357 cleanup_101a() {
10358         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10359         trap 0
10360 }
10361
10362 test_101a() {
10363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10364
10365         local s
10366         local discard
10367         local nreads=10000
10368         local cache_limit=32
10369
10370         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10371         trap cleanup_101a EXIT
10372         $LCTL set_param -n llite.*.read_ahead_stats=0
10373         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10374
10375         #
10376         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10377         #
10378         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10379         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10380
10381         discard=0
10382         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10383                    get_named_value 'read.but.discarded'); do
10384                         discard=$(($discard + $s))
10385         done
10386         cleanup_101a
10387
10388         $LCTL get_param osc.*-osc*.rpc_stats
10389         $LCTL get_param llite.*.read_ahead_stats
10390
10391         # Discard is generally zero, but sometimes a few random reads line up
10392         # and trigger larger readahead, which is wasted & leads to discards.
10393         if [[ $(($discard)) -gt $nreads ]]; then
10394                 error "too many ($discard) discarded pages"
10395         fi
10396         rm -f $DIR/$tfile || true
10397 }
10398 run_test 101a "check read-ahead for random reads"
10399
10400 setup_test101bc() {
10401         test_mkdir $DIR/$tdir
10402         local ssize=$1
10403         local FILE_LENGTH=$2
10404         STRIPE_OFFSET=0
10405
10406         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10407
10408         local list=$(comma_list $(osts_nodes))
10409         set_osd_param $list '' read_cache_enable 0
10410         set_osd_param $list '' writethrough_cache_enable 0
10411
10412         trap cleanup_test101bc EXIT
10413         # prepare the read-ahead file
10414         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10415
10416         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10417                                 count=$FILE_SIZE_MB 2> /dev/null
10418
10419 }
10420
10421 cleanup_test101bc() {
10422         trap 0
10423         rm -rf $DIR/$tdir
10424         rm -f $DIR/$tfile
10425
10426         local list=$(comma_list $(osts_nodes))
10427         set_osd_param $list '' read_cache_enable 1
10428         set_osd_param $list '' writethrough_cache_enable 1
10429 }
10430
10431 calc_total() {
10432         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10433 }
10434
10435 ra_check_101() {
10436         local READ_SIZE=$1
10437         local STRIPE_SIZE=$2
10438         local FILE_LENGTH=$3
10439         local RA_INC=1048576
10440         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10441         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10442                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10443         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10444                   get_named_value 'read.but.discarded' | calc_total)
10445         if [[ $DISCARD -gt $discard_limit ]]; then
10446                 $LCTL get_param llite.*.read_ahead_stats
10447                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10448         else
10449                 echo "Read-ahead success for size ${READ_SIZE}"
10450         fi
10451 }
10452
10453 test_101b() {
10454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10455         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10456
10457         local STRIPE_SIZE=1048576
10458         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10459
10460         if [ $SLOW == "yes" ]; then
10461                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10462         else
10463                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10464         fi
10465
10466         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10467
10468         # prepare the read-ahead file
10469         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10470         cancel_lru_locks osc
10471         for BIDX in 2 4 8 16 32 64 128 256
10472         do
10473                 local BSIZE=$((BIDX*4096))
10474                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10475                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10476                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10477                 $LCTL set_param -n llite.*.read_ahead_stats=0
10478                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10479                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10480                 cancel_lru_locks osc
10481                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10482         done
10483         cleanup_test101bc
10484         true
10485 }
10486 run_test 101b "check stride-io mode read-ahead ================="
10487
10488 test_101c() {
10489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10490
10491         local STRIPE_SIZE=1048576
10492         local FILE_LENGTH=$((STRIPE_SIZE*100))
10493         local nreads=10000
10494         local rsize=65536
10495         local osc_rpc_stats
10496
10497         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10498
10499         cancel_lru_locks osc
10500         $LCTL set_param osc.*.rpc_stats=0
10501         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10502         $LCTL get_param osc.*.rpc_stats
10503         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10504                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10505                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10506                 local size
10507
10508                 if [ $lines -le 20 ]; then
10509                         echo "continue debug"
10510                         continue
10511                 fi
10512                 for size in 1 2 4 8; do
10513                         local rpc=$(echo "$stats" |
10514                                     awk '($1 == "'$size':") {print $2; exit; }')
10515                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10516                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10517                 done
10518                 echo "$osc_rpc_stats check passed!"
10519         done
10520         cleanup_test101bc
10521         true
10522 }
10523 run_test 101c "check stripe_size aligned read-ahead"
10524
10525 test_101d() {
10526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10527
10528         local file=$DIR/$tfile
10529         local sz_MB=${FILESIZE_101d:-80}
10530         local ra_MB=${READAHEAD_MB:-40}
10531
10532         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10533         [ $free_MB -lt $sz_MB ] &&
10534                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10535
10536         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10537         $LFS setstripe -c -1 $file || error "setstripe failed"
10538
10539         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10540         echo Cancel LRU locks on lustre client to flush the client cache
10541         cancel_lru_locks osc
10542
10543         echo Disable read-ahead
10544         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10545         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10546         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10547         $LCTL get_param -n llite.*.max_read_ahead_mb
10548
10549         echo "Reading the test file $file with read-ahead disabled"
10550         local sz_KB=$((sz_MB * 1024 / 4))
10551         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10552         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10553         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10554                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10555
10556         echo "Cancel LRU locks on lustre client to flush the client cache"
10557         cancel_lru_locks osc
10558         echo Enable read-ahead with ${ra_MB}MB
10559         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10560
10561         echo "Reading the test file $file with read-ahead enabled"
10562         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10563                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10564
10565         echo "read-ahead disabled time read $raOFF"
10566         echo "read-ahead enabled time read $raON"
10567
10568         rm -f $file
10569         wait_delete_completed
10570
10571         # use awk for this check instead of bash because it handles decimals
10572         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10573                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10574 }
10575 run_test 101d "file read with and without read-ahead enabled"
10576
10577 test_101e() {
10578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10579
10580         local file=$DIR/$tfile
10581         local size_KB=500  #KB
10582         local count=100
10583         local bsize=1024
10584
10585         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10586         local need_KB=$((count * size_KB))
10587         [[ $free_KB -le $need_KB ]] &&
10588                 skip_env "Need free space $need_KB, have $free_KB"
10589
10590         echo "Creating $count ${size_KB}K test files"
10591         for ((i = 0; i < $count; i++)); do
10592                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10593         done
10594
10595         echo "Cancel LRU locks on lustre client to flush the client cache"
10596         cancel_lru_locks $OSC
10597
10598         echo "Reset readahead stats"
10599         $LCTL set_param -n llite.*.read_ahead_stats=0
10600
10601         for ((i = 0; i < $count; i++)); do
10602                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10603         done
10604
10605         $LCTL get_param llite.*.max_cached_mb
10606         $LCTL get_param llite.*.read_ahead_stats
10607         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10608                      get_named_value 'misses' | calc_total)
10609
10610         for ((i = 0; i < $count; i++)); do
10611                 rm -rf $file.$i 2>/dev/null
10612         done
10613
10614         #10000 means 20% reads are missing in readahead
10615         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10616 }
10617 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10618
10619 test_101f() {
10620         which iozone || skip_env "no iozone installed"
10621
10622         local old_debug=$($LCTL get_param debug)
10623         old_debug=${old_debug#*=}
10624         $LCTL set_param debug="reada mmap"
10625
10626         # create a test file
10627         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10628
10629         echo Cancel LRU locks on lustre client to flush the client cache
10630         cancel_lru_locks osc
10631
10632         echo Reset readahead stats
10633         $LCTL set_param -n llite.*.read_ahead_stats=0
10634
10635         echo mmap read the file with small block size
10636         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10637                 > /dev/null 2>&1
10638
10639         echo checking missing pages
10640         $LCTL get_param llite.*.read_ahead_stats
10641         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10642                         get_named_value 'misses' | calc_total)
10643
10644         $LCTL set_param debug="$old_debug"
10645         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10646         rm -f $DIR/$tfile
10647 }
10648 run_test 101f "check mmap read performance"
10649
10650 test_101g_brw_size_test() {
10651         local mb=$1
10652         local pages=$((mb * 1048576 / PAGE_SIZE))
10653         local file=$DIR/$tfile
10654
10655         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10656                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10657         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10658                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10659                         return 2
10660         done
10661
10662         stack_trap "rm -f $file" EXIT
10663         $LCTL set_param -n osc.*.rpc_stats=0
10664
10665         # 10 RPCs should be enough for the test
10666         local count=10
10667         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10668                 { error "dd write ${mb} MB blocks failed"; return 3; }
10669         cancel_lru_locks osc
10670         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10671                 { error "dd write ${mb} MB blocks failed"; return 4; }
10672
10673         # calculate number of full-sized read and write RPCs
10674         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10675                 sed -n '/pages per rpc/,/^$/p' |
10676                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10677                 END { print reads,writes }'))
10678         # allow one extra full-sized read RPC for async readahead
10679         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10680                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10681         [[ ${rpcs[1]} == $count ]] ||
10682                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10683 }
10684
10685 test_101g() {
10686         remote_ost_nodsh && skip "remote OST with nodsh"
10687
10688         local rpcs
10689         local osts=$(get_facets OST)
10690         local list=$(comma_list $(osts_nodes))
10691         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10692         local brw_size="obdfilter.*.brw_size"
10693
10694         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10695
10696         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10697
10698         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10699                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10700                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10701            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10702                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10703                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10704
10705                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10706                         suffix="M"
10707
10708                 if [[ $orig_mb -lt 16 ]]; then
10709                         save_lustre_params $osts "$brw_size" > $p
10710                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10711                                 error "set 16MB RPC size failed"
10712
10713                         echo "remount client to enable new RPC size"
10714                         remount_client $MOUNT || error "remount_client failed"
10715                 fi
10716
10717                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10718                 # should be able to set brw_size=12, but no rpc_stats for that
10719                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10720         fi
10721
10722         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10723
10724         if [[ $orig_mb -lt 16 ]]; then
10725                 restore_lustre_params < $p
10726                 remount_client $MOUNT || error "remount_client restore failed"
10727         fi
10728
10729         rm -f $p $DIR/$tfile
10730 }
10731 run_test 101g "Big bulk(4/16 MiB) readahead"
10732
10733 test_101h() {
10734         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10735
10736         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10737                 error "dd 70M file failed"
10738         echo Cancel LRU locks on lustre client to flush the client cache
10739         cancel_lru_locks osc
10740
10741         echo "Reset readahead stats"
10742         $LCTL set_param -n llite.*.read_ahead_stats 0
10743
10744         echo "Read 10M of data but cross 64M bundary"
10745         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10746         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10747                      get_named_value 'misses' | calc_total)
10748         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10749         rm -f $p $DIR/$tfile
10750 }
10751 run_test 101h "Readahead should cover current read window"
10752
10753 test_101i() {
10754         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10755                 error "dd 10M file failed"
10756
10757         local max_per_file_mb=$($LCTL get_param -n \
10758                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10759         cancel_lru_locks osc
10760         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10761         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10762                 error "set max_read_ahead_per_file_mb to 1 failed"
10763
10764         echo "Reset readahead stats"
10765         $LCTL set_param llite.*.read_ahead_stats=0
10766
10767         dd if=$DIR/$tfile of=/dev/null bs=2M
10768
10769         $LCTL get_param llite.*.read_ahead_stats
10770         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10771                      awk '/misses/ { print $2 }')
10772         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10773         rm -f $DIR/$tfile
10774 }
10775 run_test 101i "allow current readahead to exceed reservation"
10776
10777 test_101j() {
10778         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10779                 error "setstripe $DIR/$tfile failed"
10780         local file_size=$((1048576 * 16))
10781         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10782         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10783
10784         echo Disable read-ahead
10785         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10786
10787         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10788         for blk in $PAGE_SIZE 1048576 $file_size; do
10789                 cancel_lru_locks osc
10790                 echo "Reset readahead stats"
10791                 $LCTL set_param -n llite.*.read_ahead_stats=0
10792                 local count=$(($file_size / $blk))
10793                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10794                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10795                              get_named_value 'failed.to.fast.read' | calc_total)
10796                 $LCTL get_param -n llite.*.read_ahead_stats
10797                 [ $miss -eq $count ] || error "expected $count got $miss"
10798         done
10799
10800         rm -f $p $DIR/$tfile
10801 }
10802 run_test 101j "A complete read block should be submitted when no RA"
10803
10804 setup_test102() {
10805         test_mkdir $DIR/$tdir
10806         chown $RUNAS_ID $DIR/$tdir
10807         STRIPE_SIZE=65536
10808         STRIPE_OFFSET=1
10809         STRIPE_COUNT=$OSTCOUNT
10810         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10811
10812         trap cleanup_test102 EXIT
10813         cd $DIR
10814         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10815         cd $DIR/$tdir
10816         for num in 1 2 3 4; do
10817                 for count in $(seq 1 $STRIPE_COUNT); do
10818                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10819                                 local size=`expr $STRIPE_SIZE \* $num`
10820                                 local file=file"$num-$idx-$count"
10821                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10822                         done
10823                 done
10824         done
10825
10826         cd $DIR
10827         $1 tar cf $TMP/f102.tar $tdir --xattrs
10828 }
10829
10830 cleanup_test102() {
10831         trap 0
10832         rm -f $TMP/f102.tar
10833         rm -rf $DIR/d0.sanity/d102
10834 }
10835
10836 test_102a() {
10837         [ "$UID" != 0 ] && skip "must run as root"
10838         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10839                 skip_env "must have user_xattr"
10840
10841         [ -z "$(which setfattr 2>/dev/null)" ] &&
10842                 skip_env "could not find setfattr"
10843
10844         local testfile=$DIR/$tfile
10845
10846         touch $testfile
10847         echo "set/get xattr..."
10848         setfattr -n trusted.name1 -v value1 $testfile ||
10849                 error "setfattr -n trusted.name1=value1 $testfile failed"
10850         getfattr -n trusted.name1 $testfile 2> /dev/null |
10851           grep "trusted.name1=.value1" ||
10852                 error "$testfile missing trusted.name1=value1"
10853
10854         setfattr -n user.author1 -v author1 $testfile ||
10855                 error "setfattr -n user.author1=author1 $testfile failed"
10856         getfattr -n user.author1 $testfile 2> /dev/null |
10857           grep "user.author1=.author1" ||
10858                 error "$testfile missing trusted.author1=author1"
10859
10860         echo "listxattr..."
10861         setfattr -n trusted.name2 -v value2 $testfile ||
10862                 error "$testfile unable to set trusted.name2"
10863         setfattr -n trusted.name3 -v value3 $testfile ||
10864                 error "$testfile unable to set trusted.name3"
10865         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10866             grep "trusted.name" | wc -l) -eq 3 ] ||
10867                 error "$testfile missing 3 trusted.name xattrs"
10868
10869         setfattr -n user.author2 -v author2 $testfile ||
10870                 error "$testfile unable to set user.author2"
10871         setfattr -n user.author3 -v author3 $testfile ||
10872                 error "$testfile unable to set user.author3"
10873         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10874             grep "user.author" | wc -l) -eq 3 ] ||
10875                 error "$testfile missing 3 user.author xattrs"
10876
10877         echo "remove xattr..."
10878         setfattr -x trusted.name1 $testfile ||
10879                 error "$testfile error deleting trusted.name1"
10880         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10881                 error "$testfile did not delete trusted.name1 xattr"
10882
10883         setfattr -x user.author1 $testfile ||
10884                 error "$testfile error deleting user.author1"
10885         echo "set lustre special xattr ..."
10886         $LFS setstripe -c1 $testfile
10887         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10888                 awk -F "=" '/trusted.lov/ { print $2 }' )
10889         setfattr -n "trusted.lov" -v $lovea $testfile ||
10890                 error "$testfile doesn't ignore setting trusted.lov again"
10891         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10892                 error "$testfile allow setting invalid trusted.lov"
10893         rm -f $testfile
10894 }
10895 run_test 102a "user xattr test =================================="
10896
10897 check_102b_layout() {
10898         local layout="$*"
10899         local testfile=$DIR/$tfile
10900
10901         echo "test layout '$layout'"
10902         $LFS setstripe $layout $testfile || error "setstripe failed"
10903         $LFS getstripe -y $testfile
10904
10905         echo "get/set/list trusted.lov xattr ..." # b=10930
10906         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10907         [[ "$value" =~ "trusted.lov" ]] ||
10908                 error "can't get trusted.lov from $testfile"
10909         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10910                 error "getstripe failed"
10911
10912         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10913
10914         value=$(cut -d= -f2 <<<$value)
10915         # LU-13168: truncated xattr should fail if short lov_user_md header
10916         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10917                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10918         for len in $lens; do
10919                 echo "setfattr $len $testfile.2"
10920                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10921                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10922         done
10923         local stripe_size=$($LFS getstripe -S $testfile.2)
10924         local stripe_count=$($LFS getstripe -c $testfile.2)
10925         [[ $stripe_size -eq 65536 ]] ||
10926                 error "stripe size $stripe_size != 65536"
10927         [[ $stripe_count -eq $stripe_count_orig ]] ||
10928                 error "stripe count $stripe_count != $stripe_count_orig"
10929         rm $testfile $testfile.2
10930 }
10931
10932 test_102b() {
10933         [ -z "$(which setfattr 2>/dev/null)" ] &&
10934                 skip_env "could not find setfattr"
10935         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10936
10937         # check plain layout
10938         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10939
10940         # and also check composite layout
10941         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10942
10943 }
10944 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10945
10946 test_102c() {
10947         [ -z "$(which setfattr 2>/dev/null)" ] &&
10948                 skip_env "could not find setfattr"
10949         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10950
10951         # b10930: get/set/list lustre.lov xattr
10952         echo "get/set/list lustre.lov xattr ..."
10953         test_mkdir $DIR/$tdir
10954         chown $RUNAS_ID $DIR/$tdir
10955         local testfile=$DIR/$tdir/$tfile
10956         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10957                 error "setstripe failed"
10958         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10959                 error "getstripe failed"
10960         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10961         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10962
10963         local testfile2=${testfile}2
10964         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10965                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10966
10967         $RUNAS $MCREATE $testfile2
10968         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10969         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10970         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10971         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10972         [ $stripe_count -eq $STRIPECOUNT ] ||
10973                 error "stripe count $stripe_count != $STRIPECOUNT"
10974 }
10975 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10976
10977 compare_stripe_info1() {
10978         local stripe_index_all_zero=true
10979
10980         for num in 1 2 3 4; do
10981                 for count in $(seq 1 $STRIPE_COUNT); do
10982                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10983                                 local size=$((STRIPE_SIZE * num))
10984                                 local file=file"$num-$offset-$count"
10985                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10986                                 [[ $stripe_size -ne $size ]] &&
10987                                     error "$file: size $stripe_size != $size"
10988                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10989                                 # allow fewer stripes to be created, ORI-601
10990                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10991                                     error "$file: count $stripe_count != $count"
10992                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10993                                 [[ $stripe_index -ne 0 ]] &&
10994                                         stripe_index_all_zero=false
10995                         done
10996                 done
10997         done
10998         $stripe_index_all_zero &&
10999                 error "all files are being extracted starting from OST index 0"
11000         return 0
11001 }
11002
11003 have_xattrs_include() {
11004         tar --help | grep -q xattrs-include &&
11005                 echo --xattrs-include="lustre.*"
11006 }
11007
11008 test_102d() {
11009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11010         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11011
11012         XINC=$(have_xattrs_include)
11013         setup_test102
11014         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11015         cd $DIR/$tdir/$tdir
11016         compare_stripe_info1
11017 }
11018 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11019
11020 test_102f() {
11021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11022         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11023
11024         XINC=$(have_xattrs_include)
11025         setup_test102
11026         test_mkdir $DIR/$tdir.restore
11027         cd $DIR
11028         tar cf - --xattrs $tdir | tar xf - \
11029                 -C $DIR/$tdir.restore --xattrs $XINC
11030         cd $DIR/$tdir.restore/$tdir
11031         compare_stripe_info1
11032 }
11033 run_test 102f "tar copy files, not keep osts"
11034
11035 grow_xattr() {
11036         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11037                 skip "must have user_xattr"
11038         [ -z "$(which setfattr 2>/dev/null)" ] &&
11039                 skip_env "could not find setfattr"
11040         [ -z "$(which getfattr 2>/dev/null)" ] &&
11041                 skip_env "could not find getfattr"
11042
11043         local xsize=${1:-1024}  # in bytes
11044         local file=$DIR/$tfile
11045         local value="$(generate_string $xsize)"
11046         local xbig=trusted.big
11047         local toobig=$2
11048
11049         touch $file
11050         log "save $xbig on $file"
11051         if [ -z "$toobig" ]
11052         then
11053                 setfattr -n $xbig -v $value $file ||
11054                         error "saving $xbig on $file failed"
11055         else
11056                 setfattr -n $xbig -v $value $file &&
11057                         error "saving $xbig on $file succeeded"
11058                 return 0
11059         fi
11060
11061         local orig=$(get_xattr_value $xbig $file)
11062         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11063
11064         local xsml=trusted.sml
11065         log "save $xsml on $file"
11066         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11067
11068         local new=$(get_xattr_value $xbig $file)
11069         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11070
11071         log "grow $xsml on $file"
11072         setfattr -n $xsml -v "$value" $file ||
11073                 error "growing $xsml on $file failed"
11074
11075         new=$(get_xattr_value $xbig $file)
11076         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11077         log "$xbig still valid after growing $xsml"
11078
11079         rm -f $file
11080 }
11081
11082 test_102h() { # bug 15777
11083         grow_xattr 1024
11084 }
11085 run_test 102h "grow xattr from inside inode to external block"
11086
11087 test_102ha() {
11088         large_xattr_enabled || skip_env "ea_inode feature disabled"
11089
11090         echo "setting xattr of max xattr size: $(max_xattr_size)"
11091         grow_xattr $(max_xattr_size)
11092
11093         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11094         echo "This should fail:"
11095         grow_xattr $(($(max_xattr_size) + 10)) 1
11096 }
11097 run_test 102ha "grow xattr from inside inode to external inode"
11098
11099 test_102i() { # bug 17038
11100         [ -z "$(which getfattr 2>/dev/null)" ] &&
11101                 skip "could not find getfattr"
11102
11103         touch $DIR/$tfile
11104         ln -s $DIR/$tfile $DIR/${tfile}link
11105         getfattr -n trusted.lov $DIR/$tfile ||
11106                 error "lgetxattr on $DIR/$tfile failed"
11107         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11108                 grep -i "no such attr" ||
11109                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11110         rm -f $DIR/$tfile $DIR/${tfile}link
11111 }
11112 run_test 102i "lgetxattr test on symbolic link ============"
11113
11114 test_102j() {
11115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11116         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11117
11118         XINC=$(have_xattrs_include)
11119         setup_test102 "$RUNAS"
11120         chown $RUNAS_ID $DIR/$tdir
11121         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11122         cd $DIR/$tdir/$tdir
11123         compare_stripe_info1 "$RUNAS"
11124 }
11125 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11126
11127 test_102k() {
11128         [ -z "$(which setfattr 2>/dev/null)" ] &&
11129                 skip "could not find setfattr"
11130
11131         touch $DIR/$tfile
11132         # b22187 just check that does not crash for regular file.
11133         setfattr -n trusted.lov $DIR/$tfile
11134         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11135         local test_kdir=$DIR/$tdir
11136         test_mkdir $test_kdir
11137         local default_size=$($LFS getstripe -S $test_kdir)
11138         local default_count=$($LFS getstripe -c $test_kdir)
11139         local default_offset=$($LFS getstripe -i $test_kdir)
11140         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11141                 error 'dir setstripe failed'
11142         setfattr -n trusted.lov $test_kdir
11143         local stripe_size=$($LFS getstripe -S $test_kdir)
11144         local stripe_count=$($LFS getstripe -c $test_kdir)
11145         local stripe_offset=$($LFS getstripe -i $test_kdir)
11146         [ $stripe_size -eq $default_size ] ||
11147                 error "stripe size $stripe_size != $default_size"
11148         [ $stripe_count -eq $default_count ] ||
11149                 error "stripe count $stripe_count != $default_count"
11150         [ $stripe_offset -eq $default_offset ] ||
11151                 error "stripe offset $stripe_offset != $default_offset"
11152         rm -rf $DIR/$tfile $test_kdir
11153 }
11154 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11155
11156 test_102l() {
11157         [ -z "$(which getfattr 2>/dev/null)" ] &&
11158                 skip "could not find getfattr"
11159
11160         # LU-532 trusted. xattr is invisible to non-root
11161         local testfile=$DIR/$tfile
11162
11163         touch $testfile
11164
11165         echo "listxattr as user..."
11166         chown $RUNAS_ID $testfile
11167         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11168             grep -q "trusted" &&
11169                 error "$testfile trusted xattrs are user visible"
11170
11171         return 0;
11172 }
11173 run_test 102l "listxattr size test =================================="
11174
11175 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11176         local path=$DIR/$tfile
11177         touch $path
11178
11179         listxattr_size_check $path || error "listattr_size_check $path failed"
11180 }
11181 run_test 102m "Ensure listxattr fails on small bufffer ========"
11182
11183 cleanup_test102
11184
11185 getxattr() { # getxattr path name
11186         # Return the base64 encoding of the value of xattr name on path.
11187         local path=$1
11188         local name=$2
11189
11190         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11191         # file: $path
11192         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11193         #
11194         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11195
11196         getfattr --absolute-names --encoding=base64 --name=$name $path |
11197                 awk -F= -v name=$name '$1 == name {
11198                         print substr($0, index($0, "=") + 1);
11199         }'
11200 }
11201
11202 test_102n() { # LU-4101 mdt: protect internal xattrs
11203         [ -z "$(which setfattr 2>/dev/null)" ] &&
11204                 skip "could not find setfattr"
11205         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11206         then
11207                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11208         fi
11209
11210         local file0=$DIR/$tfile.0
11211         local file1=$DIR/$tfile.1
11212         local xattr0=$TMP/$tfile.0
11213         local xattr1=$TMP/$tfile.1
11214         local namelist="lov lma lmv link fid version som hsm"
11215         local name
11216         local value
11217
11218         rm -rf $file0 $file1 $xattr0 $xattr1
11219         touch $file0 $file1
11220
11221         # Get 'before' xattrs of $file1.
11222         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11223
11224         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11225                 namelist+=" lfsck_namespace"
11226         for name in $namelist; do
11227                 # Try to copy xattr from $file0 to $file1.
11228                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11229
11230                 setfattr --name=trusted.$name --value="$value" $file1 ||
11231                         error "setxattr 'trusted.$name' failed"
11232
11233                 # Try to set a garbage xattr.
11234                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11235
11236                 if [[ x$name == "xlov" ]]; then
11237                         setfattr --name=trusted.lov --value="$value" $file1 &&
11238                         error "setxattr invalid 'trusted.lov' success"
11239                 else
11240                         setfattr --name=trusted.$name --value="$value" $file1 ||
11241                                 error "setxattr invalid 'trusted.$name' failed"
11242                 fi
11243
11244                 # Try to remove the xattr from $file1. We don't care if this
11245                 # appears to succeed or fail, we just don't want there to be
11246                 # any changes or crashes.
11247                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11248         done
11249
11250         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11251         then
11252                 name="lfsck_ns"
11253                 # Try to copy xattr from $file0 to $file1.
11254                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11255
11256                 setfattr --name=trusted.$name --value="$value" $file1 ||
11257                         error "setxattr 'trusted.$name' failed"
11258
11259                 # Try to set a garbage xattr.
11260                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11261
11262                 setfattr --name=trusted.$name --value="$value" $file1 ||
11263                         error "setxattr 'trusted.$name' failed"
11264
11265                 # Try to remove the xattr from $file1. We don't care if this
11266                 # appears to succeed or fail, we just don't want there to be
11267                 # any changes or crashes.
11268                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11269         fi
11270
11271         # Get 'after' xattrs of file1.
11272         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11273
11274         if ! diff $xattr0 $xattr1; then
11275                 error "before and after xattrs of '$file1' differ"
11276         fi
11277
11278         rm -rf $file0 $file1 $xattr0 $xattr1
11279
11280         return 0
11281 }
11282 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11283
11284 test_102p() { # LU-4703 setxattr did not check ownership
11285         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11286                 skip "MDS needs to be at least 2.5.56"
11287
11288         local testfile=$DIR/$tfile
11289
11290         touch $testfile
11291
11292         echo "setfacl as user..."
11293         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11294         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11295
11296         echo "setfattr as user..."
11297         setfacl -m "u:$RUNAS_ID:---" $testfile
11298         $RUNAS setfattr -x system.posix_acl_access $testfile
11299         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11300 }
11301 run_test 102p "check setxattr(2) correctly fails without permission"
11302
11303 test_102q() {
11304         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11305                 skip "MDS needs to be at least 2.6.92"
11306
11307         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11308 }
11309 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11310
11311 test_102r() {
11312         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11313                 skip "MDS needs to be at least 2.6.93"
11314
11315         touch $DIR/$tfile || error "touch"
11316         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11317         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11318         rm $DIR/$tfile || error "rm"
11319
11320         #normal directory
11321         mkdir -p $DIR/$tdir || error "mkdir"
11322         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11323         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11324         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11325                 error "$testfile error deleting user.author1"
11326         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11327                 grep "user.$(basename $tdir)" &&
11328                 error "$tdir did not delete user.$(basename $tdir)"
11329         rmdir $DIR/$tdir || error "rmdir"
11330
11331         #striped directory
11332         test_mkdir $DIR/$tdir
11333         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11334         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11335         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11336                 error "$testfile error deleting user.author1"
11337         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11338                 grep "user.$(basename $tdir)" &&
11339                 error "$tdir did not delete user.$(basename $tdir)"
11340         rmdir $DIR/$tdir || error "rm striped dir"
11341 }
11342 run_test 102r "set EAs with empty values"
11343
11344 test_102s() {
11345         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11346                 skip "MDS needs to be at least 2.11.52"
11347
11348         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11349
11350         save_lustre_params client "llite.*.xattr_cache" > $save
11351
11352         for cache in 0 1; do
11353                 lctl set_param llite.*.xattr_cache=$cache
11354
11355                 rm -f $DIR/$tfile
11356                 touch $DIR/$tfile || error "touch"
11357                 for prefix in lustre security system trusted user; do
11358                         # Note getxattr() may fail with 'Operation not
11359                         # supported' or 'No such attribute' depending
11360                         # on prefix and cache.
11361                         getfattr -n $prefix.n102s $DIR/$tfile &&
11362                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11363                 done
11364         done
11365
11366         restore_lustre_params < $save
11367 }
11368 run_test 102s "getting nonexistent xattrs should fail"
11369
11370 test_102t() {
11371         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11372                 skip "MDS needs to be at least 2.11.52"
11373
11374         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11375
11376         save_lustre_params client "llite.*.xattr_cache" > $save
11377
11378         for cache in 0 1; do
11379                 lctl set_param llite.*.xattr_cache=$cache
11380
11381                 for buf_size in 0 256; do
11382                         rm -f $DIR/$tfile
11383                         touch $DIR/$tfile || error "touch"
11384                         setfattr -n user.multiop $DIR/$tfile
11385                         $MULTIOP $DIR/$tfile oa$buf_size ||
11386                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11387                 done
11388         done
11389
11390         restore_lustre_params < $save
11391 }
11392 run_test 102t "zero length xattr values handled correctly"
11393
11394 run_acl_subtest()
11395 {
11396     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11397     return $?
11398 }
11399
11400 test_103a() {
11401         [ "$UID" != 0 ] && skip "must run as root"
11402         $GSS && skip_env "could not run under gss"
11403         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11404                 skip_env "must have acl enabled"
11405         [ -z "$(which setfacl 2>/dev/null)" ] &&
11406                 skip_env "could not find setfacl"
11407         remote_mds_nodsh && skip "remote MDS with nodsh"
11408
11409         gpasswd -a daemon bin                           # LU-5641
11410         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11411
11412         declare -a identity_old
11413
11414         for num in $(seq $MDSCOUNT); do
11415                 switch_identity $num true || identity_old[$num]=$?
11416         done
11417
11418         SAVE_UMASK=$(umask)
11419         umask 0022
11420         mkdir -p $DIR/$tdir
11421         cd $DIR/$tdir
11422
11423         echo "performing cp ..."
11424         run_acl_subtest cp || error "run_acl_subtest cp failed"
11425         echo "performing getfacl-noacl..."
11426         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11427         echo "performing misc..."
11428         run_acl_subtest misc || error  "misc test failed"
11429         echo "performing permissions..."
11430         run_acl_subtest permissions || error "permissions failed"
11431         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11432         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11433                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11434                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11435         then
11436                 echo "performing permissions xattr..."
11437                 run_acl_subtest permissions_xattr ||
11438                         error "permissions_xattr failed"
11439         fi
11440         echo "performing setfacl..."
11441         run_acl_subtest setfacl || error  "setfacl test failed"
11442
11443         # inheritance test got from HP
11444         echo "performing inheritance..."
11445         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11446         chmod +x make-tree || error "chmod +x failed"
11447         run_acl_subtest inheritance || error "inheritance test failed"
11448         rm -f make-tree
11449
11450         echo "LU-974 ignore umask when acl is enabled..."
11451         run_acl_subtest 974 || error "LU-974 umask test failed"
11452         if [ $MDSCOUNT -ge 2 ]; then
11453                 run_acl_subtest 974_remote ||
11454                         error "LU-974 umask test failed under remote dir"
11455         fi
11456
11457         echo "LU-2561 newly created file is same size as directory..."
11458         if [ "$mds1_FSTYPE" != "zfs" ]; then
11459                 run_acl_subtest 2561 || error "LU-2561 test failed"
11460         else
11461                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11462         fi
11463
11464         run_acl_subtest 4924 || error "LU-4924 test failed"
11465
11466         cd $SAVE_PWD
11467         umask $SAVE_UMASK
11468
11469         for num in $(seq $MDSCOUNT); do
11470                 if [ "${identity_old[$num]}" = 1 ]; then
11471                         switch_identity $num false || identity_old[$num]=$?
11472                 fi
11473         done
11474 }
11475 run_test 103a "acl test"
11476
11477 test_103b() {
11478         declare -a pids
11479         local U
11480
11481         for U in {0..511}; do
11482                 {
11483                 local O=$(printf "%04o" $U)
11484
11485                 umask $(printf "%04o" $((511 ^ $O)))
11486                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11487                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11488
11489                 (( $S == ($O & 0666) )) ||
11490                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11491
11492                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11493                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11494                 (( $S == ($O & 0666) )) ||
11495                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11496
11497                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11498                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11499                 (( $S == ($O & 0666) )) ||
11500                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11501                 rm -f $DIR/$tfile.[smp]$0
11502                 } &
11503                 local pid=$!
11504
11505                 # limit the concurrently running threads to 64. LU-11878
11506                 local idx=$((U % 64))
11507                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11508                 pids[idx]=$pid
11509         done
11510         wait
11511 }
11512 run_test 103b "umask lfs setstripe"
11513
11514 test_103c() {
11515         mkdir -p $DIR/$tdir
11516         cp -rp $DIR/$tdir $DIR/$tdir.bak
11517
11518         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11519                 error "$DIR/$tdir shouldn't contain default ACL"
11520         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11521                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11522         true
11523 }
11524 run_test 103c "'cp -rp' won't set empty acl"
11525
11526 test_103e() {
11527         local numacl
11528         local fileacl
11529         local saved_debug=$($LCTL get_param -n debug)
11530
11531         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11532                 skip "MDS needs to be at least 2.14.0"
11533
11534         large_xattr_enabled || skip_env "ea_inode feature disabled"
11535
11536         mkdir -p $DIR/$tdir
11537         # add big LOV EA to cause reply buffer overflow earlier
11538         $LFS setstripe -C 1000 $DIR/$tdir
11539         lctl set_param mdc.*-mdc*.stats=clear
11540
11541         $LCTL set_param debug=0
11542         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11543         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11544
11545         # add a large number of default ACLs (expect 8000+ for 2.13+)
11546         for U in {2..7000}; do
11547                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11548                         error "Able to add just $U default ACLs"
11549         done
11550         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11551         echo "$numacl default ACLs created"
11552
11553         stat $DIR/$tdir || error "Cannot stat directory"
11554         # check file creation
11555         touch $DIR/$tdir/$tfile ||
11556                 error "failed to create $tfile with $numacl default ACLs"
11557         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11558         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11559         echo "$fileacl ACLs were inherited"
11560         (( $fileacl == $numacl )) ||
11561                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11562         # check that new ACLs creation adds new ACLs to inherited ACLs
11563         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11564                 error "Cannot set new ACL"
11565         numacl=$((numacl + 1))
11566         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11567         (( $fileacl == $numacl )) ||
11568                 error "failed to add new ACL: $fileacl != $numacl as expected"
11569         # adds more ACLs to a file to reach their maximum at 8000+
11570         numacl=0
11571         for U in {20000..25000}; do
11572                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11573                 numacl=$((numacl + 1))
11574         done
11575         echo "Added $numacl more ACLs to the file"
11576         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11577         echo "Total $fileacl ACLs in file"
11578         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11579         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11580         rmdir $DIR/$tdir || error "Cannot remove directory"
11581 }
11582 run_test 103e "inheritance of big amount of default ACLs"
11583
11584 test_103f() {
11585         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11586                 skip "MDS needs to be at least 2.14.51"
11587
11588         large_xattr_enabled || skip_env "ea_inode feature disabled"
11589
11590         # enable changelog to consume more internal MDD buffers
11591         changelog_register
11592
11593         mkdir -p $DIR/$tdir
11594         # add big LOV EA
11595         $LFS setstripe -C 1000 $DIR/$tdir
11596         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11597         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11598         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11599         rmdir $DIR/$tdir || error "Cannot remove directory"
11600 }
11601 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11602
11603 test_104a() {
11604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11605
11606         touch $DIR/$tfile
11607         lfs df || error "lfs df failed"
11608         lfs df -ih || error "lfs df -ih failed"
11609         lfs df -h $DIR || error "lfs df -h $DIR failed"
11610         lfs df -i $DIR || error "lfs df -i $DIR failed"
11611         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11612         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11613
11614         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11615         lctl --device %$OSC deactivate
11616         lfs df || error "lfs df with deactivated OSC failed"
11617         lctl --device %$OSC activate
11618         # wait the osc back to normal
11619         wait_osc_import_ready client ost
11620
11621         lfs df || error "lfs df with reactivated OSC failed"
11622         rm -f $DIR/$tfile
11623 }
11624 run_test 104a "lfs df [-ih] [path] test ========================="
11625
11626 test_104b() {
11627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11628         [ $RUNAS_ID -eq $UID ] &&
11629                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11630
11631         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11632                         grep "Permission denied" | wc -l)))
11633         if [ $denied_cnt -ne 0 ]; then
11634                 error "lfs check servers test failed"
11635         fi
11636 }
11637 run_test 104b "$RUNAS lfs check servers test ===================="
11638
11639 #
11640 # Verify $1 is within range of $2.
11641 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11642 # $1 is <= 2% of $2. Else Fail.
11643 #
11644 value_in_range() {
11645         # Strip all units (M, G, T)
11646         actual=$(echo $1 | tr -d A-Z)
11647         expect=$(echo $2 | tr -d A-Z)
11648
11649         expect_lo=$(($expect * 98 / 100)) # 2% below
11650         expect_hi=$(($expect * 102 / 100)) # 2% above
11651
11652         # permit 2% drift above and below
11653         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11654 }
11655
11656 test_104c() {
11657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11658         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11659
11660         local ost_param="osd-zfs.$FSNAME-OST0000."
11661         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11662         local ofacets=$(get_facets OST)
11663         local mfacets=$(get_facets MDS)
11664         local saved_ost_blocks=
11665         local saved_mdt_blocks=
11666
11667         echo "Before recordsize change"
11668         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11669         df=($(df -h | grep "/mnt/lustre"$))
11670
11671         # For checking.
11672         echo "lfs output : ${lfs_df[*]}"
11673         echo "df  output : ${df[*]}"
11674
11675         for facet in ${ofacets//,/ }; do
11676                 if [ -z $saved_ost_blocks ]; then
11677                         saved_ost_blocks=$(do_facet $facet \
11678                                 lctl get_param -n $ost_param.blocksize)
11679                         echo "OST Blocksize: $saved_ost_blocks"
11680                 fi
11681                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11682                 do_facet $facet zfs set recordsize=32768 $ost
11683         done
11684
11685         # BS too small. Sufficient for functional testing.
11686         for facet in ${mfacets//,/ }; do
11687                 if [ -z $saved_mdt_blocks ]; then
11688                         saved_mdt_blocks=$(do_facet $facet \
11689                                 lctl get_param -n $mdt_param.blocksize)
11690                         echo "MDT Blocksize: $saved_mdt_blocks"
11691                 fi
11692                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11693                 do_facet $facet zfs set recordsize=32768 $mdt
11694         done
11695
11696         # Give new values chance to reflect change
11697         sleep 2
11698
11699         echo "After recordsize change"
11700         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11701         df_after=($(df -h | grep "/mnt/lustre"$))
11702
11703         # For checking.
11704         echo "lfs output : ${lfs_df_after[*]}"
11705         echo "df  output : ${df_after[*]}"
11706
11707         # Verify lfs df
11708         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11709                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11710         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11711                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11712         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11713                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11714
11715         # Verify df
11716         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11717                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11718         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11719                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11720         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11721                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11722
11723         # Restore MDT recordize back to original
11724         for facet in ${mfacets//,/ }; do
11725                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11726                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11727         done
11728
11729         # Restore OST recordize back to original
11730         for facet in ${ofacets//,/ }; do
11731                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11732                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11733         done
11734
11735         return 0
11736 }
11737 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11738
11739 test_105a() {
11740         # doesn't work on 2.4 kernels
11741         touch $DIR/$tfile
11742         if $(flock_is_enabled); then
11743                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11744         else
11745                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11746         fi
11747         rm -f $DIR/$tfile
11748 }
11749 run_test 105a "flock when mounted without -o flock test ========"
11750
11751 test_105b() {
11752         touch $DIR/$tfile
11753         if $(flock_is_enabled); then
11754                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11755         else
11756                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11757         fi
11758         rm -f $DIR/$tfile
11759 }
11760 run_test 105b "fcntl when mounted without -o flock test ========"
11761
11762 test_105c() {
11763         touch $DIR/$tfile
11764         if $(flock_is_enabled); then
11765                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11766         else
11767                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11768         fi
11769         rm -f $DIR/$tfile
11770 }
11771 run_test 105c "lockf when mounted without -o flock test"
11772
11773 test_105d() { # bug 15924
11774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11775
11776         test_mkdir $DIR/$tdir
11777         flock_is_enabled || skip_env "mount w/o flock enabled"
11778         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11779         $LCTL set_param fail_loc=0x80000315
11780         flocks_test 2 $DIR/$tdir
11781 }
11782 run_test 105d "flock race (should not freeze) ========"
11783
11784 test_105e() { # bug 22660 && 22040
11785         flock_is_enabled || skip_env "mount w/o flock enabled"
11786
11787         touch $DIR/$tfile
11788         flocks_test 3 $DIR/$tfile
11789 }
11790 run_test 105e "Two conflicting flocks from same process"
11791
11792 test_106() { #bug 10921
11793         test_mkdir $DIR/$tdir
11794         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11795         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11796 }
11797 run_test 106 "attempt exec of dir followed by chown of that dir"
11798
11799 test_107() {
11800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11801
11802         CDIR=`pwd`
11803         local file=core
11804
11805         cd $DIR
11806         rm -f $file
11807
11808         local save_pattern=$(sysctl -n kernel.core_pattern)
11809         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11810         sysctl -w kernel.core_pattern=$file
11811         sysctl -w kernel.core_uses_pid=0
11812
11813         ulimit -c unlimited
11814         sleep 60 &
11815         SLEEPPID=$!
11816
11817         sleep 1
11818
11819         kill -s 11 $SLEEPPID
11820         wait $SLEEPPID
11821         if [ -e $file ]; then
11822                 size=`stat -c%s $file`
11823                 [ $size -eq 0 ] && error "Fail to create core file $file"
11824         else
11825                 error "Fail to create core file $file"
11826         fi
11827         rm -f $file
11828         sysctl -w kernel.core_pattern=$save_pattern
11829         sysctl -w kernel.core_uses_pid=$save_uses_pid
11830         cd $CDIR
11831 }
11832 run_test 107 "Coredump on SIG"
11833
11834 test_110() {
11835         test_mkdir $DIR/$tdir
11836         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11837         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11838                 error "mkdir with 256 char should fail, but did not"
11839         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11840                 error "create with 255 char failed"
11841         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11842                 error "create with 256 char should fail, but did not"
11843
11844         ls -l $DIR/$tdir
11845         rm -rf $DIR/$tdir
11846 }
11847 run_test 110 "filename length checking"
11848
11849 #
11850 # Purpose: To verify dynamic thread (OSS) creation.
11851 #
11852 test_115() {
11853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11854         remote_ost_nodsh && skip "remote OST with nodsh"
11855
11856         # Lustre does not stop service threads once they are started.
11857         # Reset number of running threads to default.
11858         stopall
11859         setupall
11860
11861         local OSTIO_pre
11862         local save_params="$TMP/sanity-$TESTNAME.parameters"
11863
11864         # Get ll_ost_io count before I/O
11865         OSTIO_pre=$(do_facet ost1 \
11866                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11867         # Exit if lustre is not running (ll_ost_io not running).
11868         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11869
11870         echo "Starting with $OSTIO_pre threads"
11871         local thread_max=$((OSTIO_pre * 2))
11872         local rpc_in_flight=$((thread_max * 2))
11873         # this is limited to OSC_MAX_RIF_MAX (256)
11874         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
11875         thread_max=$((rpc_in_flight / 2))
11876         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
11877                 return
11878
11879         # Number of I/O Process proposed to be started.
11880         local nfiles
11881         local facets=$(get_facets OST)
11882
11883         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11884         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11885
11886         # Set in_flight to $rpc_in_flight
11887         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11888                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11889         nfiles=${rpc_in_flight}
11890         # Set ost thread_max to $thread_max
11891         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11892
11893         # 5 Minutes should be sufficient for max number of OSS
11894         # threads(thread_max) to be created.
11895         local timeout=300
11896
11897         # Start I/O.
11898         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11899         test_mkdir $DIR/$tdir
11900         for i in $(seq $nfiles); do
11901                 local file=$DIR/$tdir/${tfile}-$i
11902                 $LFS setstripe -c -1 -i 0 $file
11903                 ($WTL $file $timeout)&
11904         done
11905
11906         # I/O Started - Wait for thread_started to reach thread_max or report
11907         # error if thread_started is more than thread_max.
11908         echo "Waiting for thread_started to reach thread_max"
11909         local thread_started=0
11910         local end_time=$((SECONDS + timeout))
11911
11912         while [ $SECONDS -le $end_time ] ; do
11913                 echo -n "."
11914                 # Get ost i/o thread_started count.
11915                 thread_started=$(do_facet ost1 \
11916                         "$LCTL get_param \
11917                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11918                 # Break out if thread_started is equal/greater than thread_max
11919                 if [[ $thread_started -ge $thread_max ]]; then
11920                         echo ll_ost_io thread_started $thread_started, \
11921                                 equal/greater than thread_max $thread_max
11922                         break
11923                 fi
11924                 sleep 1
11925         done
11926
11927         # Cleanup - We have the numbers, Kill i/o jobs if running.
11928         jobcount=($(jobs -p))
11929         for i in $(seq 0 $((${#jobcount[@]}-1)))
11930         do
11931                 kill -9 ${jobcount[$i]}
11932                 if [ $? -ne 0 ] ; then
11933                         echo Warning: \
11934                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11935                 fi
11936         done
11937
11938         # Cleanup files left by WTL binary.
11939         for i in $(seq $nfiles); do
11940                 local file=$DIR/$tdir/${tfile}-$i
11941                 rm -rf $file
11942                 if [ $? -ne 0 ] ; then
11943                         echo "Warning: Failed to delete file $file"
11944                 fi
11945         done
11946
11947         restore_lustre_params <$save_params
11948         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11949
11950         # Error out if no new thread has started or Thread started is greater
11951         # than thread max.
11952         if [[ $thread_started -le $OSTIO_pre ||
11953                         $thread_started -gt $thread_max ]]; then
11954                 error "ll_ost_io: thread_started $thread_started" \
11955                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11956                       "No new thread started or thread started greater " \
11957                       "than thread_max."
11958         fi
11959 }
11960 run_test 115 "verify dynamic thread creation===================="
11961
11962 free_min_max () {
11963         wait_delete_completed
11964         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11965         echo "OST kbytes available: ${AVAIL[@]}"
11966         MAXV=${AVAIL[0]}
11967         MAXI=0
11968         MINV=${AVAIL[0]}
11969         MINI=0
11970         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11971                 #echo OST $i: ${AVAIL[i]}kb
11972                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11973                         MAXV=${AVAIL[i]}
11974                         MAXI=$i
11975                 fi
11976                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11977                         MINV=${AVAIL[i]}
11978                         MINI=$i
11979                 fi
11980         done
11981         echo "Min free space: OST $MINI: $MINV"
11982         echo "Max free space: OST $MAXI: $MAXV"
11983 }
11984
11985 test_116a() { # was previously test_116()
11986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11987         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11988         remote_mds_nodsh && skip "remote MDS with nodsh"
11989
11990         echo -n "Free space priority "
11991         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11992                 head -n1
11993         declare -a AVAIL
11994         free_min_max
11995
11996         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11997         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11998         stack_trap simple_cleanup_common
11999
12000         # Check if we need to generate uneven OSTs
12001         test_mkdir -p $DIR/$tdir/OST${MINI}
12002         local FILL=$((MINV / 4))
12003         local DIFF=$((MAXV - MINV))
12004         local DIFF2=$((DIFF * 100 / MINV))
12005
12006         local threshold=$(do_facet $SINGLEMDS \
12007                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12008         threshold=${threshold%%%}
12009         echo -n "Check for uneven OSTs: "
12010         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12011
12012         if [[ $DIFF2 -gt $threshold ]]; then
12013                 echo "ok"
12014                 echo "Don't need to fill OST$MINI"
12015         else
12016                 # generate uneven OSTs. Write 2% over the QOS threshold value
12017                 echo "no"
12018                 DIFF=$((threshold - DIFF2 + 2))
12019                 DIFF2=$((MINV * DIFF / 100))
12020                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12021                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12022                         error "setstripe failed"
12023                 DIFF=$((DIFF2 / 2048))
12024                 i=0
12025                 while [ $i -lt $DIFF ]; do
12026                         i=$((i + 1))
12027                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12028                                 bs=2M count=1 2>/dev/null
12029                         echo -n .
12030                 done
12031                 echo .
12032                 sync
12033                 sleep_maxage
12034                 free_min_max
12035         fi
12036
12037         DIFF=$((MAXV - MINV))
12038         DIFF2=$((DIFF * 100 / MINV))
12039         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12040         if [ $DIFF2 -gt $threshold ]; then
12041                 echo "ok"
12042         else
12043                 skip "QOS imbalance criteria not met"
12044         fi
12045
12046         MINI1=$MINI
12047         MINV1=$MINV
12048         MAXI1=$MAXI
12049         MAXV1=$MAXV
12050
12051         # now fill using QOS
12052         $LFS setstripe -c 1 $DIR/$tdir
12053         FILL=$((FILL / 200))
12054         if [ $FILL -gt 600 ]; then
12055                 FILL=600
12056         fi
12057         echo "writing $FILL files to QOS-assigned OSTs"
12058         i=0
12059         while [ $i -lt $FILL ]; do
12060                 i=$((i + 1))
12061                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12062                         count=1 2>/dev/null
12063                 echo -n .
12064         done
12065         echo "wrote $i 200k files"
12066         sync
12067         sleep_maxage
12068
12069         echo "Note: free space may not be updated, so measurements might be off"
12070         free_min_max
12071         DIFF2=$((MAXV - MINV))
12072         echo "free space delta: orig $DIFF final $DIFF2"
12073         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12074         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12075         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12076         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12077         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12078         if [[ $DIFF -gt 0 ]]; then
12079                 FILL=$((DIFF2 * 100 / DIFF - 100))
12080                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12081         fi
12082
12083         # Figure out which files were written where
12084         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12085                awk '/'$MINI1': / {print $2; exit}')
12086         echo $UUID
12087         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12088         echo "$MINC files created on smaller OST $MINI1"
12089         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12090                awk '/'$MAXI1': / {print $2; exit}')
12091         echo $UUID
12092         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12093         echo "$MAXC files created on larger OST $MAXI1"
12094         if [[ $MINC -gt 0 ]]; then
12095                 FILL=$((MAXC * 100 / MINC - 100))
12096                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12097         fi
12098         [[ $MAXC -gt $MINC ]] ||
12099                 error_ignore LU-9 "stripe QOS didn't balance free space"
12100 }
12101 run_test 116a "stripe QOS: free space balance ==================="
12102
12103 test_116b() { # LU-2093
12104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12105         remote_mds_nodsh && skip "remote MDS with nodsh"
12106
12107 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12108         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12109                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12110         [ -z "$old_rr" ] && skip "no QOS"
12111         do_facet $SINGLEMDS lctl set_param \
12112                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12113         mkdir -p $DIR/$tdir
12114         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12115         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12116         do_facet $SINGLEMDS lctl set_param fail_loc=0
12117         rm -rf $DIR/$tdir
12118         do_facet $SINGLEMDS lctl set_param \
12119                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12120 }
12121 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12122
12123 test_117() # bug 10891
12124 {
12125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12126
12127         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12128         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12129         lctl set_param fail_loc=0x21e
12130         > $DIR/$tfile || error "truncate failed"
12131         lctl set_param fail_loc=0
12132         echo "Truncate succeeded."
12133         rm -f $DIR/$tfile
12134 }
12135 run_test 117 "verify osd extend =========="
12136
12137 NO_SLOW_RESENDCOUNT=4
12138 export OLD_RESENDCOUNT=""
12139 set_resend_count () {
12140         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12141         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12142         lctl set_param -n $PROC_RESENDCOUNT $1
12143         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12144 }
12145
12146 # for reduce test_118* time (b=14842)
12147 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12148
12149 # Reset async IO behavior after error case
12150 reset_async() {
12151         FILE=$DIR/reset_async
12152
12153         # Ensure all OSCs are cleared
12154         $LFS setstripe -c -1 $FILE
12155         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12156         sync
12157         rm $FILE
12158 }
12159
12160 test_118a() #bug 11710
12161 {
12162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12163
12164         reset_async
12165
12166         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12167         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12168         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12169
12170         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12171                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12172                 return 1;
12173         fi
12174         rm -f $DIR/$tfile
12175 }
12176 run_test 118a "verify O_SYNC works =========="
12177
12178 test_118b()
12179 {
12180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12181         remote_ost_nodsh && skip "remote OST with nodsh"
12182
12183         reset_async
12184
12185         #define OBD_FAIL_SRV_ENOENT 0x217
12186         set_nodes_failloc "$(osts_nodes)" 0x217
12187         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12188         RC=$?
12189         set_nodes_failloc "$(osts_nodes)" 0
12190         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12191         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12192                     grep -c writeback)
12193
12194         if [[ $RC -eq 0 ]]; then
12195                 error "Must return error due to dropped pages, rc=$RC"
12196                 return 1;
12197         fi
12198
12199         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12200                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12201                 return 1;
12202         fi
12203
12204         echo "Dirty pages not leaked on ENOENT"
12205
12206         # Due to the above error the OSC will issue all RPCs syncronously
12207         # until a subsequent RPC completes successfully without error.
12208         $MULTIOP $DIR/$tfile Ow4096yc
12209         rm -f $DIR/$tfile
12210
12211         return 0
12212 }
12213 run_test 118b "Reclaim dirty pages on fatal error =========="
12214
12215 test_118c()
12216 {
12217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12218
12219         # for 118c, restore the original resend count, LU-1940
12220         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12221                                 set_resend_count $OLD_RESENDCOUNT
12222         remote_ost_nodsh && skip "remote OST with nodsh"
12223
12224         reset_async
12225
12226         #define OBD_FAIL_OST_EROFS               0x216
12227         set_nodes_failloc "$(osts_nodes)" 0x216
12228
12229         # multiop should block due to fsync until pages are written
12230         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12231         MULTIPID=$!
12232         sleep 1
12233
12234         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12235                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12236         fi
12237
12238         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12239                     grep -c writeback)
12240         if [[ $WRITEBACK -eq 0 ]]; then
12241                 error "No page in writeback, writeback=$WRITEBACK"
12242         fi
12243
12244         set_nodes_failloc "$(osts_nodes)" 0
12245         wait $MULTIPID
12246         RC=$?
12247         if [[ $RC -ne 0 ]]; then
12248                 error "Multiop fsync failed, rc=$RC"
12249         fi
12250
12251         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12252         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12253                     grep -c writeback)
12254         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12255                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12256         fi
12257
12258         rm -f $DIR/$tfile
12259         echo "Dirty pages flushed via fsync on EROFS"
12260         return 0
12261 }
12262 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12263
12264 # continue to use small resend count to reduce test_118* time (b=14842)
12265 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12266
12267 test_118d()
12268 {
12269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12270         remote_ost_nodsh && skip "remote OST with nodsh"
12271
12272         reset_async
12273
12274         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12275         set_nodes_failloc "$(osts_nodes)" 0x214
12276         # multiop should block due to fsync until pages are written
12277         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12278         MULTIPID=$!
12279         sleep 1
12280
12281         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12282                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12283         fi
12284
12285         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12286                     grep -c writeback)
12287         if [[ $WRITEBACK -eq 0 ]]; then
12288                 error "No page in writeback, writeback=$WRITEBACK"
12289         fi
12290
12291         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12292         set_nodes_failloc "$(osts_nodes)" 0
12293
12294         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12295         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12296                     grep -c writeback)
12297         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12298                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12299         fi
12300
12301         rm -f $DIR/$tfile
12302         echo "Dirty pages gaurenteed flushed via fsync"
12303         return 0
12304 }
12305 run_test 118d "Fsync validation inject a delay of the bulk =========="
12306
12307 test_118f() {
12308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12309
12310         reset_async
12311
12312         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12313         lctl set_param fail_loc=0x8000040a
12314
12315         # Should simulate EINVAL error which is fatal
12316         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12317         RC=$?
12318         if [[ $RC -eq 0 ]]; then
12319                 error "Must return error due to dropped pages, rc=$RC"
12320         fi
12321
12322         lctl set_param fail_loc=0x0
12323
12324         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12325         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12326         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12327                     grep -c writeback)
12328         if [[ $LOCKED -ne 0 ]]; then
12329                 error "Locked pages remain in cache, locked=$LOCKED"
12330         fi
12331
12332         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12333                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12334         fi
12335
12336         rm -f $DIR/$tfile
12337         echo "No pages locked after fsync"
12338
12339         reset_async
12340         return 0
12341 }
12342 run_test 118f "Simulate unrecoverable OSC side error =========="
12343
12344 test_118g() {
12345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12346
12347         reset_async
12348
12349         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12350         lctl set_param fail_loc=0x406
12351
12352         # simulate local -ENOMEM
12353         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12354         RC=$?
12355
12356         lctl set_param fail_loc=0
12357         if [[ $RC -eq 0 ]]; then
12358                 error "Must return error due to dropped pages, rc=$RC"
12359         fi
12360
12361         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12362         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12363         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12364                         grep -c writeback)
12365         if [[ $LOCKED -ne 0 ]]; then
12366                 error "Locked pages remain in cache, locked=$LOCKED"
12367         fi
12368
12369         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12370                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12371         fi
12372
12373         rm -f $DIR/$tfile
12374         echo "No pages locked after fsync"
12375
12376         reset_async
12377         return 0
12378 }
12379 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12380
12381 test_118h() {
12382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12383         remote_ost_nodsh && skip "remote OST with nodsh"
12384
12385         reset_async
12386
12387         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12388         set_nodes_failloc "$(osts_nodes)" 0x20e
12389         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12390         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12391         RC=$?
12392
12393         set_nodes_failloc "$(osts_nodes)" 0
12394         if [[ $RC -eq 0 ]]; then
12395                 error "Must return error due to dropped pages, rc=$RC"
12396         fi
12397
12398         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12399         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12400         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12401                     grep -c writeback)
12402         if [[ $LOCKED -ne 0 ]]; then
12403                 error "Locked pages remain in cache, locked=$LOCKED"
12404         fi
12405
12406         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12407                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12408         fi
12409
12410         rm -f $DIR/$tfile
12411         echo "No pages locked after fsync"
12412
12413         return 0
12414 }
12415 run_test 118h "Verify timeout in handling recoverables errors  =========="
12416
12417 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12418
12419 test_118i() {
12420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12421         remote_ost_nodsh && skip "remote OST with nodsh"
12422
12423         reset_async
12424
12425         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12426         set_nodes_failloc "$(osts_nodes)" 0x20e
12427
12428         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12429         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12430         PID=$!
12431         sleep 5
12432         set_nodes_failloc "$(osts_nodes)" 0
12433
12434         wait $PID
12435         RC=$?
12436         if [[ $RC -ne 0 ]]; then
12437                 error "got error, but should be not, rc=$RC"
12438         fi
12439
12440         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12441         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12442         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12443         if [[ $LOCKED -ne 0 ]]; then
12444                 error "Locked pages remain in cache, locked=$LOCKED"
12445         fi
12446
12447         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12448                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12449         fi
12450
12451         rm -f $DIR/$tfile
12452         echo "No pages locked after fsync"
12453
12454         return 0
12455 }
12456 run_test 118i "Fix error before timeout in recoverable error  =========="
12457
12458 [ "$SLOW" = "no" ] && set_resend_count 4
12459
12460 test_118j() {
12461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12462         remote_ost_nodsh && skip "remote OST with nodsh"
12463
12464         reset_async
12465
12466         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12467         set_nodes_failloc "$(osts_nodes)" 0x220
12468
12469         # return -EIO from OST
12470         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12471         RC=$?
12472         set_nodes_failloc "$(osts_nodes)" 0x0
12473         if [[ $RC -eq 0 ]]; then
12474                 error "Must return error due to dropped pages, rc=$RC"
12475         fi
12476
12477         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12478         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12479         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12480         if [[ $LOCKED -ne 0 ]]; then
12481                 error "Locked pages remain in cache, locked=$LOCKED"
12482         fi
12483
12484         # in recoverable error on OST we want resend and stay until it finished
12485         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12486                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12487         fi
12488
12489         rm -f $DIR/$tfile
12490         echo "No pages locked after fsync"
12491
12492         return 0
12493 }
12494 run_test 118j "Simulate unrecoverable OST side error =========="
12495
12496 test_118k()
12497 {
12498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12499         remote_ost_nodsh && skip "remote OSTs with nodsh"
12500
12501         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12502         set_nodes_failloc "$(osts_nodes)" 0x20e
12503         test_mkdir $DIR/$tdir
12504
12505         for ((i=0;i<10;i++)); do
12506                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12507                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12508                 SLEEPPID=$!
12509                 sleep 0.500s
12510                 kill $SLEEPPID
12511                 wait $SLEEPPID
12512         done
12513
12514         set_nodes_failloc "$(osts_nodes)" 0
12515         rm -rf $DIR/$tdir
12516 }
12517 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12518
12519 test_118l() # LU-646
12520 {
12521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12522
12523         test_mkdir $DIR/$tdir
12524         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12525         rm -rf $DIR/$tdir
12526 }
12527 run_test 118l "fsync dir"
12528
12529 test_118m() # LU-3066
12530 {
12531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12532
12533         test_mkdir $DIR/$tdir
12534         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12535         rm -rf $DIR/$tdir
12536 }
12537 run_test 118m "fdatasync dir ========="
12538
12539 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12540
12541 test_118n()
12542 {
12543         local begin
12544         local end
12545
12546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12547         remote_ost_nodsh && skip "remote OSTs with nodsh"
12548
12549         # Sleep to avoid a cached response.
12550         #define OBD_STATFS_CACHE_SECONDS 1
12551         sleep 2
12552
12553         # Inject a 10 second delay in the OST_STATFS handler.
12554         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12555         set_nodes_failloc "$(osts_nodes)" 0x242
12556
12557         begin=$SECONDS
12558         stat --file-system $MOUNT > /dev/null
12559         end=$SECONDS
12560
12561         set_nodes_failloc "$(osts_nodes)" 0
12562
12563         if ((end - begin > 20)); then
12564             error "statfs took $((end - begin)) seconds, expected 10"
12565         fi
12566 }
12567 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12568
12569 test_119a() # bug 11737
12570 {
12571         BSIZE=$((512 * 1024))
12572         directio write $DIR/$tfile 0 1 $BSIZE
12573         # We ask to read two blocks, which is more than a file size.
12574         # directio will indicate an error when requested and actual
12575         # sizes aren't equeal (a normal situation in this case) and
12576         # print actual read amount.
12577         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12578         if [ "$NOB" != "$BSIZE" ]; then
12579                 error "read $NOB bytes instead of $BSIZE"
12580         fi
12581         rm -f $DIR/$tfile
12582 }
12583 run_test 119a "Short directIO read must return actual read amount"
12584
12585 test_119b() # bug 11737
12586 {
12587         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12588
12589         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12590         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12591         sync
12592         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12593                 error "direct read failed"
12594         rm -f $DIR/$tfile
12595 }
12596 run_test 119b "Sparse directIO read must return actual read amount"
12597
12598 test_119c() # bug 13099
12599 {
12600         BSIZE=1048576
12601         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12602         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12603         rm -f $DIR/$tfile
12604 }
12605 run_test 119c "Testing for direct read hitting hole"
12606
12607 test_119d() # bug 15950
12608 {
12609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12610
12611         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12612         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12613         BSIZE=1048576
12614         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12615         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12616         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12617         lctl set_param fail_loc=0x40d
12618         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12619         pid_dio=$!
12620         sleep 1
12621         cat $DIR/$tfile > /dev/null &
12622         lctl set_param fail_loc=0
12623         pid_reads=$!
12624         wait $pid_dio
12625         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12626         sleep 2
12627         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12628         error "the read rpcs have not completed in 2s"
12629         rm -f $DIR/$tfile
12630         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12631 }
12632 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12633
12634 test_120a() {
12635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12636         remote_mds_nodsh && skip "remote MDS with nodsh"
12637         test_mkdir -i0 -c1 $DIR/$tdir
12638         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12639                 skip_env "no early lock cancel on server"
12640
12641         lru_resize_disable mdc
12642         lru_resize_disable osc
12643         cancel_lru_locks mdc
12644         # asynchronous object destroy at MDT could cause bl ast to client
12645         cancel_lru_locks osc
12646
12647         stat $DIR/$tdir > /dev/null
12648         can1=$(do_facet mds1 \
12649                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12650                awk '/ldlm_cancel/ {print $2}')
12651         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12652                awk '/ldlm_bl_callback/ {print $2}')
12653         test_mkdir -i0 -c1 $DIR/$tdir/d1
12654         can2=$(do_facet mds1 \
12655                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12656                awk '/ldlm_cancel/ {print $2}')
12657         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12658                awk '/ldlm_bl_callback/ {print $2}')
12659         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12660         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12661         lru_resize_enable mdc
12662         lru_resize_enable osc
12663 }
12664 run_test 120a "Early Lock Cancel: mkdir test"
12665
12666 test_120b() {
12667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12668         remote_mds_nodsh && skip "remote MDS with nodsh"
12669         test_mkdir $DIR/$tdir
12670         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12671                 skip_env "no early lock cancel on server"
12672
12673         lru_resize_disable mdc
12674         lru_resize_disable osc
12675         cancel_lru_locks mdc
12676         stat $DIR/$tdir > /dev/null
12677         can1=$(do_facet $SINGLEMDS \
12678                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12679                awk '/ldlm_cancel/ {print $2}')
12680         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12681                awk '/ldlm_bl_callback/ {print $2}')
12682         touch $DIR/$tdir/f1
12683         can2=$(do_facet $SINGLEMDS \
12684                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12685                awk '/ldlm_cancel/ {print $2}')
12686         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12687                awk '/ldlm_bl_callback/ {print $2}')
12688         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12689         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12690         lru_resize_enable mdc
12691         lru_resize_enable osc
12692 }
12693 run_test 120b "Early Lock Cancel: create test"
12694
12695 test_120c() {
12696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12697         remote_mds_nodsh && skip "remote MDS with nodsh"
12698         test_mkdir -i0 -c1 $DIR/$tdir
12699         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12700                 skip "no early lock cancel on server"
12701
12702         lru_resize_disable mdc
12703         lru_resize_disable osc
12704         test_mkdir -i0 -c1 $DIR/$tdir/d1
12705         test_mkdir -i0 -c1 $DIR/$tdir/d2
12706         touch $DIR/$tdir/d1/f1
12707         cancel_lru_locks mdc
12708         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12709         can1=$(do_facet mds1 \
12710                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12711                awk '/ldlm_cancel/ {print $2}')
12712         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12713                awk '/ldlm_bl_callback/ {print $2}')
12714         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12715         can2=$(do_facet mds1 \
12716                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12717                awk '/ldlm_cancel/ {print $2}')
12718         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12719                awk '/ldlm_bl_callback/ {print $2}')
12720         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12721         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12722         lru_resize_enable mdc
12723         lru_resize_enable osc
12724 }
12725 run_test 120c "Early Lock Cancel: link test"
12726
12727 test_120d() {
12728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12729         remote_mds_nodsh && skip "remote MDS with nodsh"
12730         test_mkdir -i0 -c1 $DIR/$tdir
12731         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12732                 skip_env "no early lock cancel on server"
12733
12734         lru_resize_disable mdc
12735         lru_resize_disable osc
12736         touch $DIR/$tdir
12737         cancel_lru_locks mdc
12738         stat $DIR/$tdir > /dev/null
12739         can1=$(do_facet mds1 \
12740                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12741                awk '/ldlm_cancel/ {print $2}')
12742         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12743                awk '/ldlm_bl_callback/ {print $2}')
12744         chmod a+x $DIR/$tdir
12745         can2=$(do_facet mds1 \
12746                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12747                awk '/ldlm_cancel/ {print $2}')
12748         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12749                awk '/ldlm_bl_callback/ {print $2}')
12750         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12751         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12752         lru_resize_enable mdc
12753         lru_resize_enable osc
12754 }
12755 run_test 120d "Early Lock Cancel: setattr test"
12756
12757 test_120e() {
12758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12759         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12760                 skip_env "no early lock cancel on server"
12761         remote_mds_nodsh && skip "remote MDS with nodsh"
12762
12763         local dlmtrace_set=false
12764
12765         test_mkdir -i0 -c1 $DIR/$tdir
12766         lru_resize_disable mdc
12767         lru_resize_disable osc
12768         ! $LCTL get_param debug | grep -q dlmtrace &&
12769                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12770         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12771         cancel_lru_locks mdc
12772         cancel_lru_locks osc
12773         dd if=$DIR/$tdir/f1 of=/dev/null
12774         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12775         # XXX client can not do early lock cancel of OST lock
12776         # during unlink (LU-4206), so cancel osc lock now.
12777         sleep 2
12778         cancel_lru_locks osc
12779         can1=$(do_facet mds1 \
12780                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12781                awk '/ldlm_cancel/ {print $2}')
12782         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12783                awk '/ldlm_bl_callback/ {print $2}')
12784         unlink $DIR/$tdir/f1
12785         sleep 5
12786         can2=$(do_facet mds1 \
12787                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12788                awk '/ldlm_cancel/ {print $2}')
12789         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12790                awk '/ldlm_bl_callback/ {print $2}')
12791         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12792                 $LCTL dk $TMP/cancel.debug.txt
12793         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12794                 $LCTL dk $TMP/blocking.debug.txt
12795         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12796         lru_resize_enable mdc
12797         lru_resize_enable osc
12798 }
12799 run_test 120e "Early Lock Cancel: unlink test"
12800
12801 test_120f() {
12802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12803         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12804                 skip_env "no early lock cancel on server"
12805         remote_mds_nodsh && skip "remote MDS with nodsh"
12806
12807         test_mkdir -i0 -c1 $DIR/$tdir
12808         lru_resize_disable mdc
12809         lru_resize_disable osc
12810         test_mkdir -i0 -c1 $DIR/$tdir/d1
12811         test_mkdir -i0 -c1 $DIR/$tdir/d2
12812         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12813         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12814         cancel_lru_locks mdc
12815         cancel_lru_locks osc
12816         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12817         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12818         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12819         # XXX client can not do early lock cancel of OST lock
12820         # during rename (LU-4206), so cancel osc lock now.
12821         sleep 2
12822         cancel_lru_locks osc
12823         can1=$(do_facet mds1 \
12824                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12825                awk '/ldlm_cancel/ {print $2}')
12826         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12827                awk '/ldlm_bl_callback/ {print $2}')
12828         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12829         sleep 5
12830         can2=$(do_facet mds1 \
12831                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12832                awk '/ldlm_cancel/ {print $2}')
12833         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12834                awk '/ldlm_bl_callback/ {print $2}')
12835         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12836         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12837         lru_resize_enable mdc
12838         lru_resize_enable osc
12839 }
12840 run_test 120f "Early Lock Cancel: rename test"
12841
12842 test_120g() {
12843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12844         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12845                 skip_env "no early lock cancel on server"
12846         remote_mds_nodsh && skip "remote MDS with nodsh"
12847
12848         lru_resize_disable mdc
12849         lru_resize_disable osc
12850         count=10000
12851         echo create $count files
12852         test_mkdir $DIR/$tdir
12853         cancel_lru_locks mdc
12854         cancel_lru_locks osc
12855         t0=$(date +%s)
12856
12857         can0=$(do_facet $SINGLEMDS \
12858                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12859                awk '/ldlm_cancel/ {print $2}')
12860         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12861                awk '/ldlm_bl_callback/ {print $2}')
12862         createmany -o $DIR/$tdir/f $count
12863         sync
12864         can1=$(do_facet $SINGLEMDS \
12865                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12866                awk '/ldlm_cancel/ {print $2}')
12867         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12868                awk '/ldlm_bl_callback/ {print $2}')
12869         t1=$(date +%s)
12870         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12871         echo rm $count files
12872         rm -r $DIR/$tdir
12873         sync
12874         can2=$(do_facet $SINGLEMDS \
12875                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12876                awk '/ldlm_cancel/ {print $2}')
12877         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12878                awk '/ldlm_bl_callback/ {print $2}')
12879         t2=$(date +%s)
12880         echo total: $count removes in $((t2-t1))
12881         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12882         sleep 2
12883         # wait for commitment of removal
12884         lru_resize_enable mdc
12885         lru_resize_enable osc
12886 }
12887 run_test 120g "Early Lock Cancel: performance test"
12888
12889 test_121() { #bug #10589
12890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12891
12892         rm -rf $DIR/$tfile
12893         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12894 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12895         lctl set_param fail_loc=0x310
12896         cancel_lru_locks osc > /dev/null
12897         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12898         lctl set_param fail_loc=0
12899         [[ $reads -eq $writes ]] ||
12900                 error "read $reads blocks, must be $writes blocks"
12901 }
12902 run_test 121 "read cancel race ========="
12903
12904 test_123a_base() { # was test 123, statahead(bug 11401)
12905         local lsx="$1"
12906
12907         SLOWOK=0
12908         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12909                 log "testing UP system. Performance may be lower than expected."
12910                 SLOWOK=1
12911         fi
12912
12913         rm -rf $DIR/$tdir
12914         test_mkdir $DIR/$tdir
12915         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12916         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12917         MULT=10
12918         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12919                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12920
12921                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12922                 lctl set_param -n llite.*.statahead_max 0
12923                 lctl get_param llite.*.statahead_max
12924                 cancel_lru_locks mdc
12925                 cancel_lru_locks osc
12926                 stime=$(date +%s)
12927                 time $lsx $DIR/$tdir | wc -l
12928                 etime=$(date +%s)
12929                 delta=$((etime - stime))
12930                 log "$lsx $i files without statahead: $delta sec"
12931                 lctl set_param llite.*.statahead_max=$max
12932
12933                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12934                         grep "statahead wrong:" | awk '{print $3}')
12935                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12936                 cancel_lru_locks mdc
12937                 cancel_lru_locks osc
12938                 stime=$(date +%s)
12939                 time $lsx $DIR/$tdir | wc -l
12940                 etime=$(date +%s)
12941                 delta_sa=$((etime - stime))
12942                 log "$lsx $i files with statahead: $delta_sa sec"
12943                 lctl get_param -n llite.*.statahead_stats
12944                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12945                         grep "statahead wrong:" | awk '{print $3}')
12946
12947                 [[ $swrong -lt $ewrong ]] &&
12948                         log "statahead was stopped, maybe too many locks held!"
12949                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12950
12951                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12952                         max=$(lctl get_param -n llite.*.statahead_max |
12953                                 head -n 1)
12954                         lctl set_param -n llite.*.statahead_max 0
12955                         lctl get_param llite.*.statahead_max
12956                         cancel_lru_locks mdc
12957                         cancel_lru_locks osc
12958                         stime=$(date +%s)
12959                         time $lsx $DIR/$tdir | wc -l
12960                         etime=$(date +%s)
12961                         delta=$((etime - stime))
12962                         log "$lsx $i files again without statahead: $delta sec"
12963                         lctl set_param llite.*.statahead_max=$max
12964                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12965                                 if [  $SLOWOK -eq 0 ]; then
12966                                         error "$lsx $i files is slower with statahead!"
12967                                 else
12968                                         log "$lsx $i files is slower with statahead!"
12969                                 fi
12970                                 break
12971                         fi
12972                 fi
12973
12974                 [ $delta -gt 20 ] && break
12975                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12976                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12977         done
12978         log "$lsx done"
12979
12980         stime=$(date +%s)
12981         rm -r $DIR/$tdir
12982         sync
12983         etime=$(date +%s)
12984         delta=$((etime - stime))
12985         log "rm -r $DIR/$tdir/: $delta seconds"
12986         log "rm done"
12987         lctl get_param -n llite.*.statahead_stats
12988 }
12989
12990 test_123aa() {
12991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12992
12993         test_123a_base "ls -l"
12994 }
12995 run_test 123aa "verify statahead work"
12996
12997 test_123ab() {
12998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12999
13000         statx_supported || skip_env "Test must be statx() syscall supported"
13001
13002         test_123a_base "$STATX -l"
13003 }
13004 run_test 123ab "verify statahead work by using statx"
13005
13006 test_123ac() {
13007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13008
13009         statx_supported || skip_env "Test must be statx() syscall supported"
13010
13011         local rpcs_before
13012         local rpcs_after
13013         local agl_before
13014         local agl_after
13015
13016         cancel_lru_locks $OSC
13017         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13018         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13019                 awk '/agl.total:/ {print $3}')
13020         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13021         test_123a_base "$STATX --cached=always -D"
13022         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13023                 awk '/agl.total:/ {print $3}')
13024         [ $agl_before -eq $agl_after ] ||
13025                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13026         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13027         [ $rpcs_after -eq $rpcs_before ] ||
13028                 error "$STATX should not send glimpse RPCs to $OSC"
13029 }
13030 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13031
13032 test_123b () { # statahead(bug 15027)
13033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13034
13035         test_mkdir $DIR/$tdir
13036         createmany -o $DIR/$tdir/$tfile-%d 1000
13037
13038         cancel_lru_locks mdc
13039         cancel_lru_locks osc
13040
13041 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13042         lctl set_param fail_loc=0x80000803
13043         ls -lR $DIR/$tdir > /dev/null
13044         log "ls done"
13045         lctl set_param fail_loc=0x0
13046         lctl get_param -n llite.*.statahead_stats
13047         rm -r $DIR/$tdir
13048         sync
13049
13050 }
13051 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13052
13053 test_123c() {
13054         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13055
13056         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13057         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13058         touch $DIR/$tdir.1/{1..3}
13059         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13060
13061         remount_client $MOUNT
13062
13063         $MULTIOP $DIR/$tdir.0 Q
13064
13065         # let statahead to complete
13066         ls -l $DIR/$tdir.0 > /dev/null
13067
13068         testid=$(echo $TESTNAME | tr '_' ' ')
13069         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13070                 error "statahead warning" || true
13071 }
13072 run_test 123c "Can not initialize inode warning on DNE statahead"
13073
13074 test_124a() {
13075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13076         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13077                 skip_env "no lru resize on server"
13078
13079         local NR=2000
13080
13081         test_mkdir $DIR/$tdir
13082
13083         log "create $NR files at $DIR/$tdir"
13084         createmany -o $DIR/$tdir/f $NR ||
13085                 error "failed to create $NR files in $DIR/$tdir"
13086
13087         cancel_lru_locks mdc
13088         ls -l $DIR/$tdir > /dev/null
13089
13090         local NSDIR=""
13091         local LRU_SIZE=0
13092         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13093                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13094                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13095                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13096                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13097                         log "NSDIR=$NSDIR"
13098                         log "NS=$(basename $NSDIR)"
13099                         break
13100                 fi
13101         done
13102
13103         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13104                 skip "Not enough cached locks created!"
13105         fi
13106         log "LRU=$LRU_SIZE"
13107
13108         local SLEEP=30
13109
13110         # We know that lru resize allows one client to hold $LIMIT locks
13111         # for 10h. After that locks begin to be killed by client.
13112         local MAX_HRS=10
13113         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13114         log "LIMIT=$LIMIT"
13115         if [ $LIMIT -lt $LRU_SIZE ]; then
13116                 skip "Limit is too small $LIMIT"
13117         fi
13118
13119         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13120         # killing locks. Some time was spent for creating locks. This means
13121         # that up to the moment of sleep finish we must have killed some of
13122         # them (10-100 locks). This depends on how fast ther were created.
13123         # Many of them were touched in almost the same moment and thus will
13124         # be killed in groups.
13125         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13126
13127         # Use $LRU_SIZE_B here to take into account real number of locks
13128         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13129         local LRU_SIZE_B=$LRU_SIZE
13130         log "LVF=$LVF"
13131         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13132         log "OLD_LVF=$OLD_LVF"
13133         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13134
13135         # Let's make sure that we really have some margin. Client checks
13136         # cached locks every 10 sec.
13137         SLEEP=$((SLEEP+20))
13138         log "Sleep ${SLEEP} sec"
13139         local SEC=0
13140         while ((SEC<$SLEEP)); do
13141                 echo -n "..."
13142                 sleep 5
13143                 SEC=$((SEC+5))
13144                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13145                 echo -n "$LRU_SIZE"
13146         done
13147         echo ""
13148         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13149         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13150
13151         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13152                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13153                 unlinkmany $DIR/$tdir/f $NR
13154                 return
13155         }
13156
13157         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13158         log "unlink $NR files at $DIR/$tdir"
13159         unlinkmany $DIR/$tdir/f $NR
13160 }
13161 run_test 124a "lru resize ======================================="
13162
13163 get_max_pool_limit()
13164 {
13165         local limit=$($LCTL get_param \
13166                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13167         local max=0
13168         for l in $limit; do
13169                 if [[ $l -gt $max ]]; then
13170                         max=$l
13171                 fi
13172         done
13173         echo $max
13174 }
13175
13176 test_124b() {
13177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13178         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13179                 skip_env "no lru resize on server"
13180
13181         LIMIT=$(get_max_pool_limit)
13182
13183         NR=$(($(default_lru_size)*20))
13184         if [[ $NR -gt $LIMIT ]]; then
13185                 log "Limit lock number by $LIMIT locks"
13186                 NR=$LIMIT
13187         fi
13188
13189         IFree=$(mdsrate_inodes_available)
13190         if [ $IFree -lt $NR ]; then
13191                 log "Limit lock number by $IFree inodes"
13192                 NR=$IFree
13193         fi
13194
13195         lru_resize_disable mdc
13196         test_mkdir -p $DIR/$tdir/disable_lru_resize
13197
13198         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13199         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13200         cancel_lru_locks mdc
13201         stime=`date +%s`
13202         PID=""
13203         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13204         PID="$PID $!"
13205         sleep 2
13206         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13207         PID="$PID $!"
13208         sleep 2
13209         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13210         PID="$PID $!"
13211         wait $PID
13212         etime=`date +%s`
13213         nolruresize_delta=$((etime-stime))
13214         log "ls -la time: $nolruresize_delta seconds"
13215         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13216         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13217
13218         lru_resize_enable mdc
13219         test_mkdir -p $DIR/$tdir/enable_lru_resize
13220
13221         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13222         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13223         cancel_lru_locks mdc
13224         stime=`date +%s`
13225         PID=""
13226         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13227         PID="$PID $!"
13228         sleep 2
13229         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13230         PID="$PID $!"
13231         sleep 2
13232         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13233         PID="$PID $!"
13234         wait $PID
13235         etime=`date +%s`
13236         lruresize_delta=$((etime-stime))
13237         log "ls -la time: $lruresize_delta seconds"
13238         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13239
13240         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13241                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13242         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13243                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13244         else
13245                 log "lru resize performs the same with no lru resize"
13246         fi
13247         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13248 }
13249 run_test 124b "lru resize (performance test) ======================="
13250
13251 test_124c() {
13252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13253         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13254                 skip_env "no lru resize on server"
13255
13256         # cache ununsed locks on client
13257         local nr=100
13258         cancel_lru_locks mdc
13259         test_mkdir $DIR/$tdir
13260         createmany -o $DIR/$tdir/f $nr ||
13261                 error "failed to create $nr files in $DIR/$tdir"
13262         ls -l $DIR/$tdir > /dev/null
13263
13264         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13265         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13266         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13267         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13268         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13269
13270         # set lru_max_age to 1 sec
13271         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13272         echo "sleep $((recalc_p * 2)) seconds..."
13273         sleep $((recalc_p * 2))
13274
13275         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13276         # restore lru_max_age
13277         $LCTL set_param -n $nsdir.lru_max_age $max_age
13278         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13279         unlinkmany $DIR/$tdir/f $nr
13280 }
13281 run_test 124c "LRUR cancel very aged locks"
13282
13283 test_124d() {
13284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13285         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13286                 skip_env "no lru resize on server"
13287
13288         # cache ununsed locks on client
13289         local nr=100
13290
13291         lru_resize_disable mdc
13292         stack_trap "lru_resize_enable mdc" EXIT
13293
13294         cancel_lru_locks mdc
13295
13296         # asynchronous object destroy at MDT could cause bl ast to client
13297         test_mkdir $DIR/$tdir
13298         createmany -o $DIR/$tdir/f $nr ||
13299                 error "failed to create $nr files in $DIR/$tdir"
13300         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13301
13302         ls -l $DIR/$tdir > /dev/null
13303
13304         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13305         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13306         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13307         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13308
13309         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13310
13311         # set lru_max_age to 1 sec
13312         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13313         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13314
13315         echo "sleep $((recalc_p * 2)) seconds..."
13316         sleep $((recalc_p * 2))
13317
13318         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13319
13320         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13321 }
13322 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13323
13324 test_125() { # 13358
13325         $LCTL get_param -n llite.*.client_type | grep -q local ||
13326                 skip "must run as local client"
13327         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13328                 skip_env "must have acl enabled"
13329         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13330
13331         test_mkdir $DIR/$tdir
13332         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13333         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13334         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13335 }
13336 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13337
13338 test_126() { # bug 12829/13455
13339         $GSS && skip_env "must run as gss disabled"
13340         $LCTL get_param -n llite.*.client_type | grep -q local ||
13341                 skip "must run as local client"
13342         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13343
13344         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13345         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13346         rm -f $DIR/$tfile
13347         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13348 }
13349 run_test 126 "check that the fsgid provided by the client is taken into account"
13350
13351 test_127a() { # bug 15521
13352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13353         local name count samp unit min max sum sumsq
13354
13355         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13356         echo "stats before reset"
13357         $LCTL get_param osc.*.stats
13358         $LCTL set_param osc.*.stats=0
13359         local fsize=$((2048 * 1024))
13360
13361         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13362         cancel_lru_locks osc
13363         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13364
13365         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13366         stack_trap "rm -f $TMP/$tfile.tmp"
13367         while read name count samp unit min max sum sumsq; do
13368                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13369                 [ ! $min ] && error "Missing min value for $name proc entry"
13370                 eval $name=$count || error "Wrong proc format"
13371
13372                 case $name in
13373                 read_bytes|write_bytes)
13374                         [[ "$unit" =~ "bytes" ]] ||
13375                                 error "unit is not 'bytes': $unit"
13376                         (( $min >= 4096 )) || error "min is too small: $min"
13377                         (( $min <= $fsize )) || error "min is too big: $min"
13378                         (( $max >= 4096 )) || error "max is too small: $max"
13379                         (( $max <= $fsize )) || error "max is too big: $max"
13380                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13381                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13382                                 error "sumsquare is too small: $sumsq"
13383                         (( $sumsq <= $fsize * $fsize )) ||
13384                                 error "sumsquare is too big: $sumsq"
13385                         ;;
13386                 ost_read|ost_write)
13387                         [[ "$unit" =~ "usec" ]] ||
13388                                 error "unit is not 'usec': $unit"
13389                         ;;
13390                 *)      ;;
13391                 esac
13392         done < $DIR/$tfile.tmp
13393
13394         #check that we actually got some stats
13395         [ "$read_bytes" ] || error "Missing read_bytes stats"
13396         [ "$write_bytes" ] || error "Missing write_bytes stats"
13397         [ "$read_bytes" != 0 ] || error "no read done"
13398         [ "$write_bytes" != 0 ] || error "no write done"
13399 }
13400 run_test 127a "verify the client stats are sane"
13401
13402 test_127b() { # bug LU-333
13403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13404         local name count samp unit min max sum sumsq
13405
13406         echo "stats before reset"
13407         $LCTL get_param llite.*.stats
13408         $LCTL set_param llite.*.stats=0
13409
13410         # perform 2 reads and writes so MAX is different from SUM.
13411         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13412         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13413         cancel_lru_locks osc
13414         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13415         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13416
13417         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13418         stack_trap "rm -f $TMP/$tfile.tmp"
13419         while read name count samp unit min max sum sumsq; do
13420                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13421                 eval $name=$count || error "Wrong proc format"
13422
13423                 case $name in
13424                 read_bytes|write_bytes)
13425                         [[ "$unit" =~ "bytes" ]] ||
13426                                 error "unit is not 'bytes': $unit"
13427                         (( $count == 2 )) || error "count is not 2: $count"
13428                         (( $min == $PAGE_SIZE )) ||
13429                                 error "min is not $PAGE_SIZE: $min"
13430                         (( $max == $PAGE_SIZE )) ||
13431                                 error "max is not $PAGE_SIZE: $max"
13432                         (( $sum == $PAGE_SIZE * 2 )) ||
13433                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13434                         ;;
13435                 read|write)
13436                         [[ "$unit" =~ "usec" ]] ||
13437                                 error "unit is not 'usec': $unit"
13438                         ;;
13439                 *)      ;;
13440                 esac
13441         done < $TMP/$tfile.tmp
13442
13443         #check that we actually got some stats
13444         [ "$read_bytes" ] || error "Missing read_bytes stats"
13445         [ "$write_bytes" ] || error "Missing write_bytes stats"
13446         [ "$read_bytes" != 0 ] || error "no read done"
13447         [ "$write_bytes" != 0 ] || error "no write done"
13448 }
13449 run_test 127b "verify the llite client stats are sane"
13450
13451 test_127c() { # LU-12394
13452         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13453         local size
13454         local bsize
13455         local reads
13456         local writes
13457         local count
13458
13459         $LCTL set_param llite.*.extents_stats=1
13460         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13461
13462         # Use two stripes so there is enough space in default config
13463         $LFS setstripe -c 2 $DIR/$tfile
13464
13465         # Extent stats start at 0-4K and go in power of two buckets
13466         # LL_HIST_START = 12 --> 2^12 = 4K
13467         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13468         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13469         # small configs
13470         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13471                 do
13472                 # Write and read, 2x each, second time at a non-zero offset
13473                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13474                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13475                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13476                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13477                 rm -f $DIR/$tfile
13478         done
13479
13480         $LCTL get_param llite.*.extents_stats
13481
13482         count=2
13483         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13484                 do
13485                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13486                                 grep -m 1 $bsize)
13487                 reads=$(echo $bucket | awk '{print $5}')
13488                 writes=$(echo $bucket | awk '{print $9}')
13489                 [ "$reads" -eq $count ] ||
13490                         error "$reads reads in < $bsize bucket, expect $count"
13491                 [ "$writes" -eq $count ] ||
13492                         error "$writes writes in < $bsize bucket, expect $count"
13493         done
13494
13495         # Test mmap write and read
13496         $LCTL set_param llite.*.extents_stats=c
13497         size=512
13498         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13499         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13500         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13501
13502         $LCTL get_param llite.*.extents_stats
13503
13504         count=$(((size*1024) / PAGE_SIZE))
13505
13506         bsize=$((2 * PAGE_SIZE / 1024))K
13507
13508         bucket=$($LCTL get_param -n llite.*.extents_stats |
13509                         grep -m 1 $bsize)
13510         reads=$(echo $bucket | awk '{print $5}')
13511         writes=$(echo $bucket | awk '{print $9}')
13512         # mmap writes fault in the page first, creating an additonal read
13513         [ "$reads" -eq $((2 * count)) ] ||
13514                 error "$reads reads in < $bsize bucket, expect $count"
13515         [ "$writes" -eq $count ] ||
13516                 error "$writes writes in < $bsize bucket, expect $count"
13517 }
13518 run_test 127c "test llite extent stats with regular & mmap i/o"
13519
13520 test_128() { # bug 15212
13521         touch $DIR/$tfile
13522         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13523                 find $DIR/$tfile
13524                 find $DIR/$tfile
13525         EOF
13526
13527         result=$(grep error $TMP/$tfile.log)
13528         rm -f $DIR/$tfile $TMP/$tfile.log
13529         [ -z "$result" ] ||
13530                 error "consecutive find's under interactive lfs failed"
13531 }
13532 run_test 128 "interactive lfs for 2 consecutive find's"
13533
13534 set_dir_limits () {
13535         local mntdev
13536         local canondev
13537         local node
13538
13539         local ldproc=/proc/fs/ldiskfs
13540         local facets=$(get_facets MDS)
13541
13542         for facet in ${facets//,/ }; do
13543                 canondev=$(ldiskfs_canon \
13544                            *.$(convert_facet2label $facet).mntdev $facet)
13545                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13546                         ldproc=/sys/fs/ldiskfs
13547                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13548                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13549         done
13550 }
13551
13552 check_mds_dmesg() {
13553         local facets=$(get_facets MDS)
13554         for facet in ${facets//,/ }; do
13555                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13556         done
13557         return 1
13558 }
13559
13560 test_129() {
13561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13562         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13563                 skip "Need MDS version with at least 2.5.56"
13564         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13565                 skip_env "ldiskfs only test"
13566         fi
13567         remote_mds_nodsh && skip "remote MDS with nodsh"
13568
13569         local ENOSPC=28
13570         local has_warning=false
13571
13572         rm -rf $DIR/$tdir
13573         mkdir -p $DIR/$tdir
13574
13575         # block size of mds1
13576         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13577         set_dir_limits $maxsize $((maxsize * 6 / 8))
13578         stack_trap "set_dir_limits 0 0"
13579         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13580         local dirsize=$(stat -c%s "$DIR/$tdir")
13581         local nfiles=0
13582         while (( $dirsize <= $maxsize )); do
13583                 $MCREATE $DIR/$tdir/file_base_$nfiles
13584                 rc=$?
13585                 # check two errors:
13586                 # ENOSPC for ext4 max_dir_size, which has been used since
13587                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13588                 if (( rc == ENOSPC )); then
13589                         set_dir_limits 0 0
13590                         echo "rc=$rc returned as expected after $nfiles files"
13591
13592                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13593                                 error "create failed w/o dir size limit"
13594
13595                         # messages may be rate limited if test is run repeatedly
13596                         check_mds_dmesg '"is approaching max"' ||
13597                                 echo "warning message should be output"
13598                         check_mds_dmesg '"has reached max"' ||
13599                                 echo "reached message should be output"
13600
13601                         dirsize=$(stat -c%s "$DIR/$tdir")
13602
13603                         [[ $dirsize -ge $maxsize ]] && return 0
13604                         error "dirsize $dirsize < $maxsize after $nfiles files"
13605                 elif (( rc != 0 )); then
13606                         break
13607                 fi
13608                 nfiles=$((nfiles + 1))
13609                 dirsize=$(stat -c%s "$DIR/$tdir")
13610         done
13611
13612         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13613 }
13614 run_test 129 "test directory size limit ========================"
13615
13616 OLDIFS="$IFS"
13617 cleanup_130() {
13618         trap 0
13619         IFS="$OLDIFS"
13620 }
13621
13622 test_130a() {
13623         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13624         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13625
13626         trap cleanup_130 EXIT RETURN
13627
13628         local fm_file=$DIR/$tfile
13629         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13630         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13631                 error "dd failed for $fm_file"
13632
13633         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13634         filefrag -ves $fm_file
13635         RC=$?
13636         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13637                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13638         [ $RC != 0 ] && error "filefrag $fm_file failed"
13639
13640         filefrag_op=$(filefrag -ve -k $fm_file |
13641                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13642         lun=$($LFS getstripe -i $fm_file)
13643
13644         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13645         IFS=$'\n'
13646         tot_len=0
13647         for line in $filefrag_op
13648         do
13649                 frag_lun=`echo $line | cut -d: -f5`
13650                 ext_len=`echo $line | cut -d: -f4`
13651                 if (( $frag_lun != $lun )); then
13652                         cleanup_130
13653                         error "FIEMAP on 1-stripe file($fm_file) failed"
13654                         return
13655                 fi
13656                 (( tot_len += ext_len ))
13657         done
13658
13659         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13660                 cleanup_130
13661                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13662                 return
13663         fi
13664
13665         cleanup_130
13666
13667         echo "FIEMAP on single striped file succeeded"
13668 }
13669 run_test 130a "FIEMAP (1-stripe file)"
13670
13671 test_130b() {
13672         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13673
13674         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13675         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13676
13677         trap cleanup_130 EXIT RETURN
13678
13679         local fm_file=$DIR/$tfile
13680         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13681                         error "setstripe on $fm_file"
13682         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13683                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13684
13685         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13686                 error "dd failed on $fm_file"
13687
13688         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13689         filefrag_op=$(filefrag -ve -k $fm_file |
13690                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13691
13692         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13693                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13694
13695         IFS=$'\n'
13696         tot_len=0
13697         num_luns=1
13698         for line in $filefrag_op
13699         do
13700                 frag_lun=$(echo $line | cut -d: -f5 |
13701                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13702                 ext_len=$(echo $line | cut -d: -f4)
13703                 if (( $frag_lun != $last_lun )); then
13704                         if (( tot_len != 1024 )); then
13705                                 cleanup_130
13706                                 error "FIEMAP on $fm_file failed; returned " \
13707                                 "len $tot_len for OST $last_lun instead of 1024"
13708                                 return
13709                         else
13710                                 (( num_luns += 1 ))
13711                                 tot_len=0
13712                         fi
13713                 fi
13714                 (( tot_len += ext_len ))
13715                 last_lun=$frag_lun
13716         done
13717         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13718                 cleanup_130
13719                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13720                         "luns or wrong len for OST $last_lun"
13721                 return
13722         fi
13723
13724         cleanup_130
13725
13726         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13727 }
13728 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13729
13730 test_130c() {
13731         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13732
13733         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13734         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13735
13736         trap cleanup_130 EXIT RETURN
13737
13738         local fm_file=$DIR/$tfile
13739         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13740         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13741                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13742
13743         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13744                         error "dd failed on $fm_file"
13745
13746         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13747         filefrag_op=$(filefrag -ve -k $fm_file |
13748                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13749
13750         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13751                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13752
13753         IFS=$'\n'
13754         tot_len=0
13755         num_luns=1
13756         for line in $filefrag_op
13757         do
13758                 frag_lun=$(echo $line | cut -d: -f5 |
13759                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13760                 ext_len=$(echo $line | cut -d: -f4)
13761                 if (( $frag_lun != $last_lun )); then
13762                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13763                         if (( logical != 512 )); then
13764                                 cleanup_130
13765                                 error "FIEMAP on $fm_file failed; returned " \
13766                                 "logical start for lun $logical instead of 512"
13767                                 return
13768                         fi
13769                         if (( tot_len != 512 )); then
13770                                 cleanup_130
13771                                 error "FIEMAP on $fm_file failed; returned " \
13772                                 "len $tot_len for OST $last_lun instead of 1024"
13773                                 return
13774                         else
13775                                 (( num_luns += 1 ))
13776                                 tot_len=0
13777                         fi
13778                 fi
13779                 (( tot_len += ext_len ))
13780                 last_lun=$frag_lun
13781         done
13782         if (( num_luns != 2 || tot_len != 512 )); then
13783                 cleanup_130
13784                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13785                         "luns or wrong len for OST $last_lun"
13786                 return
13787         fi
13788
13789         cleanup_130
13790
13791         echo "FIEMAP on 2-stripe file with hole succeeded"
13792 }
13793 run_test 130c "FIEMAP (2-stripe file with hole)"
13794
13795 test_130d() {
13796         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13797
13798         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13799         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13800
13801         trap cleanup_130 EXIT RETURN
13802
13803         local fm_file=$DIR/$tfile
13804         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13805                         error "setstripe on $fm_file"
13806         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13807                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13808
13809         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13810         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13811                 error "dd failed on $fm_file"
13812
13813         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13814         filefrag_op=$(filefrag -ve -k $fm_file |
13815                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13816
13817         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13818                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13819
13820         IFS=$'\n'
13821         tot_len=0
13822         num_luns=1
13823         for line in $filefrag_op
13824         do
13825                 frag_lun=$(echo $line | cut -d: -f5 |
13826                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13827                 ext_len=$(echo $line | cut -d: -f4)
13828                 if (( $frag_lun != $last_lun )); then
13829                         if (( tot_len != 1024 )); then
13830                                 cleanup_130
13831                                 error "FIEMAP on $fm_file failed; returned " \
13832                                 "len $tot_len for OST $last_lun instead of 1024"
13833                                 return
13834                         else
13835                                 (( num_luns += 1 ))
13836                                 tot_len=0
13837                         fi
13838                 fi
13839                 (( tot_len += ext_len ))
13840                 last_lun=$frag_lun
13841         done
13842         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13843                 cleanup_130
13844                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13845                         "luns or wrong len for OST $last_lun"
13846                 return
13847         fi
13848
13849         cleanup_130
13850
13851         echo "FIEMAP on N-stripe file succeeded"
13852 }
13853 run_test 130d "FIEMAP (N-stripe file)"
13854
13855 test_130e() {
13856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13857
13858         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13859         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13860
13861         trap cleanup_130 EXIT RETURN
13862
13863         local fm_file=$DIR/$tfile
13864         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13865
13866         NUM_BLKS=512
13867         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13868         for ((i = 0; i < $NUM_BLKS; i++)); do
13869                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13870                         conv=notrunc > /dev/null 2>&1
13871         done
13872
13873         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13874         filefrag_op=$(filefrag -ve -k $fm_file |
13875                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13876
13877         last_lun=$(echo $filefrag_op | cut -d: -f5)
13878
13879         IFS=$'\n'
13880         tot_len=0
13881         num_luns=1
13882         for line in $filefrag_op; do
13883                 frag_lun=$(echo $line | cut -d: -f5)
13884                 ext_len=$(echo $line | cut -d: -f4)
13885                 if [[ "$frag_lun" != "$last_lun" ]]; then
13886                         if (( tot_len != $EXPECTED_LEN )); then
13887                                 cleanup_130
13888                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13889                         else
13890                                 (( num_luns += 1 ))
13891                                 tot_len=0
13892                         fi
13893                 fi
13894                 (( tot_len += ext_len ))
13895                 last_lun=$frag_lun
13896         done
13897         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13898                 cleanup_130
13899                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13900         fi
13901
13902         echo "FIEMAP with continuation calls succeeded"
13903 }
13904 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13905
13906 test_130f() {
13907         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13908         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13909
13910         local fm_file=$DIR/$tfile
13911         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13912                 error "multiop create with lov_delay_create on $fm_file"
13913
13914         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13915         filefrag_extents=$(filefrag -vek $fm_file |
13916                            awk '/extents? found/ { print $2 }')
13917         if [[ "$filefrag_extents" != "0" ]]; then
13918                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13919         fi
13920
13921         rm -f $fm_file
13922 }
13923 run_test 130f "FIEMAP (unstriped file)"
13924
13925 test_130g() {
13926         local file=$DIR/$tfile
13927         local nr=$((OSTCOUNT * 100))
13928
13929         $LFS setstripe -C $nr $file ||
13930                 error "failed to setstripe -C $nr $file"
13931
13932         dd if=/dev/zero of=$file count=$nr bs=1M
13933         sync
13934         nr=$($LFS getstripe -c $file)
13935
13936         local extents=$(filefrag -v $file |
13937                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13938
13939         echo "filefrag list $extents extents in file with stripecount $nr"
13940         if (( extents < nr )); then
13941                 $LFS getstripe $file
13942                 filefrag -v $file
13943                 error "filefrag printed $extents < $nr extents"
13944         fi
13945
13946         rm -f $file
13947 }
13948 run_test 130g "FIEMAP (overstripe file)"
13949
13950 # Test for writev/readv
13951 test_131a() {
13952         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13953                 error "writev test failed"
13954         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13955                 error "readv failed"
13956         rm -f $DIR/$tfile
13957 }
13958 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13959
13960 test_131b() {
13961         local fsize=$((524288 + 1048576 + 1572864))
13962         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13963                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13964                         error "append writev test failed"
13965
13966         ((fsize += 1572864 + 1048576))
13967         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13968                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13969                         error "append writev test failed"
13970         rm -f $DIR/$tfile
13971 }
13972 run_test 131b "test append writev"
13973
13974 test_131c() {
13975         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13976         error "NOT PASS"
13977 }
13978 run_test 131c "test read/write on file w/o objects"
13979
13980 test_131d() {
13981         rwv -f $DIR/$tfile -w -n 1 1572864
13982         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13983         if [ "$NOB" != 1572864 ]; then
13984                 error "Short read filed: read $NOB bytes instead of 1572864"
13985         fi
13986         rm -f $DIR/$tfile
13987 }
13988 run_test 131d "test short read"
13989
13990 test_131e() {
13991         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13992         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13993         error "read hitting hole failed"
13994         rm -f $DIR/$tfile
13995 }
13996 run_test 131e "test read hitting hole"
13997
13998 check_stats() {
13999         local facet=$1
14000         local op=$2
14001         local want=${3:-0}
14002         local res
14003
14004         case $facet in
14005         mds*) res=$(do_facet $facet \
14006                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
14007                  ;;
14008         ost*) res=$(do_facet $facet \
14009                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
14010                  ;;
14011         *) error "Wrong facet '$facet'" ;;
14012         esac
14013         [ "$res" ] || error "The counter for $op on $facet was not incremented"
14014         # if the argument $3 is zero, it means any stat increment is ok.
14015         if [[ $want -gt 0 ]]; then
14016                 local count=$(echo $res | awk '{ print $2 }')
14017                 [[ $count -ne $want ]] &&
14018                         error "The $op counter on $facet is $count, not $want"
14019         fi
14020 }
14021
14022 test_133a() {
14023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14024         remote_ost_nodsh && skip "remote OST with nodsh"
14025         remote_mds_nodsh && skip "remote MDS with nodsh"
14026         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14027                 skip_env "MDS doesn't support rename stats"
14028
14029         local testdir=$DIR/${tdir}/stats_testdir
14030
14031         mkdir -p $DIR/${tdir}
14032
14033         # clear stats.
14034         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14035         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14036
14037         # verify mdt stats first.
14038         mkdir ${testdir} || error "mkdir failed"
14039         check_stats $SINGLEMDS "mkdir" 1
14040         touch ${testdir}/${tfile} || error "touch failed"
14041         check_stats $SINGLEMDS "open" 1
14042         check_stats $SINGLEMDS "close" 1
14043         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14044                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14045                 check_stats $SINGLEMDS "mknod" 2
14046         }
14047         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14048         check_stats $SINGLEMDS "unlink" 1
14049         rm -f ${testdir}/${tfile} || error "file remove failed"
14050         check_stats $SINGLEMDS "unlink" 2
14051
14052         # remove working dir and check mdt stats again.
14053         rmdir ${testdir} || error "rmdir failed"
14054         check_stats $SINGLEMDS "rmdir" 1
14055
14056         local testdir1=$DIR/${tdir}/stats_testdir1
14057         mkdir -p ${testdir}
14058         mkdir -p ${testdir1}
14059         touch ${testdir1}/test1
14060         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14061         check_stats $SINGLEMDS "crossdir_rename" 1
14062
14063         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14064         check_stats $SINGLEMDS "samedir_rename" 1
14065
14066         rm -rf $DIR/${tdir}
14067 }
14068 run_test 133a "Verifying MDT stats ========================================"
14069
14070 test_133b() {
14071         local res
14072
14073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14074         remote_ost_nodsh && skip "remote OST with nodsh"
14075         remote_mds_nodsh && skip "remote MDS with nodsh"
14076
14077         local testdir=$DIR/${tdir}/stats_testdir
14078
14079         mkdir -p ${testdir} || error "mkdir failed"
14080         touch ${testdir}/${tfile} || error "touch failed"
14081         cancel_lru_locks mdc
14082
14083         # clear stats.
14084         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14085         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14086
14087         # extra mdt stats verification.
14088         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14089         check_stats $SINGLEMDS "setattr" 1
14090         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14091         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14092         then            # LU-1740
14093                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14094                 check_stats $SINGLEMDS "getattr" 1
14095         fi
14096         rm -rf $DIR/${tdir}
14097
14098         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14099         # so the check below is not reliable
14100         [ $MDSCOUNT -eq 1 ] || return 0
14101
14102         # Sleep to avoid a cached response.
14103         #define OBD_STATFS_CACHE_SECONDS 1
14104         sleep 2
14105         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14106         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14107         $LFS df || error "lfs failed"
14108         check_stats $SINGLEMDS "statfs" 1
14109
14110         # check aggregated statfs (LU-10018)
14111         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14112                 return 0
14113         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14114                 return 0
14115         sleep 2
14116         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14117         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14118         df $DIR
14119         check_stats $SINGLEMDS "statfs" 1
14120
14121         # We want to check that the client didn't send OST_STATFS to
14122         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14123         # extra care is needed here.
14124         if remote_mds; then
14125                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14126                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14127
14128                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14129                 [ "$res" ] && error "OST got STATFS"
14130         fi
14131
14132         return 0
14133 }
14134 run_test 133b "Verifying extra MDT stats =================================="
14135
14136 test_133c() {
14137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14138         remote_ost_nodsh && skip "remote OST with nodsh"
14139         remote_mds_nodsh && skip "remote MDS with nodsh"
14140
14141         local testdir=$DIR/$tdir/stats_testdir
14142
14143         test_mkdir -p $testdir
14144
14145         # verify obdfilter stats.
14146         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14147         sync
14148         cancel_lru_locks osc
14149         wait_delete_completed
14150
14151         # clear stats.
14152         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14153         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14154
14155         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14156                 error "dd failed"
14157         sync
14158         cancel_lru_locks osc
14159         check_stats ost1 "write" 1
14160
14161         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14162         check_stats ost1 "read" 1
14163
14164         > $testdir/$tfile || error "truncate failed"
14165         check_stats ost1 "punch" 1
14166
14167         rm -f $testdir/$tfile || error "file remove failed"
14168         wait_delete_completed
14169         check_stats ost1 "destroy" 1
14170
14171         rm -rf $DIR/$tdir
14172 }
14173 run_test 133c "Verifying OST stats ========================================"
14174
14175 order_2() {
14176         local value=$1
14177         local orig=$value
14178         local order=1
14179
14180         while [ $value -ge 2 ]; do
14181                 order=$((order*2))
14182                 value=$((value/2))
14183         done
14184
14185         if [ $orig -gt $order ]; then
14186                 order=$((order*2))
14187         fi
14188         echo $order
14189 }
14190
14191 size_in_KMGT() {
14192     local value=$1
14193     local size=('K' 'M' 'G' 'T');
14194     local i=0
14195     local size_string=$value
14196
14197     while [ $value -ge 1024 ]; do
14198         if [ $i -gt 3 ]; then
14199             #T is the biggest unit we get here, if that is bigger,
14200             #just return XXXT
14201             size_string=${value}T
14202             break
14203         fi
14204         value=$((value >> 10))
14205         if [ $value -lt 1024 ]; then
14206             size_string=${value}${size[$i]}
14207             break
14208         fi
14209         i=$((i + 1))
14210     done
14211
14212     echo $size_string
14213 }
14214
14215 get_rename_size() {
14216         local size=$1
14217         local context=${2:-.}
14218         local sample=$(do_facet $SINGLEMDS $LCTL \
14219                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14220                 grep -A1 $context |
14221                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14222         echo $sample
14223 }
14224
14225 test_133d() {
14226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14227         remote_ost_nodsh && skip "remote OST with nodsh"
14228         remote_mds_nodsh && skip "remote MDS with nodsh"
14229         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14230                 skip_env "MDS doesn't support rename stats"
14231
14232         local testdir1=$DIR/${tdir}/stats_testdir1
14233         local testdir2=$DIR/${tdir}/stats_testdir2
14234         mkdir -p $DIR/${tdir}
14235
14236         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14237
14238         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14239         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14240
14241         createmany -o $testdir1/test 512 || error "createmany failed"
14242
14243         # check samedir rename size
14244         mv ${testdir1}/test0 ${testdir1}/test_0
14245
14246         local testdir1_size=$(ls -l $DIR/${tdir} |
14247                 awk '/stats_testdir1/ {print $5}')
14248         local testdir2_size=$(ls -l $DIR/${tdir} |
14249                 awk '/stats_testdir2/ {print $5}')
14250
14251         testdir1_size=$(order_2 $testdir1_size)
14252         testdir2_size=$(order_2 $testdir2_size)
14253
14254         testdir1_size=$(size_in_KMGT $testdir1_size)
14255         testdir2_size=$(size_in_KMGT $testdir2_size)
14256
14257         echo "source rename dir size: ${testdir1_size}"
14258         echo "target rename dir size: ${testdir2_size}"
14259
14260         local cmd="do_facet $SINGLEMDS $LCTL "
14261         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14262
14263         eval $cmd || error "$cmd failed"
14264         local samedir=$($cmd | grep 'same_dir')
14265         local same_sample=$(get_rename_size $testdir1_size)
14266         [ -z "$samedir" ] && error "samedir_rename_size count error"
14267         [[ $same_sample -eq 1 ]] ||
14268                 error "samedir_rename_size error $same_sample"
14269         echo "Check same dir rename stats success"
14270
14271         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14272
14273         # check crossdir rename size
14274         mv ${testdir1}/test_0 ${testdir2}/test_0
14275
14276         testdir1_size=$(ls -l $DIR/${tdir} |
14277                 awk '/stats_testdir1/ {print $5}')
14278         testdir2_size=$(ls -l $DIR/${tdir} |
14279                 awk '/stats_testdir2/ {print $5}')
14280
14281         testdir1_size=$(order_2 $testdir1_size)
14282         testdir2_size=$(order_2 $testdir2_size)
14283
14284         testdir1_size=$(size_in_KMGT $testdir1_size)
14285         testdir2_size=$(size_in_KMGT $testdir2_size)
14286
14287         echo "source rename dir size: ${testdir1_size}"
14288         echo "target rename dir size: ${testdir2_size}"
14289
14290         eval $cmd || error "$cmd failed"
14291         local crossdir=$($cmd | grep 'crossdir')
14292         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14293         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14294         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14295         [[ $src_sample -eq 1 ]] ||
14296                 error "crossdir_rename_size error $src_sample"
14297         [[ $tgt_sample -eq 1 ]] ||
14298                 error "crossdir_rename_size error $tgt_sample"
14299         echo "Check cross dir rename stats success"
14300         rm -rf $DIR/${tdir}
14301 }
14302 run_test 133d "Verifying rename_stats ========================================"
14303
14304 test_133e() {
14305         remote_mds_nodsh && skip "remote MDS with nodsh"
14306         remote_ost_nodsh && skip "remote OST with nodsh"
14307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14308
14309         local testdir=$DIR/${tdir}/stats_testdir
14310         local ctr f0 f1 bs=32768 count=42 sum
14311
14312         mkdir -p ${testdir} || error "mkdir failed"
14313
14314         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14315
14316         for ctr in {write,read}_bytes; do
14317                 sync
14318                 cancel_lru_locks osc
14319
14320                 do_facet ost1 $LCTL set_param -n \
14321                         "obdfilter.*.exports.clear=clear"
14322
14323                 if [ $ctr = write_bytes ]; then
14324                         f0=/dev/zero
14325                         f1=${testdir}/${tfile}
14326                 else
14327                         f0=${testdir}/${tfile}
14328                         f1=/dev/null
14329                 fi
14330
14331                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14332                         error "dd failed"
14333                 sync
14334                 cancel_lru_locks osc
14335
14336                 sum=$(do_facet ost1 $LCTL get_param \
14337                         "obdfilter.*.exports.*.stats" |
14338                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14339                                 $1 == ctr { sum += $7 }
14340                                 END { printf("%0.0f", sum) }')
14341
14342                 if ((sum != bs * count)); then
14343                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14344                 fi
14345         done
14346
14347         rm -rf $DIR/${tdir}
14348 }
14349 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14350
14351 test_133f() {
14352         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14353                 skip "too old lustre for get_param -R ($facet_ver)"
14354
14355         # verifying readability.
14356         $LCTL get_param -R '*' &> /dev/null
14357
14358         # Verifing writability with badarea_io.
14359         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14360         local skipped_params='force_lbug|changelog_mask|daemon_file'
14361         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14362                 egrep -v "$skipped_params" |
14363                 xargs -n 1 find $proc_dirs -name |
14364                 xargs -n 1 badarea_io ||
14365                 error "client badarea_io failed"
14366
14367         # remount the FS in case writes/reads /proc break the FS
14368         cleanup || error "failed to unmount"
14369         setup || error "failed to setup"
14370 }
14371 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14372
14373 test_133g() {
14374         remote_mds_nodsh && skip "remote MDS with nodsh"
14375         remote_ost_nodsh && skip "remote OST with nodsh"
14376
14377         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14378         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14379         local facet
14380         for facet in mds1 ost1; do
14381                 local facet_ver=$(lustre_version_code $facet)
14382                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14383                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14384                 else
14385                         log "$facet: too old lustre for get_param -R"
14386                 fi
14387                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14388                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14389                                 tr -d = | egrep -v $skipped_params |
14390                                 xargs -n 1 find $proc_dirs -name |
14391                                 xargs -n 1 badarea_io" ||
14392                                         error "$facet badarea_io failed"
14393                 else
14394                         skip_noexit "$facet: too old lustre for get_param -R"
14395                 fi
14396         done
14397
14398         # remount the FS in case writes/reads /proc break the FS
14399         cleanup || error "failed to unmount"
14400         setup || error "failed to setup"
14401 }
14402 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14403
14404 test_133h() {
14405         remote_mds_nodsh && skip "remote MDS with nodsh"
14406         remote_ost_nodsh && skip "remote OST with nodsh"
14407         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14408                 skip "Need MDS version at least 2.9.54"
14409
14410         local facet
14411         for facet in client mds1 ost1; do
14412                 # Get the list of files that are missing the terminating newline
14413                 local plist=$(do_facet $facet
14414                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14415                 local ent
14416                 for ent in $plist; do
14417                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14418                                 awk -v FS='\v' -v RS='\v\v' \
14419                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14420                                         print FILENAME}'" 2>/dev/null)
14421                         [ -z $missing ] || {
14422                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14423                                 error "file does not end with newline: $facet-$ent"
14424                         }
14425                 done
14426         done
14427 }
14428 run_test 133h "Proc files should end with newlines"
14429
14430 test_134a() {
14431         remote_mds_nodsh && skip "remote MDS with nodsh"
14432         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14433                 skip "Need MDS version at least 2.7.54"
14434
14435         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14436         cancel_lru_locks mdc
14437
14438         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14439         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14440         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14441
14442         local nr=1000
14443         createmany -o $DIR/$tdir/f $nr ||
14444                 error "failed to create $nr files in $DIR/$tdir"
14445         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14446
14447         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14448         do_facet mds1 $LCTL set_param fail_loc=0x327
14449         do_facet mds1 $LCTL set_param fail_val=500
14450         touch $DIR/$tdir/m
14451
14452         echo "sleep 10 seconds ..."
14453         sleep 10
14454         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14455
14456         do_facet mds1 $LCTL set_param fail_loc=0
14457         do_facet mds1 $LCTL set_param fail_val=0
14458         [ $lck_cnt -lt $unused ] ||
14459                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14460
14461         rm $DIR/$tdir/m
14462         unlinkmany $DIR/$tdir/f $nr
14463 }
14464 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14465
14466 test_134b() {
14467         remote_mds_nodsh && skip "remote MDS with nodsh"
14468         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14469                 skip "Need MDS version at least 2.7.54"
14470
14471         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14472         cancel_lru_locks mdc
14473
14474         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14475                         ldlm.lock_reclaim_threshold_mb)
14476         # disable reclaim temporarily
14477         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14478
14479         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14480         do_facet mds1 $LCTL set_param fail_loc=0x328
14481         do_facet mds1 $LCTL set_param fail_val=500
14482
14483         $LCTL set_param debug=+trace
14484
14485         local nr=600
14486         createmany -o $DIR/$tdir/f $nr &
14487         local create_pid=$!
14488
14489         echo "Sleep $TIMEOUT seconds ..."
14490         sleep $TIMEOUT
14491         if ! ps -p $create_pid  > /dev/null 2>&1; then
14492                 do_facet mds1 $LCTL set_param fail_loc=0
14493                 do_facet mds1 $LCTL set_param fail_val=0
14494                 do_facet mds1 $LCTL set_param \
14495                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14496                 error "createmany finished incorrectly!"
14497         fi
14498         do_facet mds1 $LCTL set_param fail_loc=0
14499         do_facet mds1 $LCTL set_param fail_val=0
14500         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14501         wait $create_pid || return 1
14502
14503         unlinkmany $DIR/$tdir/f $nr
14504 }
14505 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14506
14507 test_135() {
14508         remote_mds_nodsh && skip "remote MDS with nodsh"
14509         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14510                 skip "Need MDS version at least 2.13.50"
14511         local fname
14512
14513         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14514
14515 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14516         #set only one record at plain llog
14517         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14518
14519         #fill already existed plain llog each 64767
14520         #wrapping whole catalog
14521         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14522
14523         createmany -o $DIR/$tdir/$tfile_ 64700
14524         for (( i = 0; i < 64700; i = i + 2 ))
14525         do
14526                 rm $DIR/$tdir/$tfile_$i &
14527                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14528                 local pid=$!
14529                 wait $pid
14530         done
14531
14532         #waiting osp synchronization
14533         wait_delete_completed
14534 }
14535 run_test 135 "Race catalog processing"
14536
14537 test_136() {
14538         remote_mds_nodsh && skip "remote MDS with nodsh"
14539         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14540                 skip "Need MDS version at least 2.13.50"
14541         local fname
14542
14543         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14544         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14545         #set only one record at plain llog
14546 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14547         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14548
14549         #fill already existed 2 plain llogs each 64767
14550         #wrapping whole catalog
14551         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14552         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14553         wait_delete_completed
14554
14555         createmany -o $DIR/$tdir/$tfile_ 10
14556         sleep 25
14557
14558         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14559         for (( i = 0; i < 10; i = i + 3 ))
14560         do
14561                 rm $DIR/$tdir/$tfile_$i &
14562                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14563                 local pid=$!
14564                 wait $pid
14565                 sleep 7
14566                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14567         done
14568
14569         #waiting osp synchronization
14570         wait_delete_completed
14571 }
14572 run_test 136 "Race catalog processing 2"
14573
14574 test_140() { #bug-17379
14575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14576
14577         test_mkdir $DIR/$tdir
14578         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14579         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14580
14581         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14582         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14583         local i=0
14584         while i=$((i + 1)); do
14585                 test_mkdir $i
14586                 cd $i || error "Changing to $i"
14587                 ln -s ../stat stat || error "Creating stat symlink"
14588                 # Read the symlink until ELOOP present,
14589                 # not LBUGing the system is considered success,
14590                 # we didn't overrun the stack.
14591                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14592                 if [ $ret -ne 0 ]; then
14593                         if [ $ret -eq 40 ]; then
14594                                 break  # -ELOOP
14595                         else
14596                                 error "Open stat symlink"
14597                                         return
14598                         fi
14599                 fi
14600         done
14601         i=$((i - 1))
14602         echo "The symlink depth = $i"
14603         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14604                 error "Invalid symlink depth"
14605
14606         # Test recursive symlink
14607         ln -s symlink_self symlink_self
14608         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14609         echo "open symlink_self returns $ret"
14610         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14611 }
14612 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14613
14614 test_150a() {
14615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14616
14617         local TF="$TMP/$tfile"
14618
14619         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14620         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14621         cp $TF $DIR/$tfile
14622         cancel_lru_locks $OSC
14623         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14624         remount_client $MOUNT
14625         df -P $MOUNT
14626         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14627
14628         $TRUNCATE $TF 6000
14629         $TRUNCATE $DIR/$tfile 6000
14630         cancel_lru_locks $OSC
14631         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14632
14633         echo "12345" >>$TF
14634         echo "12345" >>$DIR/$tfile
14635         cancel_lru_locks $OSC
14636         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14637
14638         echo "12345" >>$TF
14639         echo "12345" >>$DIR/$tfile
14640         cancel_lru_locks $OSC
14641         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14642 }
14643 run_test 150a "truncate/append tests"
14644
14645 test_150b() {
14646         check_set_fallocate_or_skip
14647
14648         touch $DIR/$tfile
14649         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14650         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14651 }
14652 run_test 150b "Verify fallocate (prealloc) functionality"
14653
14654 test_150bb() {
14655         check_set_fallocate_or_skip
14656
14657         touch $DIR/$tfile
14658         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14659         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14660         > $DIR/$tfile
14661         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14662         # precomputed md5sum for 20MB of zeroes
14663         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14664         local sum=($(md5sum $DIR/$tfile))
14665
14666         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14667
14668         check_set_fallocate 1
14669
14670         > $DIR/$tfile
14671         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14672         sum=($(md5sum $DIR/$tfile))
14673
14674         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14675 }
14676 run_test 150bb "Verify fallocate modes both zero space"
14677
14678 test_150c() {
14679         check_set_fallocate_or_skip
14680         local striping="-c2"
14681
14682         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14683         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14684         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14685         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14686         local want=$((OSTCOUNT * 1048576))
14687
14688         # Must allocate all requested space, not more than 5% extra
14689         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14690                 error "bytes $bytes is not $want"
14691
14692         rm -f $DIR/$tfile
14693
14694         echo "verify fallocate on PFL file"
14695
14696         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14697
14698         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14699                 error "Create $DIR/$tfile failed"
14700         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14701         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14702         want=$((512 * 1048576))
14703
14704         # Must allocate all requested space, not more than 5% extra
14705         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14706                 error "bytes $bytes is not $want"
14707 }
14708 run_test 150c "Verify fallocate Size and Blocks"
14709
14710 test_150d() {
14711         check_set_fallocate_or_skip
14712         local striping="-c2"
14713
14714         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14715
14716         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14717         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14718                 error "setstripe failed"
14719         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14720         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14721         local want=$((OSTCOUNT * 1048576))
14722
14723         # Must allocate all requested space, not more than 5% extra
14724         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14725                 error "bytes $bytes is not $want"
14726 }
14727 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14728
14729 test_150e() {
14730         check_set_fallocate_or_skip
14731
14732         echo "df before:"
14733         $LFS df
14734         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14735         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14736                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14737
14738         # Find OST with Minimum Size
14739         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14740                        sort -un | head -1)
14741
14742         # Get 100MB per OST of the available space to reduce run time
14743         # else 60% of the available space if we are running SLOW tests
14744         if [ $SLOW == "no" ]; then
14745                 local space=$((1024 * 100 * OSTCOUNT))
14746         else
14747                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14748         fi
14749
14750         fallocate -l${space}k $DIR/$tfile ||
14751                 error "fallocate ${space}k $DIR/$tfile failed"
14752         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14753
14754         # get size immediately after fallocate. This should be correctly
14755         # updated
14756         local size=$(stat -c '%s' $DIR/$tfile)
14757         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14758
14759         # Sleep for a while for statfs to get updated. And not pull from cache.
14760         sleep 2
14761
14762         echo "df after fallocate:"
14763         $LFS df
14764
14765         (( size / 1024 == space )) || error "size $size != requested $space"
14766         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14767                 error "used $used < space $space"
14768
14769         rm $DIR/$tfile || error "rm failed"
14770         sync
14771         wait_delete_completed
14772
14773         echo "df after unlink:"
14774         $LFS df
14775 }
14776 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14777
14778 test_150f() {
14779         local size
14780         local blocks
14781         local want_size_before=20480 # in bytes
14782         local want_blocks_before=40 # 512 sized blocks
14783         local want_blocks_after=24  # 512 sized blocks
14784         local length=$(((want_blocks_before - want_blocks_after) * 512))
14785
14786         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14787                 skip "need at least 2.14.0 for fallocate punch"
14788
14789         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14790                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14791         fi
14792
14793         check_set_fallocate_or_skip
14794         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14795
14796         [[ "x$DOM" == "xyes" ]] &&
14797                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14798
14799         echo "Verify fallocate punch: Range within the file range"
14800         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14801                 error "dd failed for bs 4096 and count 5"
14802
14803         # Call fallocate with punch range which is within the file range
14804         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14805                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14806         # client must see changes immediately after fallocate
14807         size=$(stat -c '%s' $DIR/$tfile)
14808         blocks=$(stat -c '%b' $DIR/$tfile)
14809
14810         # Verify punch worked.
14811         (( blocks == want_blocks_after )) ||
14812                 error "punch failed: blocks $blocks != $want_blocks_after"
14813
14814         (( size == want_size_before )) ||
14815                 error "punch failed: size $size != $want_size_before"
14816
14817         # Verify there is hole in file
14818         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14819         # precomputed md5sum
14820         local expect="4a9a834a2db02452929c0a348273b4aa"
14821
14822         cksum=($(md5sum $DIR/$tfile))
14823         [[ "${cksum[0]}" == "$expect" ]] ||
14824                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14825
14826         # Start second sub-case for fallocate punch.
14827         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14828         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14829                 error "dd failed for bs 4096 and count 5"
14830
14831         # Punch range less than block size will have no change in block count
14832         want_blocks_after=40  # 512 sized blocks
14833
14834         # Punch overlaps two blocks and less than blocksize
14835         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14836                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14837         size=$(stat -c '%s' $DIR/$tfile)
14838         blocks=$(stat -c '%b' $DIR/$tfile)
14839
14840         # Verify punch worked.
14841         (( blocks == want_blocks_after )) ||
14842                 error "punch failed: blocks $blocks != $want_blocks_after"
14843
14844         (( size == want_size_before )) ||
14845                 error "punch failed: size $size != $want_size_before"
14846
14847         # Verify if range is really zero'ed out. We expect Zeros.
14848         # precomputed md5sum
14849         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14850         cksum=($(md5sum $DIR/$tfile))
14851         [[ "${cksum[0]}" == "$expect" ]] ||
14852                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14853 }
14854 run_test 150f "Verify fallocate punch functionality"
14855
14856 test_150g() {
14857         local space
14858         local size
14859         local blocks
14860         local blocks_after
14861         local size_after
14862         local BS=4096 # Block size in bytes
14863
14864         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14865                 skip "need at least 2.14.0 for fallocate punch"
14866
14867         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14868                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14869         fi
14870
14871         check_set_fallocate_or_skip
14872         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14873
14874         if [[ "x$DOM" == "xyes" ]]; then
14875                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14876                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14877         else
14878                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14879                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14880         fi
14881
14882         # Get 100MB per OST of the available space to reduce run time
14883         # else 60% of the available space if we are running SLOW tests
14884         if [ $SLOW == "no" ]; then
14885                 space=$((1024 * 100 * OSTCOUNT))
14886         else
14887                 # Find OST with Minimum Size
14888                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14889                         sort -un | head -1)
14890                 echo "min size OST: $space"
14891                 space=$(((space * 60)/100 * OSTCOUNT))
14892         fi
14893         # space in 1k units, round to 4k blocks
14894         local blkcount=$((space * 1024 / $BS))
14895
14896         echo "Verify fallocate punch: Very large Range"
14897         fallocate -l${space}k $DIR/$tfile ||
14898                 error "fallocate ${space}k $DIR/$tfile failed"
14899         # write 1M at the end, start and in the middle
14900         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14901                 error "dd failed: bs $BS count 256"
14902         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14903                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14904         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14905                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14906
14907         # Gather stats.
14908         size=$(stat -c '%s' $DIR/$tfile)
14909
14910         # gather punch length.
14911         local punch_size=$((size - (BS * 2)))
14912
14913         echo "punch_size = $punch_size"
14914         echo "size - punch_size: $((size - punch_size))"
14915         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14916
14917         # Call fallocate to punch all except 2 blocks. We leave the
14918         # first and the last block
14919         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14920         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
14921                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
14922
14923         size_after=$(stat -c '%s' $DIR/$tfile)
14924         blocks_after=$(stat -c '%b' $DIR/$tfile)
14925
14926         # Verify punch worked.
14927         # Size should be kept
14928         (( size == size_after )) ||
14929                 error "punch failed: size $size != $size_after"
14930
14931         # two 4k data blocks to remain plus possible 1 extra extent block
14932         (( blocks_after <= ((BS / 512) * 3) )) ||
14933                 error "too many blocks remains: $blocks_after"
14934
14935         # Verify that file has hole between the first and the last blocks
14936         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14937         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14938
14939         echo "Hole at [$hole_start, $hole_end)"
14940         (( hole_start == BS )) ||
14941                 error "no hole at offset $BS after punch"
14942
14943         (( hole_end == BS + punch_size )) ||
14944                 error "data at offset $hole_end < $((BS + punch_size))"
14945 }
14946 run_test 150g "Verify fallocate punch on large range"
14947
14948 #LU-2902 roc_hit was not able to read all values from lproc
14949 function roc_hit_init() {
14950         local list=$(comma_list $(osts_nodes))
14951         local dir=$DIR/$tdir-check
14952         local file=$dir/$tfile
14953         local BEFORE
14954         local AFTER
14955         local idx
14956
14957         test_mkdir $dir
14958         #use setstripe to do a write to every ost
14959         for i in $(seq 0 $((OSTCOUNT-1))); do
14960                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14961                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14962                 idx=$(printf %04x $i)
14963                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14964                         awk '$1 == "cache_access" {sum += $7}
14965                                 END { printf("%0.0f", sum) }')
14966
14967                 cancel_lru_locks osc
14968                 cat $file >/dev/null
14969
14970                 AFTER=$(get_osd_param $list *OST*$idx stats |
14971                         awk '$1 == "cache_access" {sum += $7}
14972                                 END { printf("%0.0f", sum) }')
14973
14974                 echo BEFORE:$BEFORE AFTER:$AFTER
14975                 if ! let "AFTER - BEFORE == 4"; then
14976                         rm -rf $dir
14977                         error "roc_hit is not safe to use"
14978                 fi
14979                 rm $file
14980         done
14981
14982         rm -rf $dir
14983 }
14984
14985 function roc_hit() {
14986         local list=$(comma_list $(osts_nodes))
14987         echo $(get_osd_param $list '' stats |
14988                 awk '$1 == "cache_hit" {sum += $7}
14989                         END { printf("%0.0f", sum) }')
14990 }
14991
14992 function set_cache() {
14993         local on=1
14994
14995         if [ "$2" == "off" ]; then
14996                 on=0;
14997         fi
14998         local list=$(comma_list $(osts_nodes))
14999         set_osd_param $list '' $1_cache_enable $on
15000
15001         cancel_lru_locks osc
15002 }
15003
15004 test_151() {
15005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15006         remote_ost_nodsh && skip "remote OST with nodsh"
15007
15008         local CPAGES=3
15009         local list=$(comma_list $(osts_nodes))
15010
15011         # check whether obdfilter is cache capable at all
15012         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15013                 skip "not cache-capable obdfilter"
15014         fi
15015
15016         # check cache is enabled on all obdfilters
15017         if get_osd_param $list '' read_cache_enable | grep 0; then
15018                 skip "oss cache is disabled"
15019         fi
15020
15021         set_osd_param $list '' writethrough_cache_enable 1
15022
15023         # check write cache is enabled on all obdfilters
15024         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15025                 skip "oss write cache is NOT enabled"
15026         fi
15027
15028         roc_hit_init
15029
15030         #define OBD_FAIL_OBD_NO_LRU  0x609
15031         do_nodes $list $LCTL set_param fail_loc=0x609
15032
15033         # pages should be in the case right after write
15034         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15035                 error "dd failed"
15036
15037         local BEFORE=$(roc_hit)
15038         cancel_lru_locks osc
15039         cat $DIR/$tfile >/dev/null
15040         local AFTER=$(roc_hit)
15041
15042         do_nodes $list $LCTL set_param fail_loc=0
15043
15044         if ! let "AFTER - BEFORE == CPAGES"; then
15045                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15046         fi
15047
15048         cancel_lru_locks osc
15049         # invalidates OST cache
15050         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15051         set_osd_param $list '' read_cache_enable 0
15052         cat $DIR/$tfile >/dev/null
15053
15054         # now data shouldn't be found in the cache
15055         BEFORE=$(roc_hit)
15056         cancel_lru_locks osc
15057         cat $DIR/$tfile >/dev/null
15058         AFTER=$(roc_hit)
15059         if let "AFTER - BEFORE != 0"; then
15060                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15061         fi
15062
15063         set_osd_param $list '' read_cache_enable 1
15064         rm -f $DIR/$tfile
15065 }
15066 run_test 151 "test cache on oss and controls ==============================="
15067
15068 test_152() {
15069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15070
15071         local TF="$TMP/$tfile"
15072
15073         # simulate ENOMEM during write
15074 #define OBD_FAIL_OST_NOMEM      0x226
15075         lctl set_param fail_loc=0x80000226
15076         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15077         cp $TF $DIR/$tfile
15078         sync || error "sync failed"
15079         lctl set_param fail_loc=0
15080
15081         # discard client's cache
15082         cancel_lru_locks osc
15083
15084         # simulate ENOMEM during read
15085         lctl set_param fail_loc=0x80000226
15086         cmp $TF $DIR/$tfile || error "cmp failed"
15087         lctl set_param fail_loc=0
15088
15089         rm -f $TF
15090 }
15091 run_test 152 "test read/write with enomem ============================"
15092
15093 test_153() {
15094         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15095 }
15096 run_test 153 "test if fdatasync does not crash ======================="
15097
15098 dot_lustre_fid_permission_check() {
15099         local fid=$1
15100         local ffid=$MOUNT/.lustre/fid/$fid
15101         local test_dir=$2
15102
15103         echo "stat fid $fid"
15104         stat $ffid > /dev/null || error "stat $ffid failed."
15105         echo "touch fid $fid"
15106         touch $ffid || error "touch $ffid failed."
15107         echo "write to fid $fid"
15108         cat /etc/hosts > $ffid || error "write $ffid failed."
15109         echo "read fid $fid"
15110         diff /etc/hosts $ffid || error "read $ffid failed."
15111         echo "append write to fid $fid"
15112         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15113         echo "rename fid $fid"
15114         mv $ffid $test_dir/$tfile.1 &&
15115                 error "rename $ffid to $tfile.1 should fail."
15116         touch $test_dir/$tfile.1
15117         mv $test_dir/$tfile.1 $ffid &&
15118                 error "rename $tfile.1 to $ffid should fail."
15119         rm -f $test_dir/$tfile.1
15120         echo "truncate fid $fid"
15121         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15122         echo "link fid $fid"
15123         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15124         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15125                 echo "setfacl fid $fid"
15126                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15127                 echo "getfacl fid $fid"
15128                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15129         fi
15130         echo "unlink fid $fid"
15131         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15132         echo "mknod fid $fid"
15133         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15134
15135         fid=[0xf00000400:0x1:0x0]
15136         ffid=$MOUNT/.lustre/fid/$fid
15137
15138         echo "stat non-exist fid $fid"
15139         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15140         echo "write to non-exist fid $fid"
15141         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15142         echo "link new fid $fid"
15143         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15144
15145         mkdir -p $test_dir/$tdir
15146         touch $test_dir/$tdir/$tfile
15147         fid=$($LFS path2fid $test_dir/$tdir)
15148         rc=$?
15149         [ $rc -ne 0 ] &&
15150                 error "error: could not get fid for $test_dir/$dir/$tfile."
15151
15152         ffid=$MOUNT/.lustre/fid/$fid
15153
15154         echo "ls $fid"
15155         ls $ffid > /dev/null || error "ls $ffid failed."
15156         echo "touch $fid/$tfile.1"
15157         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15158
15159         echo "touch $MOUNT/.lustre/fid/$tfile"
15160         touch $MOUNT/.lustre/fid/$tfile && \
15161                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15162
15163         echo "setxattr to $MOUNT/.lustre/fid"
15164         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15165
15166         echo "listxattr for $MOUNT/.lustre/fid"
15167         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15168
15169         echo "delxattr from $MOUNT/.lustre/fid"
15170         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15171
15172         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15173         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15174                 error "touch invalid fid should fail."
15175
15176         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15177         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15178                 error "touch non-normal fid should fail."
15179
15180         echo "rename $tdir to $MOUNT/.lustre/fid"
15181         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15182                 error "rename to $MOUNT/.lustre/fid should fail."
15183
15184         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15185         then            # LU-3547
15186                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15187                 local new_obf_mode=777
15188
15189                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15190                 chmod $new_obf_mode $DIR/.lustre/fid ||
15191                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15192
15193                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15194                 [ $obf_mode -eq $new_obf_mode ] ||
15195                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15196
15197                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15198                 chmod $old_obf_mode $DIR/.lustre/fid ||
15199                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15200         fi
15201
15202         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15203         fid=$($LFS path2fid $test_dir/$tfile-2)
15204
15205         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15206         then # LU-5424
15207                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15208                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15209                         error "create lov data thru .lustre failed"
15210         fi
15211         echo "cp /etc/passwd $test_dir/$tfile-2"
15212         cp /etc/passwd $test_dir/$tfile-2 ||
15213                 error "copy to $test_dir/$tfile-2 failed."
15214         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15215         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15216                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15217
15218         rm -rf $test_dir/tfile.lnk
15219         rm -rf $test_dir/$tfile-2
15220 }
15221
15222 test_154A() {
15223         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15224                 skip "Need MDS version at least 2.4.1"
15225
15226         local tf=$DIR/$tfile
15227         touch $tf
15228
15229         local fid=$($LFS path2fid $tf)
15230         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15231
15232         # check that we get the same pathname back
15233         local rootpath
15234         local found
15235         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15236                 echo "$rootpath $fid"
15237                 found=$($LFS fid2path $rootpath "$fid")
15238                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15239                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15240         done
15241
15242         # check wrong root path format
15243         rootpath=$MOUNT"_wrong"
15244         found=$($LFS fid2path $rootpath "$fid")
15245         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15246 }
15247 run_test 154A "lfs path2fid and fid2path basic checks"
15248
15249 test_154B() {
15250         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15251                 skip "Need MDS version at least 2.4.1"
15252
15253         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15254         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15255         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15256         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15257
15258         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15259         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15260
15261         # check that we get the same pathname
15262         echo "PFID: $PFID, name: $name"
15263         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15264         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15265         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15266                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15267
15268         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15269 }
15270 run_test 154B "verify the ll_decode_linkea tool"
15271
15272 test_154a() {
15273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15274         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15275         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15276                 skip "Need MDS version at least 2.2.51"
15277         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15278
15279         cp /etc/hosts $DIR/$tfile
15280
15281         fid=$($LFS path2fid $DIR/$tfile)
15282         rc=$?
15283         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15284
15285         dot_lustre_fid_permission_check "$fid" $DIR ||
15286                 error "dot lustre permission check $fid failed"
15287
15288         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15289
15290         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15291
15292         touch $MOUNT/.lustre/file &&
15293                 error "creation is not allowed under .lustre"
15294
15295         mkdir $MOUNT/.lustre/dir &&
15296                 error "mkdir is not allowed under .lustre"
15297
15298         rm -rf $DIR/$tfile
15299 }
15300 run_test 154a "Open-by-FID"
15301
15302 test_154b() {
15303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15304         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15305         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15306         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15307                 skip "Need MDS version at least 2.2.51"
15308
15309         local remote_dir=$DIR/$tdir/remote_dir
15310         local MDTIDX=1
15311         local rc=0
15312
15313         mkdir -p $DIR/$tdir
15314         $LFS mkdir -i $MDTIDX $remote_dir ||
15315                 error "create remote directory failed"
15316
15317         cp /etc/hosts $remote_dir/$tfile
15318
15319         fid=$($LFS path2fid $remote_dir/$tfile)
15320         rc=$?
15321         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15322
15323         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15324                 error "dot lustre permission check $fid failed"
15325         rm -rf $DIR/$tdir
15326 }
15327 run_test 154b "Open-by-FID for remote directory"
15328
15329 test_154c() {
15330         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15331                 skip "Need MDS version at least 2.4.1"
15332
15333         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15334         local FID1=$($LFS path2fid $DIR/$tfile.1)
15335         local FID2=$($LFS path2fid $DIR/$tfile.2)
15336         local FID3=$($LFS path2fid $DIR/$tfile.3)
15337
15338         local N=1
15339         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15340                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15341                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15342                 local want=FID$N
15343                 [ "$FID" = "${!want}" ] ||
15344                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15345                 N=$((N + 1))
15346         done
15347
15348         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15349         do
15350                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15351                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15352                 N=$((N + 1))
15353         done
15354 }
15355 run_test 154c "lfs path2fid and fid2path multiple arguments"
15356
15357 test_154d() {
15358         remote_mds_nodsh && skip "remote MDS with nodsh"
15359         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15360                 skip "Need MDS version at least 2.5.53"
15361
15362         if remote_mds; then
15363                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15364         else
15365                 nid="0@lo"
15366         fi
15367         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15368         local fd
15369         local cmd
15370
15371         rm -f $DIR/$tfile
15372         touch $DIR/$tfile
15373
15374         local fid=$($LFS path2fid $DIR/$tfile)
15375         # Open the file
15376         fd=$(free_fd)
15377         cmd="exec $fd<$DIR/$tfile"
15378         eval $cmd
15379         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15380         echo "$fid_list" | grep "$fid"
15381         rc=$?
15382
15383         cmd="exec $fd>/dev/null"
15384         eval $cmd
15385         if [ $rc -ne 0 ]; then
15386                 error "FID $fid not found in open files list $fid_list"
15387         fi
15388 }
15389 run_test 154d "Verify open file fid"
15390
15391 test_154e()
15392 {
15393         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15394                 skip "Need MDS version at least 2.6.50"
15395
15396         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15397                 error ".lustre returned by readdir"
15398         fi
15399 }
15400 run_test 154e ".lustre is not returned by readdir"
15401
15402 test_154f() {
15403         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15404
15405         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15406         mkdir_on_mdt0 $DIR/$tdir
15407         # test dirs inherit from its stripe
15408         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15409         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15410         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15411         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15412         touch $DIR/f
15413
15414         # get fid of parents
15415         local FID0=$($LFS path2fid $DIR/$tdir)
15416         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15417         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15418         local FID3=$($LFS path2fid $DIR)
15419
15420         # check that path2fid --parents returns expected <parent_fid>/name
15421         # 1) test for a directory (single parent)
15422         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15423         [ "$parent" == "$FID0/foo1" ] ||
15424                 error "expected parent: $FID0/foo1, got: $parent"
15425
15426         # 2) test for a file with nlink > 1 (multiple parents)
15427         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15428         echo "$parent" | grep -F "$FID1/$tfile" ||
15429                 error "$FID1/$tfile not returned in parent list"
15430         echo "$parent" | grep -F "$FID2/link" ||
15431                 error "$FID2/link not returned in parent list"
15432
15433         # 3) get parent by fid
15434         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15435         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15436         echo "$parent" | grep -F "$FID1/$tfile" ||
15437                 error "$FID1/$tfile not returned in parent list (by fid)"
15438         echo "$parent" | grep -F "$FID2/link" ||
15439                 error "$FID2/link not returned in parent list (by fid)"
15440
15441         # 4) test for entry in root directory
15442         parent=$($LFS path2fid --parents $DIR/f)
15443         echo "$parent" | grep -F "$FID3/f" ||
15444                 error "$FID3/f not returned in parent list"
15445
15446         # 5) test it on root directory
15447         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15448                 error "$MOUNT should not have parents"
15449
15450         # enable xattr caching and check that linkea is correctly updated
15451         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15452         save_lustre_params client "llite.*.xattr_cache" > $save
15453         lctl set_param llite.*.xattr_cache 1
15454
15455         # 6.1) linkea update on rename
15456         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15457
15458         # get parents by fid
15459         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15460         # foo1 should no longer be returned in parent list
15461         echo "$parent" | grep -F "$FID1" &&
15462                 error "$FID1 should no longer be in parent list"
15463         # the new path should appear
15464         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15465                 error "$FID2/$tfile.moved is not in parent list"
15466
15467         # 6.2) linkea update on unlink
15468         rm -f $DIR/$tdir/foo2/link
15469         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15470         # foo2/link should no longer be returned in parent list
15471         echo "$parent" | grep -F "$FID2/link" &&
15472                 error "$FID2/link should no longer be in parent list"
15473         true
15474
15475         rm -f $DIR/f
15476         restore_lustre_params < $save
15477         rm -f $save
15478 }
15479 run_test 154f "get parent fids by reading link ea"
15480
15481 test_154g()
15482 {
15483         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15484         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15485            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15486                 skip "Need MDS version at least 2.6.92"
15487
15488         mkdir_on_mdt0 $DIR/$tdir
15489         llapi_fid_test -d $DIR/$tdir
15490 }
15491 run_test 154g "various llapi FID tests"
15492
15493 test_155_small_load() {
15494     local temp=$TMP/$tfile
15495     local file=$DIR/$tfile
15496
15497     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15498         error "dd of=$temp bs=6096 count=1 failed"
15499     cp $temp $file
15500     cancel_lru_locks $OSC
15501     cmp $temp $file || error "$temp $file differ"
15502
15503     $TRUNCATE $temp 6000
15504     $TRUNCATE $file 6000
15505     cmp $temp $file || error "$temp $file differ (truncate1)"
15506
15507     echo "12345" >>$temp
15508     echo "12345" >>$file
15509     cmp $temp $file || error "$temp $file differ (append1)"
15510
15511     echo "12345" >>$temp
15512     echo "12345" >>$file
15513     cmp $temp $file || error "$temp $file differ (append2)"
15514
15515     rm -f $temp $file
15516     true
15517 }
15518
15519 test_155_big_load() {
15520         remote_ost_nodsh && skip "remote OST with nodsh"
15521
15522         local temp=$TMP/$tfile
15523         local file=$DIR/$tfile
15524
15525         free_min_max
15526         local cache_size=$(do_facet ost$((MAXI+1)) \
15527                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15528         local large_file_size=$((cache_size * 2))
15529
15530         echo "OSS cache size: $cache_size KB"
15531         echo "Large file size: $large_file_size KB"
15532
15533         [ $MAXV -le $large_file_size ] &&
15534                 skip_env "max available OST size needs > $large_file_size KB"
15535
15536         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15537
15538         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15539                 error "dd of=$temp bs=$large_file_size count=1k failed"
15540         cp $temp $file
15541         ls -lh $temp $file
15542         cancel_lru_locks osc
15543         cmp $temp $file || error "$temp $file differ"
15544
15545         rm -f $temp $file
15546         true
15547 }
15548
15549 save_writethrough() {
15550         local facets=$(get_facets OST)
15551
15552         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15553 }
15554
15555 test_155a() {
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 on
15564         test_155_small_load
15565         restore_lustre_params < $p
15566         rm -f $p
15567 }
15568 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15569
15570 test_155b() {
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 on
15578         set_cache writethrough off
15579         test_155_small_load
15580         restore_lustre_params < $p
15581         rm -f $p
15582 }
15583 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15584
15585 test_155c() {
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 on
15594         test_155_small_load
15595         restore_lustre_params < $p
15596         rm -f $p
15597 }
15598 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15599
15600 test_155d() {
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 off
15608         set_cache writethrough off
15609         test_155_small_load
15610         restore_lustre_params < $p
15611         rm -f $p
15612 }
15613 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15614
15615 test_155e() {
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 on
15624         test_155_big_load
15625         restore_lustre_params < $p
15626         rm -f $p
15627 }
15628 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15629
15630 test_155f() {
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 on
15638         set_cache writethrough off
15639         test_155_big_load
15640         restore_lustre_params < $p
15641         rm -f $p
15642 }
15643 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15644
15645 test_155g() {
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 on
15654         test_155_big_load
15655         restore_lustre_params < $p
15656         rm -f $p
15657 }
15658 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15659
15660 test_155h() {
15661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15662
15663         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15664
15665         save_writethrough $p
15666
15667         set_cache read off
15668         set_cache writethrough off
15669         test_155_big_load
15670         restore_lustre_params < $p
15671         rm -f $p
15672 }
15673 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15674
15675 test_156() {
15676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15677         remote_ost_nodsh && skip "remote OST with nodsh"
15678         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15679                 skip "stats not implemented on old servers"
15680         [ "$ost1_FSTYPE" = "zfs" ] &&
15681                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15682
15683         local CPAGES=3
15684         local BEFORE
15685         local AFTER
15686         local file="$DIR/$tfile"
15687         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15688
15689         save_writethrough $p
15690         roc_hit_init
15691
15692         log "Turn on read and write cache"
15693         set_cache read on
15694         set_cache writethrough on
15695
15696         log "Write data and read it back."
15697         log "Read should be satisfied from the cache."
15698         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15699         BEFORE=$(roc_hit)
15700         cancel_lru_locks osc
15701         cat $file >/dev/null
15702         AFTER=$(roc_hit)
15703         if ! let "AFTER - BEFORE == CPAGES"; then
15704                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15705         else
15706                 log "cache hits: before: $BEFORE, after: $AFTER"
15707         fi
15708
15709         log "Read again; it should be satisfied from the cache."
15710         BEFORE=$AFTER
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 (3): before: $BEFORE, after: $AFTER"
15716         else
15717                 log "cache hits:: before: $BEFORE, after: $AFTER"
15718         fi
15719
15720         log "Turn off the read cache and turn on the write cache"
15721         set_cache read off
15722         set_cache writethrough on
15723
15724         log "Read again; it should be satisfied from the cache."
15725         BEFORE=$(roc_hit)
15726         cancel_lru_locks osc
15727         cat $file >/dev/null
15728         AFTER=$(roc_hit)
15729         if ! let "AFTER - BEFORE == CPAGES"; then
15730                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15731         else
15732                 log "cache hits:: before: $BEFORE, after: $AFTER"
15733         fi
15734
15735         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15736                 # > 2.12.56 uses pagecache if cached
15737                 log "Read again; it should not be satisfied from the cache."
15738                 BEFORE=$AFTER
15739                 cancel_lru_locks osc
15740                 cat $file >/dev/null
15741                 AFTER=$(roc_hit)
15742                 if ! let "AFTER - BEFORE == 0"; then
15743                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15744                 else
15745                         log "cache hits:: before: $BEFORE, after: $AFTER"
15746                 fi
15747         fi
15748
15749         log "Write data and read it back."
15750         log "Read should be satisfied from the cache."
15751         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15752         BEFORE=$(roc_hit)
15753         cancel_lru_locks osc
15754         cat $file >/dev/null
15755         AFTER=$(roc_hit)
15756         if ! let "AFTER - BEFORE == CPAGES"; then
15757                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15758         else
15759                 log "cache hits:: before: $BEFORE, after: $AFTER"
15760         fi
15761
15762         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15763                 # > 2.12.56 uses pagecache if cached
15764                 log "Read again; it should not be satisfied from the cache."
15765                 BEFORE=$AFTER
15766                 cancel_lru_locks osc
15767                 cat $file >/dev/null
15768                 AFTER=$(roc_hit)
15769                 if ! let "AFTER - BEFORE == 0"; then
15770                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15771                 else
15772                         log "cache hits:: before: $BEFORE, after: $AFTER"
15773                 fi
15774         fi
15775
15776         log "Turn off read and write cache"
15777         set_cache read off
15778         set_cache writethrough off
15779
15780         log "Write data and read it back"
15781         log "It should not be satisfied from the cache."
15782         rm -f $file
15783         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15784         cancel_lru_locks osc
15785         BEFORE=$(roc_hit)
15786         cat $file >/dev/null
15787         AFTER=$(roc_hit)
15788         if ! let "AFTER - BEFORE == 0"; then
15789                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15790         else
15791                 log "cache hits:: before: $BEFORE, after: $AFTER"
15792         fi
15793
15794         log "Turn on the read cache and turn off the write cache"
15795         set_cache read on
15796         set_cache writethrough off
15797
15798         log "Write data and read it back"
15799         log "It should not be satisfied from the cache."
15800         rm -f $file
15801         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15802         BEFORE=$(roc_hit)
15803         cancel_lru_locks osc
15804         cat $file >/dev/null
15805         AFTER=$(roc_hit)
15806         if ! let "AFTER - BEFORE == 0"; then
15807                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15808         else
15809                 log "cache hits:: before: $BEFORE, after: $AFTER"
15810         fi
15811
15812         log "Read again; it should be satisfied from the cache."
15813         BEFORE=$(roc_hit)
15814         cancel_lru_locks osc
15815         cat $file >/dev/null
15816         AFTER=$(roc_hit)
15817         if ! let "AFTER - BEFORE == CPAGES"; then
15818                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15819         else
15820                 log "cache hits:: before: $BEFORE, after: $AFTER"
15821         fi
15822
15823         restore_lustre_params < $p
15824         rm -f $p $file
15825 }
15826 run_test 156 "Verification of tunables"
15827
15828 test_160a() {
15829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15830         remote_mds_nodsh && skip "remote MDS with nodsh"
15831         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15832                 skip "Need MDS version at least 2.2.0"
15833
15834         changelog_register || error "changelog_register failed"
15835         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15836         changelog_users $SINGLEMDS | grep -q $cl_user ||
15837                 error "User $cl_user not found in changelog_users"
15838
15839         mkdir_on_mdt0 $DIR/$tdir
15840
15841         # change something
15842         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15843         changelog_clear 0 || error "changelog_clear failed"
15844         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15845         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15846         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15847         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15848         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15849         rm $DIR/$tdir/pics/desktop.jpg
15850
15851         echo "verifying changelog mask"
15852         changelog_chmask "-MKDIR"
15853         changelog_chmask "-CLOSE"
15854
15855         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15856         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15857
15858         changelog_chmask "+MKDIR"
15859         changelog_chmask "+CLOSE"
15860
15861         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15862         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15863
15864         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15865         CLOSES=$(changelog_dump | grep -c "CLOSE")
15866         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15867         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15868
15869         # verify contents
15870         echo "verifying target fid"
15871         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15872         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15873         [ "$fidc" == "$fidf" ] ||
15874                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15875         echo "verifying parent fid"
15876         # The FID returned from the Changelog may be the directory shard on
15877         # a different MDT, and not the FID returned by path2fid on the parent.
15878         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15879         # since this is what will matter when recreating this file in the tree.
15880         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15881         local pathp=$($LFS fid2path $MOUNT "$fidp")
15882         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15883                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15884
15885         echo "getting records for $cl_user"
15886         changelog_users $SINGLEMDS
15887         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15888         local nclr=3
15889         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15890                 error "changelog_clear failed"
15891         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15892         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15893         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15894                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15895
15896         local min0_rec=$(changelog_users $SINGLEMDS |
15897                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15898         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15899                           awk '{ print $1; exit; }')
15900
15901         changelog_dump | tail -n 5
15902         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15903         [ $first_rec == $((min0_rec + 1)) ] ||
15904                 error "first index should be $min0_rec + 1 not $first_rec"
15905
15906         # LU-3446 changelog index reset on MDT restart
15907         local cur_rec1=$(changelog_users $SINGLEMDS |
15908                          awk '/^current.index:/ { print $NF }')
15909         changelog_clear 0 ||
15910                 error "clear all changelog records for $cl_user failed"
15911         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15912         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15913                 error "Fail to start $SINGLEMDS"
15914         local cur_rec2=$(changelog_users $SINGLEMDS |
15915                          awk '/^current.index:/ { print $NF }')
15916         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15917         [ $cur_rec1 == $cur_rec2 ] ||
15918                 error "current index should be $cur_rec1 not $cur_rec2"
15919
15920         echo "verifying users from this test are deregistered"
15921         changelog_deregister || error "changelog_deregister failed"
15922         changelog_users $SINGLEMDS | grep -q $cl_user &&
15923                 error "User '$cl_user' still in changelog_users"
15924
15925         # lctl get_param -n mdd.*.changelog_users
15926         # current_index: 144
15927         # ID    index (idle seconds)
15928         # cl3   144   (2) mask=<list>
15929         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15930                 # this is the normal case where all users were deregistered
15931                 # make sure no new records are added when no users are present
15932                 local last_rec1=$(changelog_users $SINGLEMDS |
15933                                   awk '/^current.index:/ { print $NF }')
15934                 touch $DIR/$tdir/chloe
15935                 local last_rec2=$(changelog_users $SINGLEMDS |
15936                                   awk '/^current.index:/ { print $NF }')
15937                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15938                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15939         else
15940                 # any changelog users must be leftovers from a previous test
15941                 changelog_users $SINGLEMDS
15942                 echo "other changelog users; can't verify off"
15943         fi
15944 }
15945 run_test 160a "changelog sanity"
15946
15947 test_160b() { # LU-3587
15948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15949         remote_mds_nodsh && skip "remote MDS with nodsh"
15950         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15951                 skip "Need MDS version at least 2.2.0"
15952
15953         changelog_register || error "changelog_register failed"
15954         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15955         changelog_users $SINGLEMDS | grep -q $cl_user ||
15956                 error "User '$cl_user' not found in changelog_users"
15957
15958         local longname1=$(str_repeat a 255)
15959         local longname2=$(str_repeat b 255)
15960
15961         cd $DIR
15962         echo "creating very long named file"
15963         touch $longname1 || error "create of '$longname1' failed"
15964         echo "renaming very long named file"
15965         mv $longname1 $longname2
15966
15967         changelog_dump | grep RENME | tail -n 5
15968         rm -f $longname2
15969 }
15970 run_test 160b "Verify that very long rename doesn't crash in changelog"
15971
15972 test_160c() {
15973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15974         remote_mds_nodsh && skip "remote MDS with nodsh"
15975
15976         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15977                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15978                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15979                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15980
15981         local rc=0
15982
15983         # Registration step
15984         changelog_register || error "changelog_register failed"
15985
15986         rm -rf $DIR/$tdir
15987         mkdir -p $DIR/$tdir
15988         $MCREATE $DIR/$tdir/foo_160c
15989         changelog_chmask "-TRUNC"
15990         $TRUNCATE $DIR/$tdir/foo_160c 200
15991         changelog_chmask "+TRUNC"
15992         $TRUNCATE $DIR/$tdir/foo_160c 199
15993         changelog_dump | tail -n 5
15994         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15995         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15996 }
15997 run_test 160c "verify that changelog log catch the truncate event"
15998
15999 test_160d() {
16000         remote_mds_nodsh && skip "remote MDS with nodsh"
16001         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16003         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16004                 skip "Need MDS version at least 2.7.60"
16005
16006         # Registration step
16007         changelog_register || error "changelog_register failed"
16008
16009         mkdir -p $DIR/$tdir/migrate_dir
16010         changelog_clear 0 || error "changelog_clear failed"
16011
16012         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16013         changelog_dump | tail -n 5
16014         local migrates=$(changelog_dump | grep -c "MIGRT")
16015         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16016 }
16017 run_test 160d "verify that changelog log catch the migrate event"
16018
16019 test_160e() {
16020         remote_mds_nodsh && skip "remote MDS with nodsh"
16021
16022         # Create a user
16023         changelog_register || error "changelog_register failed"
16024
16025         local MDT0=$(facet_svc $SINGLEMDS)
16026         local rc
16027
16028         # No user (expect fail)
16029         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16030         rc=$?
16031         if [ $rc -eq 0 ]; then
16032                 error "Should fail without user"
16033         elif [ $rc -ne 4 ]; then
16034                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16035         fi
16036
16037         # Delete a future user (expect fail)
16038         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16039         rc=$?
16040         if [ $rc -eq 0 ]; then
16041                 error "Deleted non-existant user cl77"
16042         elif [ $rc -ne 2 ]; then
16043                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16044         fi
16045
16046         # Clear to a bad index (1 billion should be safe)
16047         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16048         rc=$?
16049
16050         if [ $rc -eq 0 ]; then
16051                 error "Successfully cleared to invalid CL index"
16052         elif [ $rc -ne 22 ]; then
16053                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16054         fi
16055 }
16056 run_test 160e "changelog negative testing (should return errors)"
16057
16058 test_160f() {
16059         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16060         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16061                 skip "Need MDS version at least 2.10.56"
16062
16063         local mdts=$(comma_list $(mdts_nodes))
16064
16065         # Create a user
16066         changelog_register || error "first changelog_register failed"
16067         changelog_register || error "second changelog_register failed"
16068         local cl_users
16069         declare -A cl_user1
16070         declare -A cl_user2
16071         local user_rec1
16072         local user_rec2
16073         local i
16074
16075         # generate some changelog records to accumulate on each MDT
16076         # use all_char because created files should be evenly distributed
16077         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16078                 error "test_mkdir $tdir failed"
16079         log "$(date +%s): creating first files"
16080         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16081                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16082                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16083         done
16084
16085         # check changelogs have been generated
16086         local start=$SECONDS
16087         local idle_time=$((MDSCOUNT * 5 + 5))
16088         local nbcl=$(changelog_dump | wc -l)
16089         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16090
16091         for param in "changelog_max_idle_time=$idle_time" \
16092                      "changelog_gc=1" \
16093                      "changelog_min_gc_interval=2" \
16094                      "changelog_min_free_cat_entries=3"; do
16095                 local MDT0=$(facet_svc $SINGLEMDS)
16096                 local var="${param%=*}"
16097                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16098
16099                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16100                 do_nodes $mdts $LCTL set_param mdd.*.$param
16101         done
16102
16103         # force cl_user2 to be idle (1st part), but also cancel the
16104         # cl_user1 records so that it is not evicted later in the test.
16105         local sleep1=$((idle_time / 2))
16106         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16107         sleep $sleep1
16108
16109         # simulate changelog catalog almost full
16110         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16111         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16112
16113         for i in $(seq $MDSCOUNT); do
16114                 cl_users=(${CL_USERS[mds$i]})
16115                 cl_user1[mds$i]="${cl_users[0]}"
16116                 cl_user2[mds$i]="${cl_users[1]}"
16117
16118                 [ -n "${cl_user1[mds$i]}" ] ||
16119                         error "mds$i: no user registered"
16120                 [ -n "${cl_user2[mds$i]}" ] ||
16121                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16122
16123                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16124                 [ -n "$user_rec1" ] ||
16125                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16126                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16127                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16128                 [ -n "$user_rec2" ] ||
16129                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16130                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16131                      "$user_rec1 + 2 == $user_rec2"
16132                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16133                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16134                               "$user_rec1 + 2, but is $user_rec2"
16135                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16136                 [ -n "$user_rec2" ] ||
16137                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16138                 [ $user_rec1 == $user_rec2 ] ||
16139                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16140                               "$user_rec1, but is $user_rec2"
16141         done
16142
16143         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16144         local sleep2=$((idle_time - (SECONDS - start) + 1))
16145         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16146         sleep $sleep2
16147
16148         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16149         # cl_user1 should be OK because it recently processed records.
16150         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16151         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16152                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16153                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16154         done
16155
16156         # ensure gc thread is done
16157         for i in $(mdts_nodes); do
16158                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16159                         error "$i: GC-thread not done"
16160         done
16161
16162         local first_rec
16163         for (( i = 1; i <= MDSCOUNT; i++ )); do
16164                 # check cl_user1 still registered
16165                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16166                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16167                 # check cl_user2 unregistered
16168                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16169                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16170
16171                 # check changelogs are present and starting at $user_rec1 + 1
16172                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16173                 [ -n "$user_rec1" ] ||
16174                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16175                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16176                             awk '{ print $1; exit; }')
16177
16178                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16179                 [ $((user_rec1 + 1)) == $first_rec ] ||
16180                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16181         done
16182 }
16183 run_test 160f "changelog garbage collect (timestamped users)"
16184
16185 test_160g() {
16186         remote_mds_nodsh && skip "remote MDS with nodsh"
16187         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16188                 skip "Need MDS version at least 2.14.55"
16189
16190         local mdts=$(comma_list $(mdts_nodes))
16191
16192         # Create a user
16193         changelog_register || error "first changelog_register failed"
16194         changelog_register || error "second changelog_register failed"
16195         local cl_users
16196         declare -A cl_user1
16197         declare -A cl_user2
16198         local user_rec1
16199         local user_rec2
16200         local i
16201
16202         # generate some changelog records to accumulate on each MDT
16203         # use all_char because created files should be evenly distributed
16204         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16205                 error "test_mkdir $tdir failed"
16206         for ((i = 0; i < MDSCOUNT; i++)); do
16207                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16208                         error "create $DIR/$tdir/d$i.1 failed"
16209         done
16210
16211         # check changelogs have been generated
16212         local nbcl=$(changelog_dump | wc -l)
16213         (( $nbcl > 0 )) || error "no changelogs found"
16214
16215         # reduce the max_idle_indexes value to make sure we exceed it
16216         for param in "changelog_max_idle_indexes=2" \
16217                      "changelog_gc=1" \
16218                      "changelog_min_gc_interval=2"; do
16219                 local MDT0=$(facet_svc $SINGLEMDS)
16220                 local var="${param%=*}"
16221                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16222
16223                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16224                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16225                         error "unable to set mdd.*.$param"
16226         done
16227
16228         local start=$SECONDS
16229         for i in $(seq $MDSCOUNT); do
16230                 cl_users=(${CL_USERS[mds$i]})
16231                 cl_user1[mds$i]="${cl_users[0]}"
16232                 cl_user2[mds$i]="${cl_users[1]}"
16233
16234                 [ -n "${cl_user1[mds$i]}" ] ||
16235                         error "mds$i: user1 is not registered"
16236                 [ -n "${cl_user2[mds$i]}" ] ||
16237                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16238
16239                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16240                 [ -n "$user_rec1" ] ||
16241                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16242                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16243                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16244                 [ -n "$user_rec2" ] ||
16245                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16246                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16247                      "$user_rec1 + 2 == $user_rec2"
16248                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16249                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16250                               "expected $user_rec1 + 2, but is $user_rec2"
16251                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16252                 [ -n "$user_rec2" ] ||
16253                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16254                 [ $user_rec1 == $user_rec2 ] ||
16255                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16256                               "expected $user_rec1, but is $user_rec2"
16257         done
16258
16259         # ensure we are past the previous changelog_min_gc_interval set above
16260         local sleep2=$((start + 2 - SECONDS))
16261         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16262         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16263         # cl_user1 should be OK because it recently processed records.
16264         for ((i = 0; i < MDSCOUNT; i++)); do
16265                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16266                         error "create $DIR/$tdir/d$i.3 failed"
16267         done
16268
16269         # ensure gc thread is done
16270         for i in $(mdts_nodes); do
16271                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16272                         error "$i: GC-thread not done"
16273         done
16274
16275         local first_rec
16276         for (( i = 1; i <= MDSCOUNT; i++ )); do
16277                 # check cl_user1 still registered
16278                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16279                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16280                 # check cl_user2 unregistered
16281                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16282                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16283
16284                 # check changelogs are present and starting at $user_rec1 + 1
16285                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16286                 [ -n "$user_rec1" ] ||
16287                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16288                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16289                             awk '{ print $1; exit; }')
16290
16291                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16292                 [ $((user_rec1 + 1)) == $first_rec ] ||
16293                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16294         done
16295 }
16296 run_test 160g "changelog garbage collect on idle records"
16297
16298 test_160h() {
16299         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16300         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16301                 skip "Need MDS version at least 2.10.56"
16302
16303         local mdts=$(comma_list $(mdts_nodes))
16304
16305         # Create a user
16306         changelog_register || error "first changelog_register failed"
16307         changelog_register || error "second changelog_register failed"
16308         local cl_users
16309         declare -A cl_user1
16310         declare -A cl_user2
16311         local user_rec1
16312         local user_rec2
16313         local i
16314
16315         # generate some changelog records to accumulate on each MDT
16316         # use all_char because created files should be evenly distributed
16317         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16318                 error "test_mkdir $tdir failed"
16319         for ((i = 0; i < MDSCOUNT; i++)); do
16320                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16321                         error "create $DIR/$tdir/d$i.1 failed"
16322         done
16323
16324         # check changelogs have been generated
16325         local nbcl=$(changelog_dump | wc -l)
16326         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16327
16328         for param in "changelog_max_idle_time=10" \
16329                      "changelog_gc=1" \
16330                      "changelog_min_gc_interval=2"; do
16331                 local MDT0=$(facet_svc $SINGLEMDS)
16332                 local var="${param%=*}"
16333                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16334
16335                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16336                 do_nodes $mdts $LCTL set_param mdd.*.$param
16337         done
16338
16339         # force cl_user2 to be idle (1st part)
16340         sleep 9
16341
16342         for i in $(seq $MDSCOUNT); do
16343                 cl_users=(${CL_USERS[mds$i]})
16344                 cl_user1[mds$i]="${cl_users[0]}"
16345                 cl_user2[mds$i]="${cl_users[1]}"
16346
16347                 [ -n "${cl_user1[mds$i]}" ] ||
16348                         error "mds$i: no user registered"
16349                 [ -n "${cl_user2[mds$i]}" ] ||
16350                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16351
16352                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16353                 [ -n "$user_rec1" ] ||
16354                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16355                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16356                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16357                 [ -n "$user_rec2" ] ||
16358                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16359                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16360                      "$user_rec1 + 2 == $user_rec2"
16361                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16362                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16363                               "$user_rec1 + 2, but is $user_rec2"
16364                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16365                 [ -n "$user_rec2" ] ||
16366                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16367                 [ $user_rec1 == $user_rec2 ] ||
16368                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16369                               "$user_rec1, but is $user_rec2"
16370         done
16371
16372         # force cl_user2 to be idle (2nd part) and to reach
16373         # changelog_max_idle_time
16374         sleep 2
16375
16376         # force each GC-thread start and block then
16377         # one per MDT/MDD, set fail_val accordingly
16378         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16379         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16380
16381         # generate more changelogs to trigger fail_loc
16382         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16383                 error "create $DIR/$tdir/${tfile}bis failed"
16384
16385         # stop MDT to stop GC-thread, should be done in back-ground as it will
16386         # block waiting for the thread to be released and exit
16387         declare -A stop_pids
16388         for i in $(seq $MDSCOUNT); do
16389                 stop mds$i &
16390                 stop_pids[mds$i]=$!
16391         done
16392
16393         for i in $(mdts_nodes); do
16394                 local facet
16395                 local nb=0
16396                 local facets=$(facets_up_on_host $i)
16397
16398                 for facet in ${facets//,/ }; do
16399                         if [[ $facet == mds* ]]; then
16400                                 nb=$((nb + 1))
16401                         fi
16402                 done
16403                 # ensure each MDS's gc threads are still present and all in "R"
16404                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16405                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16406                         error "$i: expected $nb GC-thread"
16407                 wait_update $i \
16408                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16409                         "R" 20 ||
16410                         error "$i: GC-thread not found in R-state"
16411                 # check umounts of each MDT on MDS have reached kthread_stop()
16412                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16413                         error "$i: expected $nb umount"
16414                 wait_update $i \
16415                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16416                         error "$i: umount not found in D-state"
16417         done
16418
16419         # release all GC-threads
16420         do_nodes $mdts $LCTL set_param fail_loc=0
16421
16422         # wait for MDT stop to complete
16423         for i in $(seq $MDSCOUNT); do
16424                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16425         done
16426
16427         # XXX
16428         # may try to check if any orphan changelog records are present
16429         # via ldiskfs/zfs and llog_reader...
16430
16431         # re-start/mount MDTs
16432         for i in $(seq $MDSCOUNT); do
16433                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16434                         error "Fail to start mds$i"
16435         done
16436
16437         local first_rec
16438         for i in $(seq $MDSCOUNT); do
16439                 # check cl_user1 still registered
16440                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16441                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16442                 # check cl_user2 unregistered
16443                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16444                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16445
16446                 # check changelogs are present and starting at $user_rec1 + 1
16447                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16448                 [ -n "$user_rec1" ] ||
16449                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16450                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16451                             awk '{ print $1; exit; }')
16452
16453                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16454                 [ $((user_rec1 + 1)) == $first_rec ] ||
16455                         error "mds$i: first index should be $user_rec1 + 1, " \
16456                               "but is $first_rec"
16457         done
16458 }
16459 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16460               "during mount"
16461
16462 test_160i() {
16463
16464         local mdts=$(comma_list $(mdts_nodes))
16465
16466         changelog_register || error "first changelog_register failed"
16467
16468         # generate some changelog records to accumulate on each MDT
16469         # use all_char because created files should be evenly distributed
16470         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16471                 error "test_mkdir $tdir failed"
16472         for ((i = 0; i < MDSCOUNT; i++)); do
16473                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16474                         error "create $DIR/$tdir/d$i.1 failed"
16475         done
16476
16477         # check changelogs have been generated
16478         local nbcl=$(changelog_dump | wc -l)
16479         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16480
16481         # simulate race between register and unregister
16482         # XXX as fail_loc is set per-MDS, with DNE configs the race
16483         # simulation will only occur for one MDT per MDS and for the
16484         # others the normal race scenario will take place
16485         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16486         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16487         do_nodes $mdts $LCTL set_param fail_val=1
16488
16489         # unregister 1st user
16490         changelog_deregister &
16491         local pid1=$!
16492         # wait some time for deregister work to reach race rdv
16493         sleep 2
16494         # register 2nd user
16495         changelog_register || error "2nd user register failed"
16496
16497         wait $pid1 || error "1st user deregister failed"
16498
16499         local i
16500         local last_rec
16501         declare -A LAST_REC
16502         for i in $(seq $MDSCOUNT); do
16503                 if changelog_users mds$i | grep "^cl"; then
16504                         # make sure new records are added with one user present
16505                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16506                                           awk '/^current.index:/ { print $NF }')
16507                 else
16508                         error "mds$i has no user registered"
16509                 fi
16510         done
16511
16512         # generate more changelog records to accumulate on each MDT
16513         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16514                 error "create $DIR/$tdir/${tfile}bis failed"
16515
16516         for i in $(seq $MDSCOUNT); do
16517                 last_rec=$(changelog_users $SINGLEMDS |
16518                            awk '/^current.index:/ { print $NF }')
16519                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16520                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16521                         error "changelogs are off on mds$i"
16522         done
16523 }
16524 run_test 160i "changelog user register/unregister race"
16525
16526 test_160j() {
16527         remote_mds_nodsh && skip "remote MDS with nodsh"
16528         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16529                 skip "Need MDS version at least 2.12.56"
16530
16531         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16532         stack_trap "umount $MOUNT2" EXIT
16533
16534         changelog_register || error "first changelog_register failed"
16535         stack_trap "changelog_deregister" EXIT
16536
16537         # generate some changelog
16538         # use all_char because created files should be evenly distributed
16539         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16540                 error "mkdir $tdir failed"
16541         for ((i = 0; i < MDSCOUNT; i++)); do
16542                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16543                         error "create $DIR/$tdir/d$i.1 failed"
16544         done
16545
16546         # open the changelog device
16547         exec 3>/dev/changelog-$FSNAME-MDT0000
16548         stack_trap "exec 3>&-" EXIT
16549         exec 4</dev/changelog-$FSNAME-MDT0000
16550         stack_trap "exec 4<&-" EXIT
16551
16552         # umount the first lustre mount
16553         umount $MOUNT
16554         stack_trap "mount_client $MOUNT" EXIT
16555
16556         # read changelog, which may or may not fail, but should not crash
16557         cat <&4 >/dev/null
16558
16559         # clear changelog
16560         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16561         changelog_users $SINGLEMDS | grep -q $cl_user ||
16562                 error "User $cl_user not found in changelog_users"
16563
16564         printf 'clear:'$cl_user':0' >&3
16565 }
16566 run_test 160j "client can be umounted while its chanangelog is being used"
16567
16568 test_160k() {
16569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16570         remote_mds_nodsh && skip "remote MDS with nodsh"
16571
16572         mkdir -p $DIR/$tdir/1/1
16573
16574         changelog_register || error "changelog_register failed"
16575         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16576
16577         changelog_users $SINGLEMDS | grep -q $cl_user ||
16578                 error "User '$cl_user' not found in changelog_users"
16579 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16580         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16581         rmdir $DIR/$tdir/1/1 & sleep 1
16582         mkdir $DIR/$tdir/2
16583         touch $DIR/$tdir/2/2
16584         rm -rf $DIR/$tdir/2
16585
16586         wait
16587         sleep 4
16588
16589         changelog_dump | grep rmdir || error "rmdir not recorded"
16590 }
16591 run_test 160k "Verify that changelog records are not lost"
16592
16593 # Verifies that a file passed as a parameter has recently had an operation
16594 # performed on it that has generated an MTIME changelog which contains the
16595 # correct parent FID. As files might reside on a different MDT from the
16596 # parent directory in DNE configurations, the FIDs are translated to paths
16597 # before being compared, which should be identical
16598 compare_mtime_changelog() {
16599         local file="${1}"
16600         local mdtidx
16601         local mtime
16602         local cl_fid
16603         local pdir
16604         local dir
16605
16606         mdtidx=$($LFS getstripe --mdt-index $file)
16607         mdtidx=$(printf "%04x" $mdtidx)
16608
16609         # Obtain the parent FID from the MTIME changelog
16610         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16611         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16612
16613         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16614         [ -z "$cl_fid" ] && error "parent FID not present"
16615
16616         # Verify that the path for the parent FID is the same as the path for
16617         # the test directory
16618         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16619
16620         dir=$(dirname $1)
16621
16622         [[ "${pdir%/}" == "$dir" ]] ||
16623                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16624 }
16625
16626 test_160l() {
16627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16628
16629         remote_mds_nodsh && skip "remote MDS with nodsh"
16630         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16631                 skip "Need MDS version at least 2.13.55"
16632
16633         local cl_user
16634
16635         changelog_register || error "changelog_register failed"
16636         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16637
16638         changelog_users $SINGLEMDS | grep -q $cl_user ||
16639                 error "User '$cl_user' not found in changelog_users"
16640
16641         # Clear some types so that MTIME changelogs are generated
16642         changelog_chmask "-CREAT"
16643         changelog_chmask "-CLOSE"
16644
16645         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16646
16647         # Test CL_MTIME during setattr
16648         touch $DIR/$tdir/$tfile
16649         compare_mtime_changelog $DIR/$tdir/$tfile
16650
16651         # Test CL_MTIME during close
16652         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16653         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16654 }
16655 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16656
16657 test_160m() {
16658         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16659         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16660                 skip "Need MDS version at least 2.14.51"
16661         local cl_users
16662         local cl_user1
16663         local cl_user2
16664         local pid1
16665
16666         # Create a user
16667         changelog_register || error "first changelog_register failed"
16668         changelog_register || error "second changelog_register failed"
16669
16670         cl_users=(${CL_USERS[mds1]})
16671         cl_user1="${cl_users[0]}"
16672         cl_user2="${cl_users[1]}"
16673         # generate some changelog records to accumulate on MDT0
16674         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16675         createmany -m $DIR/$tdir/$tfile 50 ||
16676                 error "create $DIR/$tdir/$tfile failed"
16677         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16678         rm -f $DIR/$tdir
16679
16680         # check changelogs have been generated
16681         local nbcl=$(changelog_dump | wc -l)
16682         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16683
16684 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16685         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16686
16687         __changelog_clear mds1 $cl_user1 +10
16688         __changelog_clear mds1 $cl_user2 0 &
16689         pid1=$!
16690         sleep 2
16691         __changelog_clear mds1 $cl_user1 0 ||
16692                 error "fail to cancel record for $cl_user1"
16693         wait $pid1
16694         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16695 }
16696 run_test 160m "Changelog clear race"
16697
16698 test_160n() {
16699         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16700         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16701                 skip "Need MDS version at least 2.14.51"
16702         local cl_users
16703         local cl_user1
16704         local cl_user2
16705         local pid1
16706         local first_rec
16707         local last_rec=0
16708
16709         # Create a user
16710         changelog_register || error "first changelog_register failed"
16711
16712         cl_users=(${CL_USERS[mds1]})
16713         cl_user1="${cl_users[0]}"
16714
16715         # generate some changelog records to accumulate on MDT0
16716         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16717         first_rec=$(changelog_users $SINGLEMDS |
16718                         awk '/^current.index:/ { print $NF }')
16719         while (( last_rec < (( first_rec + 65000)) )); do
16720                 createmany -m $DIR/$tdir/$tfile 10000 ||
16721                         error "create $DIR/$tdir/$tfile failed"
16722
16723                 for i in $(seq 0 10000); do
16724                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16725                                 > /dev/null
16726                 done
16727
16728                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16729                         error "unlinkmany failed unlink"
16730                 last_rec=$(changelog_users $SINGLEMDS |
16731                         awk '/^current.index:/ { print $NF }')
16732                 echo last record $last_rec
16733                 (( last_rec == 0 )) && error "no changelog found"
16734         done
16735
16736 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16737         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16738
16739         __changelog_clear mds1 $cl_user1 0 &
16740         pid1=$!
16741         sleep 2
16742         __changelog_clear mds1 $cl_user1 0 ||
16743                 error "fail to cancel record for $cl_user1"
16744         wait $pid1
16745         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16746 }
16747 run_test 160n "Changelog destroy race"
16748
16749 test_160o() {
16750         local mdt="$(facet_svc $SINGLEMDS)"
16751
16752         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16753         remote_mds_nodsh && skip "remote MDS with nodsh"
16754         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16755                 skip "Need MDS version at least 2.14.52"
16756
16757         changelog_register --user test_160o -m unlnk+close+open ||
16758                 error "changelog_register failed"
16759
16760         do_facet $SINGLEMDS $LCTL --device $mdt \
16761                                 changelog_register -u "Tt3_-#" &&
16762                 error "bad symbols in name should fail"
16763
16764         do_facet $SINGLEMDS $LCTL --device $mdt \
16765                                 changelog_register -u test_160o &&
16766                 error "the same name registration should fail"
16767
16768         do_facet $SINGLEMDS $LCTL --device $mdt \
16769                         changelog_register -u test_160toolongname &&
16770                 error "too long name registration should fail"
16771
16772         changelog_chmask "MARK+HSM"
16773         lctl get_param mdd.*.changelog*mask
16774         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16775         changelog_users $SINGLEMDS | grep -q $cl_user ||
16776                 error "User $cl_user not found in changelog_users"
16777         #verify username
16778         echo $cl_user | grep -q test_160o ||
16779                 error "User $cl_user has no specific name 'test160o'"
16780
16781         # change something
16782         changelog_clear 0 || error "changelog_clear failed"
16783         # generate some changelog records to accumulate on MDT0
16784         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16785         touch $DIR/$tdir/$tfile                 # open 1
16786
16787         OPENS=$(changelog_dump | grep -c "OPEN")
16788         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16789
16790         # must be no MKDIR it wasn't set as user mask
16791         MKDIR=$(changelog_dump | grep -c "MKDIR")
16792         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16793
16794         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16795                                 mdd.$mdt.changelog_current_mask -n)
16796         # register maskless user
16797         changelog_register || error "changelog_register failed"
16798         # effective mask should be not changed because it is not minimal
16799         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16800                                 mdd.$mdt.changelog_current_mask -n)
16801         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16802         # set server mask to minimal value
16803         changelog_chmask "MARK"
16804         # check effective mask again, should be treated as DEFMASK now
16805         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16806                                 mdd.$mdt.changelog_current_mask -n)
16807         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16808
16809         do_facet $SINGLEMDS $LCTL --device $mdt \
16810                                 changelog_deregister -u test_160o ||
16811                 error "cannot deregister by name"
16812 }
16813 run_test 160o "changelog user name and mask"
16814
16815 test_160p() {
16816         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16817         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16818                 skip "Need MDS version at least 2.14.51"
16819         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16820         local cl_users
16821         local cl_user1
16822         local entry_count
16823
16824         # Create a user
16825         changelog_register || error "first changelog_register failed"
16826
16827         cl_users=(${CL_USERS[mds1]})
16828         cl_user1="${cl_users[0]}"
16829
16830         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16831         createmany -m $DIR/$tdir/$tfile 50 ||
16832                 error "create $DIR/$tdir/$tfile failed"
16833         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16834         rm -rf $DIR/$tdir
16835
16836         # check changelogs have been generated
16837         entry_count=$(changelog_dump | wc -l)
16838         ((entry_count != 0)) || error "no changelog entries found"
16839
16840         # remove changelog_users and check that orphan entries are removed
16841         stop mds1
16842         local dev=$(mdsdevname 1)
16843         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16844         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16845         entry_count=$(changelog_dump | wc -l)
16846         ((entry_count == 0)) ||
16847                 error "found $entry_count changelog entries, expected none"
16848 }
16849 run_test 160p "Changelog orphan cleanup with no users"
16850
16851 test_160q() {
16852         local mdt="$(facet_svc $SINGLEMDS)"
16853         local clu
16854
16855         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16856         remote_mds_nodsh && skip "remote MDS with nodsh"
16857         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16858                 skip "Need MDS version at least 2.14.54"
16859
16860         # set server mask to minimal value like server init does
16861         changelog_chmask "MARK"
16862         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16863                 error "changelog_register failed"
16864         # check effective mask again, should be treated as DEFMASK now
16865         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16866                                 mdd.$mdt.changelog_current_mask -n)
16867         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16868                 error "changelog_deregister failed"
16869         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16870 }
16871 run_test 160q "changelog effective mask is DEFMASK if not set"
16872
16873 test_160s() {
16874         remote_mds_nodsh && skip "remote MDS with nodsh"
16875         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16876                 skip "Need MDS version at least 2.14.55"
16877
16878         local mdts=$(comma_list $(mdts_nodes))
16879
16880         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16881         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16882                                        fail_val=$((24 * 3600 * 10))
16883
16884         # Create a user which is 10 days old
16885         changelog_register || error "first changelog_register failed"
16886         local cl_users
16887         declare -A cl_user1
16888         local i
16889
16890         # generate some changelog records to accumulate on each MDT
16891         # use all_char because created files should be evenly distributed
16892         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16893                 error "test_mkdir $tdir failed"
16894         for ((i = 0; i < MDSCOUNT; i++)); do
16895                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16896                         error "create $DIR/$tdir/d$i.1 failed"
16897         done
16898
16899         # check changelogs have been generated
16900         local nbcl=$(changelog_dump | wc -l)
16901         (( nbcl > 0 )) || error "no changelogs found"
16902
16903         # reduce the max_idle_indexes value to make sure we exceed it
16904         for param in "changelog_max_idle_indexes=2097446912" \
16905                      "changelog_max_idle_time=2592000" \
16906                      "changelog_gc=1" \
16907                      "changelog_min_gc_interval=2"; do
16908                 local MDT0=$(facet_svc $SINGLEMDS)
16909                 local var="${param%=*}"
16910                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16911
16912                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16913                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16914                         error "unable to set mdd.*.$param"
16915         done
16916
16917         local start=$SECONDS
16918         for i in $(seq $MDSCOUNT); do
16919                 cl_users=(${CL_USERS[mds$i]})
16920                 cl_user1[mds$i]="${cl_users[0]}"
16921
16922                 [[ -n "${cl_user1[mds$i]}" ]] ||
16923                         error "mds$i: no user registered"
16924         done
16925
16926         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16927         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16928
16929         # ensure we are past the previous changelog_min_gc_interval set above
16930         local sleep2=$((start + 2 - SECONDS))
16931         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16932
16933         # Generate one more changelog to trigger GC
16934         for ((i = 0; i < MDSCOUNT; i++)); do
16935                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16936                         error "create $DIR/$tdir/d$i.3 failed"
16937         done
16938
16939         # ensure gc thread is done
16940         for node in $(mdts_nodes); do
16941                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16942                         error "$node: GC-thread not done"
16943         done
16944
16945         do_nodes $mdts $LCTL set_param fail_loc=0
16946
16947         for (( i = 1; i <= MDSCOUNT; i++ )); do
16948                 # check cl_user1 is purged
16949                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16950                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16951         done
16952         return 0
16953 }
16954 run_test 160s "changelog garbage collect on idle records * time"
16955
16956 test_161a() {
16957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16958
16959         test_mkdir -c1 $DIR/$tdir
16960         cp /etc/hosts $DIR/$tdir/$tfile
16961         test_mkdir -c1 $DIR/$tdir/foo1
16962         test_mkdir -c1 $DIR/$tdir/foo2
16963         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16964         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16965         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16966         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16967         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16968         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16969                 $LFS fid2path $DIR $FID
16970                 error "bad link ea"
16971         fi
16972         # middle
16973         rm $DIR/$tdir/foo2/zachary
16974         # last
16975         rm $DIR/$tdir/foo2/thor
16976         # first
16977         rm $DIR/$tdir/$tfile
16978         # rename
16979         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16980         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16981                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16982         rm $DIR/$tdir/foo2/maggie
16983
16984         # overflow the EA
16985         local longname=$tfile.avg_len_is_thirty_two_
16986         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16987                 error_noexit 'failed to unlink many hardlinks'" EXIT
16988         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16989                 error "failed to hardlink many files"
16990         links=$($LFS fid2path $DIR $FID | wc -l)
16991         echo -n "${links}/1000 links in link EA"
16992         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16993 }
16994 run_test 161a "link ea sanity"
16995
16996 test_161b() {
16997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16998         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16999
17000         local MDTIDX=1
17001         local remote_dir=$DIR/$tdir/remote_dir
17002
17003         mkdir -p $DIR/$tdir
17004         $LFS mkdir -i $MDTIDX $remote_dir ||
17005                 error "create remote directory failed"
17006
17007         cp /etc/hosts $remote_dir/$tfile
17008         mkdir -p $remote_dir/foo1
17009         mkdir -p $remote_dir/foo2
17010         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17011         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17012         ln $remote_dir/$tfile $remote_dir/foo1/luna
17013         ln $remote_dir/$tfile $remote_dir/foo2/thor
17014
17015         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17016                      tr -d ']')
17017         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17018                 $LFS fid2path $DIR $FID
17019                 error "bad link ea"
17020         fi
17021         # middle
17022         rm $remote_dir/foo2/zachary
17023         # last
17024         rm $remote_dir/foo2/thor
17025         # first
17026         rm $remote_dir/$tfile
17027         # rename
17028         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17029         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17030         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17031                 $LFS fid2path $DIR $FID
17032                 error "bad link rename"
17033         fi
17034         rm $remote_dir/foo2/maggie
17035
17036         # overflow the EA
17037         local longname=filename_avg_len_is_thirty_two_
17038         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17039                 error "failed to hardlink many files"
17040         links=$($LFS fid2path $DIR $FID | wc -l)
17041         echo -n "${links}/1000 links in link EA"
17042         [[ ${links} -gt 60 ]] ||
17043                 error "expected at least 60 links in link EA"
17044         unlinkmany $remote_dir/foo2/$longname 1000 ||
17045         error "failed to unlink many hardlinks"
17046 }
17047 run_test 161b "link ea sanity under remote directory"
17048
17049 test_161c() {
17050         remote_mds_nodsh && skip "remote MDS with nodsh"
17051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17052         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17053                 skip "Need MDS version at least 2.1.5"
17054
17055         # define CLF_RENAME_LAST 0x0001
17056         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17057         changelog_register || error "changelog_register failed"
17058
17059         rm -rf $DIR/$tdir
17060         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17061         touch $DIR/$tdir/foo_161c
17062         touch $DIR/$tdir/bar_161c
17063         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17064         changelog_dump | grep RENME | tail -n 5
17065         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17066         changelog_clear 0 || error "changelog_clear failed"
17067         if [ x$flags != "x0x1" ]; then
17068                 error "flag $flags is not 0x1"
17069         fi
17070
17071         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17072         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17073         touch $DIR/$tdir/foo_161c
17074         touch $DIR/$tdir/bar_161c
17075         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17076         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17077         changelog_dump | grep RENME | tail -n 5
17078         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17079         changelog_clear 0 || error "changelog_clear failed"
17080         if [ x$flags != "x0x0" ]; then
17081                 error "flag $flags is not 0x0"
17082         fi
17083         echo "rename overwrite a target having nlink > 1," \
17084                 "changelog record has flags of $flags"
17085
17086         # rename doesn't overwrite a target (changelog flag 0x0)
17087         touch $DIR/$tdir/foo_161c
17088         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17089         changelog_dump | grep RENME | tail -n 5
17090         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17091         changelog_clear 0 || error "changelog_clear failed"
17092         if [ x$flags != "x0x0" ]; then
17093                 error "flag $flags is not 0x0"
17094         fi
17095         echo "rename doesn't overwrite a target," \
17096                 "changelog record has flags of $flags"
17097
17098         # define CLF_UNLINK_LAST 0x0001
17099         # unlink a file having nlink = 1 (changelog flag 0x1)
17100         rm -f $DIR/$tdir/foo2_161c
17101         changelog_dump | grep UNLNK | tail -n 5
17102         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17103         changelog_clear 0 || error "changelog_clear failed"
17104         if [ x$flags != "x0x1" ]; then
17105                 error "flag $flags is not 0x1"
17106         fi
17107         echo "unlink a file having nlink = 1," \
17108                 "changelog record has flags of $flags"
17109
17110         # unlink a file having nlink > 1 (changelog flag 0x0)
17111         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17112         rm -f $DIR/$tdir/foobar_161c
17113         changelog_dump | grep UNLNK | tail -n 5
17114         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17115         changelog_clear 0 || error "changelog_clear failed"
17116         if [ x$flags != "x0x0" ]; then
17117                 error "flag $flags is not 0x0"
17118         fi
17119         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17120 }
17121 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17122
17123 test_161d() {
17124         remote_mds_nodsh && skip "remote MDS with nodsh"
17125         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17126
17127         local pid
17128         local fid
17129
17130         changelog_register || error "changelog_register failed"
17131
17132         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17133         # interfer with $MOUNT/.lustre/fid/ access
17134         mkdir $DIR/$tdir
17135         [[ $? -eq 0 ]] || error "mkdir failed"
17136
17137         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17138         $LCTL set_param fail_loc=0x8000140c
17139         # 5s pause
17140         $LCTL set_param fail_val=5
17141
17142         # create file
17143         echo foofoo > $DIR/$tdir/$tfile &
17144         pid=$!
17145
17146         # wait for create to be delayed
17147         sleep 2
17148
17149         ps -p $pid
17150         [[ $? -eq 0 ]] || error "create should be blocked"
17151
17152         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17153         stack_trap "rm -f $tempfile"
17154         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17155         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17156         # some delay may occur during ChangeLog publishing and file read just
17157         # above, that could allow file write to happen finally
17158         [[ -s $tempfile ]] && echo "file should be empty"
17159
17160         $LCTL set_param fail_loc=0
17161
17162         wait $pid
17163         [[ $? -eq 0 ]] || error "create failed"
17164 }
17165 run_test 161d "create with concurrent .lustre/fid access"
17166
17167 check_path() {
17168         local expected="$1"
17169         shift
17170         local fid="$2"
17171
17172         local path
17173         path=$($LFS fid2path "$@")
17174         local rc=$?
17175
17176         if [ $rc -ne 0 ]; then
17177                 error "path looked up of '$expected' failed: rc=$rc"
17178         elif [ "$path" != "$expected" ]; then
17179                 error "path looked up '$path' instead of '$expected'"
17180         else
17181                 echo "FID '$fid' resolves to path '$path' as expected"
17182         fi
17183 }
17184
17185 test_162a() { # was test_162
17186         test_mkdir -p -c1 $DIR/$tdir/d2
17187         touch $DIR/$tdir/d2/$tfile
17188         touch $DIR/$tdir/d2/x1
17189         touch $DIR/$tdir/d2/x2
17190         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17191         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17192         # regular file
17193         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17194         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17195
17196         # softlink
17197         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17198         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17199         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17200
17201         # softlink to wrong file
17202         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17203         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17204         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17205
17206         # hardlink
17207         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17208         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17209         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17210         # fid2path dir/fsname should both work
17211         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17212         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17213
17214         # hardlink count: check that there are 2 links
17215         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17216         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17217
17218         # hardlink indexing: remove the first link
17219         rm $DIR/$tdir/d2/p/q/r/hlink
17220         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17221 }
17222 run_test 162a "path lookup sanity"
17223
17224 test_162b() {
17225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17226         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17227
17228         mkdir $DIR/$tdir
17229         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17230                                 error "create striped dir failed"
17231
17232         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17233                                         tail -n 1 | awk '{print $2}')
17234         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17235
17236         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17237         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17238
17239         # regular file
17240         for ((i=0;i<5;i++)); do
17241                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17242                         error "get fid for f$i failed"
17243                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17244
17245                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17246                         error "get fid for d$i failed"
17247                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17248         done
17249
17250         return 0
17251 }
17252 run_test 162b "striped directory path lookup sanity"
17253
17254 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17255 test_162c() {
17256         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17257                 skip "Need MDS version at least 2.7.51"
17258
17259         local lpath=$tdir.local
17260         local rpath=$tdir.remote
17261
17262         test_mkdir $DIR/$lpath
17263         test_mkdir $DIR/$rpath
17264
17265         for ((i = 0; i <= 101; i++)); do
17266                 lpath="$lpath/$i"
17267                 mkdir $DIR/$lpath
17268                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17269                         error "get fid for local directory $DIR/$lpath failed"
17270                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17271
17272                 rpath="$rpath/$i"
17273                 test_mkdir $DIR/$rpath
17274                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17275                         error "get fid for remote directory $DIR/$rpath failed"
17276                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17277         done
17278
17279         return 0
17280 }
17281 run_test 162c "fid2path works with paths 100 or more directories deep"
17282
17283 oalr_event_count() {
17284         local event="${1}"
17285         local trace="${2}"
17286
17287         awk -v name="${FSNAME}-OST0000" \
17288             -v event="${event}" \
17289             '$1 == "TRACE" && $2 == event && $3 == name' \
17290             "${trace}" |
17291         wc -l
17292 }
17293
17294 oalr_expect_event_count() {
17295         local event="${1}"
17296         local trace="${2}"
17297         local expect="${3}"
17298         local count
17299
17300         count=$(oalr_event_count "${event}" "${trace}")
17301         if ((count == expect)); then
17302                 return 0
17303         fi
17304
17305         error_noexit "${event} event count was '${count}', expected ${expect}"
17306         cat "${trace}" >&2
17307         exit 1
17308 }
17309
17310 cleanup_165() {
17311         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17312         stop ost1
17313         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17314 }
17315
17316 setup_165() {
17317         sync # Flush previous IOs so we can count log entries.
17318         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17319         stack_trap cleanup_165 EXIT
17320 }
17321
17322 test_165a() {
17323         local trace="/tmp/${tfile}.trace"
17324         local rc
17325         local count
17326
17327         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17328                 skip "OFD access log unsupported"
17329
17330         setup_165
17331         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17332         sleep 5
17333
17334         do_facet ost1 ofd_access_log_reader --list
17335         stop ost1
17336
17337         do_facet ost1 killall -TERM ofd_access_log_reader
17338         wait
17339         rc=$?
17340
17341         if ((rc != 0)); then
17342                 error "ofd_access_log_reader exited with rc = '${rc}'"
17343         fi
17344
17345         # Parse trace file for discovery events:
17346         oalr_expect_event_count alr_log_add "${trace}" 1
17347         oalr_expect_event_count alr_log_eof "${trace}" 1
17348         oalr_expect_event_count alr_log_free "${trace}" 1
17349 }
17350 run_test 165a "ofd access log discovery"
17351
17352 test_165b() {
17353         local trace="/tmp/${tfile}.trace"
17354         local file="${DIR}/${tfile}"
17355         local pfid1
17356         local pfid2
17357         local -a entry
17358         local rc
17359         local count
17360         local size
17361         local flags
17362
17363         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17364                 skip "OFD access log unsupported"
17365
17366         setup_165
17367         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17368         sleep 5
17369
17370         do_facet ost1 ofd_access_log_reader --list
17371
17372         lfs setstripe -c 1 -i 0 "${file}"
17373         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17374                 error "cannot create '${file}'"
17375
17376         sleep 5
17377         do_facet ost1 killall -TERM ofd_access_log_reader
17378         wait
17379         rc=$?
17380
17381         if ((rc != 0)); then
17382                 error "ofd_access_log_reader exited with rc = '${rc}'"
17383         fi
17384
17385         oalr_expect_event_count alr_log_entry "${trace}" 1
17386
17387         pfid1=$($LFS path2fid "${file}")
17388
17389         # 1     2             3   4    5     6   7    8    9     10
17390         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17391         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17392
17393         echo "entry = '${entry[*]}'" >&2
17394
17395         pfid2=${entry[4]}
17396         if [[ "${pfid1}" != "${pfid2}" ]]; then
17397                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17398         fi
17399
17400         size=${entry[8]}
17401         if ((size != 1048576)); then
17402                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17403         fi
17404
17405         flags=${entry[10]}
17406         if [[ "${flags}" != "w" ]]; then
17407                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17408         fi
17409
17410         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17411         sleep 5
17412
17413         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17414                 error "cannot read '${file}'"
17415         sleep 5
17416
17417         do_facet ost1 killall -TERM ofd_access_log_reader
17418         wait
17419         rc=$?
17420
17421         if ((rc != 0)); then
17422                 error "ofd_access_log_reader exited with rc = '${rc}'"
17423         fi
17424
17425         oalr_expect_event_count alr_log_entry "${trace}" 1
17426
17427         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17428         echo "entry = '${entry[*]}'" >&2
17429
17430         pfid2=${entry[4]}
17431         if [[ "${pfid1}" != "${pfid2}" ]]; then
17432                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17433         fi
17434
17435         size=${entry[8]}
17436         if ((size != 524288)); then
17437                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17438         fi
17439
17440         flags=${entry[10]}
17441         if [[ "${flags}" != "r" ]]; then
17442                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17443         fi
17444 }
17445 run_test 165b "ofd access log entries are produced and consumed"
17446
17447 test_165c() {
17448         local trace="/tmp/${tfile}.trace"
17449         local file="${DIR}/${tdir}/${tfile}"
17450
17451         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17452                 skip "OFD access log unsupported"
17453
17454         test_mkdir "${DIR}/${tdir}"
17455
17456         setup_165
17457         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17458         sleep 5
17459
17460         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17461
17462         # 4096 / 64 = 64. Create twice as many entries.
17463         for ((i = 0; i < 128; i++)); do
17464                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17465                         error "cannot create file"
17466         done
17467
17468         sync
17469
17470         do_facet ost1 killall -TERM ofd_access_log_reader
17471         wait
17472         rc=$?
17473         if ((rc != 0)); then
17474                 error "ofd_access_log_reader exited with rc = '${rc}'"
17475         fi
17476
17477         unlinkmany  "${file}-%d" 128
17478 }
17479 run_test 165c "full ofd access logs do not block IOs"
17480
17481 oal_get_read_count() {
17482         local stats="$1"
17483
17484         # STATS lustre-OST0001 alr_read_count 1
17485
17486         do_facet ost1 cat "${stats}" |
17487         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17488              END { print count; }'
17489 }
17490
17491 oal_expect_read_count() {
17492         local stats="$1"
17493         local count
17494         local expect="$2"
17495
17496         # Ask ofd_access_log_reader to write stats.
17497         do_facet ost1 killall -USR1 ofd_access_log_reader
17498
17499         # Allow some time for things to happen.
17500         sleep 1
17501
17502         count=$(oal_get_read_count "${stats}")
17503         if ((count == expect)); then
17504                 return 0
17505         fi
17506
17507         error_noexit "bad read count, got ${count}, expected ${expect}"
17508         do_facet ost1 cat "${stats}" >&2
17509         exit 1
17510 }
17511
17512 test_165d() {
17513         local stats="/tmp/${tfile}.stats"
17514         local file="${DIR}/${tdir}/${tfile}"
17515         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17516
17517         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17518                 skip "OFD access log unsupported"
17519
17520         test_mkdir "${DIR}/${tdir}"
17521
17522         setup_165
17523         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17524         sleep 5
17525
17526         lfs setstripe -c 1 -i 0 "${file}"
17527
17528         do_facet ost1 lctl set_param "${param}=rw"
17529         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17530                 error "cannot create '${file}'"
17531         oal_expect_read_count "${stats}" 1
17532
17533         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17534                 error "cannot read '${file}'"
17535         oal_expect_read_count "${stats}" 2
17536
17537         do_facet ost1 lctl set_param "${param}=r"
17538         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17539                 error "cannot create '${file}'"
17540         oal_expect_read_count "${stats}" 2
17541
17542         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17543                 error "cannot read '${file}'"
17544         oal_expect_read_count "${stats}" 3
17545
17546         do_facet ost1 lctl set_param "${param}=w"
17547         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17548                 error "cannot create '${file}'"
17549         oal_expect_read_count "${stats}" 4
17550
17551         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17552                 error "cannot read '${file}'"
17553         oal_expect_read_count "${stats}" 4
17554
17555         do_facet ost1 lctl set_param "${param}=0"
17556         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17557                 error "cannot create '${file}'"
17558         oal_expect_read_count "${stats}" 4
17559
17560         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17561                 error "cannot read '${file}'"
17562         oal_expect_read_count "${stats}" 4
17563
17564         do_facet ost1 killall -TERM ofd_access_log_reader
17565         wait
17566         rc=$?
17567         if ((rc != 0)); then
17568                 error "ofd_access_log_reader exited with rc = '${rc}'"
17569         fi
17570 }
17571 run_test 165d "ofd_access_log mask works"
17572
17573 test_165e() {
17574         local stats="/tmp/${tfile}.stats"
17575         local file0="${DIR}/${tdir}-0/${tfile}"
17576         local file1="${DIR}/${tdir}-1/${tfile}"
17577
17578         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17579                 skip "OFD access log unsupported"
17580
17581         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17582
17583         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17584         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17585
17586         lfs setstripe -c 1 -i 0 "${file0}"
17587         lfs setstripe -c 1 -i 0 "${file1}"
17588
17589         setup_165
17590         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17591         sleep 5
17592
17593         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17594                 error "cannot create '${file0}'"
17595         sync
17596         oal_expect_read_count "${stats}" 0
17597
17598         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17599                 error "cannot create '${file1}'"
17600         sync
17601         oal_expect_read_count "${stats}" 1
17602
17603         do_facet ost1 killall -TERM ofd_access_log_reader
17604         wait
17605         rc=$?
17606         if ((rc != 0)); then
17607                 error "ofd_access_log_reader exited with rc = '${rc}'"
17608         fi
17609 }
17610 run_test 165e "ofd_access_log MDT index filter works"
17611
17612 test_165f() {
17613         local trace="/tmp/${tfile}.trace"
17614         local rc
17615         local count
17616
17617         setup_165
17618         do_facet ost1 timeout 60 ofd_access_log_reader \
17619                 --exit-on-close --debug=- --trace=- > "${trace}" &
17620         sleep 5
17621         stop ost1
17622
17623         wait
17624         rc=$?
17625
17626         if ((rc != 0)); then
17627                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17628                 cat "${trace}"
17629                 exit 1
17630         fi
17631 }
17632 run_test 165f "ofd_access_log_reader --exit-on-close works"
17633
17634 test_169() {
17635         # do directio so as not to populate the page cache
17636         log "creating a 10 Mb file"
17637         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17638                 error "multiop failed while creating a file"
17639         log "starting reads"
17640         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17641         log "truncating the file"
17642         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17643                 error "multiop failed while truncating the file"
17644         log "killing dd"
17645         kill %+ || true # reads might have finished
17646         echo "wait until dd is finished"
17647         wait
17648         log "removing the temporary file"
17649         rm -rf $DIR/$tfile || error "tmp file removal failed"
17650 }
17651 run_test 169 "parallel read and truncate should not deadlock"
17652
17653 test_170() {
17654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17655
17656         $LCTL clear     # bug 18514
17657         $LCTL debug_daemon start $TMP/${tfile}_log_good
17658         touch $DIR/$tfile
17659         $LCTL debug_daemon stop
17660         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17661                 error "sed failed to read log_good"
17662
17663         $LCTL debug_daemon start $TMP/${tfile}_log_good
17664         rm -rf $DIR/$tfile
17665         $LCTL debug_daemon stop
17666
17667         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17668                error "lctl df log_bad failed"
17669
17670         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17671         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17672
17673         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17674         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17675
17676         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17677                 error "bad_line good_line1 good_line2 are empty"
17678
17679         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17680         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17681         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17682
17683         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17684         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17685         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17686
17687         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17688                 error "bad_line_new good_line_new are empty"
17689
17690         local expected_good=$((good_line1 + good_line2*2))
17691
17692         rm -f $TMP/${tfile}*
17693         # LU-231, short malformed line may not be counted into bad lines
17694         if [ $bad_line -ne $bad_line_new ] &&
17695                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17696                 error "expected $bad_line bad lines, but got $bad_line_new"
17697                 return 1
17698         fi
17699
17700         if [ $expected_good -ne $good_line_new ]; then
17701                 error "expected $expected_good good lines, but got $good_line_new"
17702                 return 2
17703         fi
17704         true
17705 }
17706 run_test 170 "test lctl df to handle corrupted log ====================="
17707
17708 test_171() { # bug20592
17709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17710
17711         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17712         $LCTL set_param fail_loc=0x50e
17713         $LCTL set_param fail_val=3000
17714         multiop_bg_pause $DIR/$tfile O_s || true
17715         local MULTIPID=$!
17716         kill -USR1 $MULTIPID
17717         # cause log dump
17718         sleep 3
17719         wait $MULTIPID
17720         if dmesg | grep "recursive fault"; then
17721                 error "caught a recursive fault"
17722         fi
17723         $LCTL set_param fail_loc=0
17724         true
17725 }
17726 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17727
17728 # it would be good to share it with obdfilter-survey/iokit-libecho code
17729 setup_obdecho_osc () {
17730         local rc=0
17731         local ost_nid=$1
17732         local obdfilter_name=$2
17733         echo "Creating new osc for $obdfilter_name on $ost_nid"
17734         # make sure we can find loopback nid
17735         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17736
17737         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17738                            ${obdfilter_name}_osc_UUID || rc=2; }
17739         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17740                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17741         return $rc
17742 }
17743
17744 cleanup_obdecho_osc () {
17745         local obdfilter_name=$1
17746         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17747         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17748         return 0
17749 }
17750
17751 obdecho_test() {
17752         local OBD=$1
17753         local node=$2
17754         local pages=${3:-64}
17755         local rc=0
17756         local id
17757
17758         local count=10
17759         local obd_size=$(get_obd_size $node $OBD)
17760         local page_size=$(get_page_size $node)
17761         if [[ -n "$obd_size" ]]; then
17762                 local new_count=$((obd_size / (pages * page_size / 1024)))
17763                 [[ $new_count -ge $count ]] || count=$new_count
17764         fi
17765
17766         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17767         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17768                            rc=2; }
17769         if [ $rc -eq 0 ]; then
17770             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17771             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17772         fi
17773         echo "New object id is $id"
17774         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17775                            rc=4; }
17776         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17777                            "test_brw $count w v $pages $id" || rc=4; }
17778         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17779                            rc=4; }
17780         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17781                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17782         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17783                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17784         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17785         return $rc
17786 }
17787
17788 test_180a() {
17789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17790
17791         if ! [ -d /sys/fs/lustre/echo_client ] &&
17792            ! module_loaded obdecho; then
17793                 load_module obdecho/obdecho &&
17794                         stack_trap "rmmod obdecho" EXIT ||
17795                         error "unable to load obdecho on client"
17796         fi
17797
17798         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17799         local host=$($LCTL get_param -n osc.$osc.import |
17800                      awk '/current_connection:/ { print $2 }' )
17801         local target=$($LCTL get_param -n osc.$osc.import |
17802                        awk '/target:/ { print $2 }' )
17803         target=${target%_UUID}
17804
17805         if [ -n "$target" ]; then
17806                 setup_obdecho_osc $host $target &&
17807                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17808                         { error "obdecho setup failed with $?"; return; }
17809
17810                 obdecho_test ${target}_osc client ||
17811                         error "obdecho_test failed on ${target}_osc"
17812         else
17813                 $LCTL get_param osc.$osc.import
17814                 error "there is no osc.$osc.import target"
17815         fi
17816 }
17817 run_test 180a "test obdecho on osc"
17818
17819 test_180b() {
17820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17821         remote_ost_nodsh && skip "remote OST with nodsh"
17822
17823         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17824                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17825                 error "failed to load module obdecho"
17826
17827         local target=$(do_facet ost1 $LCTL dl |
17828                        awk '/obdfilter/ { print $4; exit; }')
17829
17830         if [ -n "$target" ]; then
17831                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17832         else
17833                 do_facet ost1 $LCTL dl
17834                 error "there is no obdfilter target on ost1"
17835         fi
17836 }
17837 run_test 180b "test obdecho directly on obdfilter"
17838
17839 test_180c() { # LU-2598
17840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17841         remote_ost_nodsh && skip "remote OST with nodsh"
17842         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17843                 skip "Need MDS version at least 2.4.0"
17844
17845         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17846                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17847                 error "failed to load module obdecho"
17848
17849         local target=$(do_facet ost1 $LCTL dl |
17850                        awk '/obdfilter/ { print $4; exit; }')
17851
17852         if [ -n "$target" ]; then
17853                 local pages=16384 # 64MB bulk I/O RPC size
17854
17855                 obdecho_test "$target" ost1 "$pages" ||
17856                         error "obdecho_test with pages=$pages failed with $?"
17857         else
17858                 do_facet ost1 $LCTL dl
17859                 error "there is no obdfilter target on ost1"
17860         fi
17861 }
17862 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17863
17864 test_181() { # bug 22177
17865         test_mkdir $DIR/$tdir
17866         # create enough files to index the directory
17867         createmany -o $DIR/$tdir/foobar 4000
17868         # print attributes for debug purpose
17869         lsattr -d .
17870         # open dir
17871         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17872         MULTIPID=$!
17873         # remove the files & current working dir
17874         unlinkmany $DIR/$tdir/foobar 4000
17875         rmdir $DIR/$tdir
17876         kill -USR1 $MULTIPID
17877         wait $MULTIPID
17878         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17879         return 0
17880 }
17881 run_test 181 "Test open-unlinked dir ========================"
17882
17883 test_182() {
17884         local fcount=1000
17885         local tcount=10
17886
17887         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17888
17889         $LCTL set_param mdc.*.rpc_stats=clear
17890
17891         for (( i = 0; i < $tcount; i++ )) ; do
17892                 mkdir $DIR/$tdir/$i
17893         done
17894
17895         for (( i = 0; i < $tcount; i++ )) ; do
17896                 createmany -o $DIR/$tdir/$i/f- $fcount &
17897         done
17898         wait
17899
17900         for (( i = 0; i < $tcount; i++ )) ; do
17901                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17902         done
17903         wait
17904
17905         $LCTL get_param mdc.*.rpc_stats
17906
17907         rm -rf $DIR/$tdir
17908 }
17909 run_test 182 "Test parallel modify metadata operations ================"
17910
17911 test_183() { # LU-2275
17912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17913         remote_mds_nodsh && skip "remote MDS with nodsh"
17914         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17915                 skip "Need MDS version at least 2.3.56"
17916
17917         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17918         echo aaa > $DIR/$tdir/$tfile
17919
17920 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17921         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17922
17923         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17924         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17925
17926         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17927
17928         # Flush negative dentry cache
17929         touch $DIR/$tdir/$tfile
17930
17931         # We are not checking for any leaked references here, they'll
17932         # become evident next time we do cleanup with module unload.
17933         rm -rf $DIR/$tdir
17934 }
17935 run_test 183 "No crash or request leak in case of strange dispositions ========"
17936
17937 # test suite 184 is for LU-2016, LU-2017
17938 test_184a() {
17939         check_swap_layouts_support
17940
17941         dir0=$DIR/$tdir/$testnum
17942         test_mkdir -p -c1 $dir0
17943         ref1=/etc/passwd
17944         ref2=/etc/group
17945         file1=$dir0/f1
17946         file2=$dir0/f2
17947         $LFS setstripe -c1 $file1
17948         cp $ref1 $file1
17949         $LFS setstripe -c2 $file2
17950         cp $ref2 $file2
17951         gen1=$($LFS getstripe -g $file1)
17952         gen2=$($LFS getstripe -g $file2)
17953
17954         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17955         gen=$($LFS getstripe -g $file1)
17956         [[ $gen1 != $gen ]] ||
17957                 error "Layout generation on $file1 does not change"
17958         gen=$($LFS getstripe -g $file2)
17959         [[ $gen2 != $gen ]] ||
17960                 error "Layout generation on $file2 does not change"
17961
17962         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17963         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17964
17965         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17966 }
17967 run_test 184a "Basic layout swap"
17968
17969 test_184b() {
17970         check_swap_layouts_support
17971
17972         dir0=$DIR/$tdir/$testnum
17973         mkdir -p $dir0 || error "creating dir $dir0"
17974         file1=$dir0/f1
17975         file2=$dir0/f2
17976         file3=$dir0/f3
17977         dir1=$dir0/d1
17978         dir2=$dir0/d2
17979         mkdir $dir1 $dir2
17980         $LFS setstripe -c1 $file1
17981         $LFS setstripe -c2 $file2
17982         $LFS setstripe -c1 $file3
17983         chown $RUNAS_ID $file3
17984         gen1=$($LFS getstripe -g $file1)
17985         gen2=$($LFS getstripe -g $file2)
17986
17987         $LFS swap_layouts $dir1 $dir2 &&
17988                 error "swap of directories layouts should fail"
17989         $LFS swap_layouts $dir1 $file1 &&
17990                 error "swap of directory and file layouts should fail"
17991         $RUNAS $LFS swap_layouts $file1 $file2 &&
17992                 error "swap of file we cannot write should fail"
17993         $LFS swap_layouts $file1 $file3 &&
17994                 error "swap of file with different owner should fail"
17995         /bin/true # to clear error code
17996 }
17997 run_test 184b "Forbidden layout swap (will generate errors)"
17998
17999 test_184c() {
18000         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18001         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18002         check_swap_layouts_support
18003         check_swap_layout_no_dom $DIR
18004
18005         local dir0=$DIR/$tdir/$testnum
18006         mkdir -p $dir0 || error "creating dir $dir0"
18007
18008         local ref1=$dir0/ref1
18009         local ref2=$dir0/ref2
18010         local file1=$dir0/file1
18011         local file2=$dir0/file2
18012         # create a file large enough for the concurrent test
18013         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18014         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18015         echo "ref file size: ref1($(stat -c %s $ref1))," \
18016              "ref2($(stat -c %s $ref2))"
18017
18018         cp $ref2 $file2
18019         dd if=$ref1 of=$file1 bs=16k &
18020         local DD_PID=$!
18021
18022         # Make sure dd starts to copy file, but wait at most 5 seconds
18023         local loops=0
18024         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18025
18026         $LFS swap_layouts $file1 $file2
18027         local rc=$?
18028         wait $DD_PID
18029         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18030         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18031
18032         # how many bytes copied before swapping layout
18033         local copied=$(stat -c %s $file2)
18034         local remaining=$(stat -c %s $ref1)
18035         remaining=$((remaining - copied))
18036         echo "Copied $copied bytes before swapping layout..."
18037
18038         cmp -n $copied $file1 $ref2 | grep differ &&
18039                 error "Content mismatch [0, $copied) of ref2 and file1"
18040         cmp -n $copied $file2 $ref1 ||
18041                 error "Content mismatch [0, $copied) of ref1 and file2"
18042         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18043                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18044
18045         # clean up
18046         rm -f $ref1 $ref2 $file1 $file2
18047 }
18048 run_test 184c "Concurrent write and layout swap"
18049
18050 test_184d() {
18051         check_swap_layouts_support
18052         check_swap_layout_no_dom $DIR
18053         [ -z "$(which getfattr 2>/dev/null)" ] &&
18054                 skip_env "no getfattr command"
18055
18056         local file1=$DIR/$tdir/$tfile-1
18057         local file2=$DIR/$tdir/$tfile-2
18058         local file3=$DIR/$tdir/$tfile-3
18059         local lovea1
18060         local lovea2
18061
18062         mkdir -p $DIR/$tdir
18063         touch $file1 || error "create $file1 failed"
18064         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18065                 error "create $file2 failed"
18066         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18067                 error "create $file3 failed"
18068         lovea1=$(get_layout_param $file1)
18069
18070         $LFS swap_layouts $file2 $file3 ||
18071                 error "swap $file2 $file3 layouts failed"
18072         $LFS swap_layouts $file1 $file2 ||
18073                 error "swap $file1 $file2 layouts failed"
18074
18075         lovea2=$(get_layout_param $file2)
18076         echo "$lovea1"
18077         echo "$lovea2"
18078         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18079
18080         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18081         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18082 }
18083 run_test 184d "allow stripeless layouts swap"
18084
18085 test_184e() {
18086         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18087                 skip "Need MDS version at least 2.6.94"
18088         check_swap_layouts_support
18089         check_swap_layout_no_dom $DIR
18090         [ -z "$(which getfattr 2>/dev/null)" ] &&
18091                 skip_env "no getfattr command"
18092
18093         local file1=$DIR/$tdir/$tfile-1
18094         local file2=$DIR/$tdir/$tfile-2
18095         local file3=$DIR/$tdir/$tfile-3
18096         local lovea
18097
18098         mkdir -p $DIR/$tdir
18099         touch $file1 || error "create $file1 failed"
18100         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18101                 error "create $file2 failed"
18102         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18103                 error "create $file3 failed"
18104
18105         $LFS swap_layouts $file1 $file2 ||
18106                 error "swap $file1 $file2 layouts failed"
18107
18108         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18109         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18110
18111         echo 123 > $file1 || error "Should be able to write into $file1"
18112
18113         $LFS swap_layouts $file1 $file3 ||
18114                 error "swap $file1 $file3 layouts failed"
18115
18116         echo 123 > $file1 || error "Should be able to write into $file1"
18117
18118         rm -rf $file1 $file2 $file3
18119 }
18120 run_test 184e "Recreate layout after stripeless layout swaps"
18121
18122 test_184f() {
18123         # Create a file with name longer than sizeof(struct stat) ==
18124         # 144 to see if we can get chars from the file name to appear
18125         # in the returned striping. Note that 'f' == 0x66.
18126         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18127
18128         mkdir -p $DIR/$tdir
18129         mcreate $DIR/$tdir/$file
18130         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18131                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18132         fi
18133 }
18134 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18135
18136 test_185() { # LU-2441
18137         # LU-3553 - no volatile file support in old servers
18138         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18139                 skip "Need MDS version at least 2.3.60"
18140
18141         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18142         touch $DIR/$tdir/spoo
18143         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18144         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18145                 error "cannot create/write a volatile file"
18146         [ "$FILESET" == "" ] &&
18147         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18148                 error "FID is still valid after close"
18149
18150         multiop_bg_pause $DIR/$tdir vVw4096_c
18151         local multi_pid=$!
18152
18153         local OLD_IFS=$IFS
18154         IFS=":"
18155         local fidv=($fid)
18156         IFS=$OLD_IFS
18157         # assume that the next FID for this client is sequential, since stdout
18158         # is unfortunately eaten by multiop_bg_pause
18159         local n=$((${fidv[1]} + 1))
18160         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18161         if [ "$FILESET" == "" ]; then
18162                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18163                         error "FID is missing before close"
18164         fi
18165         kill -USR1 $multi_pid
18166         # 1 second delay, so if mtime change we will see it
18167         sleep 1
18168         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18169         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18170 }
18171 run_test 185 "Volatile file support"
18172
18173 function create_check_volatile() {
18174         local idx=$1
18175         local tgt
18176
18177         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18178         local PID=$!
18179         sleep 1
18180         local FID=$(cat /tmp/${tfile}.fid)
18181         [ "$FID" == "" ] && error "can't get FID for volatile"
18182         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18183         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18184         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18185         kill -USR1 $PID
18186         wait
18187         sleep 1
18188         cancel_lru_locks mdc # flush opencache
18189         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18190         return 0
18191 }
18192
18193 test_185a(){
18194         # LU-12516 - volatile creation via .lustre
18195         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18196                 skip "Need MDS version at least 2.3.55"
18197
18198         create_check_volatile 0
18199         [ $MDSCOUNT -lt 2 ] && return 0
18200
18201         # DNE case
18202         create_check_volatile 1
18203
18204         return 0
18205 }
18206 run_test 185a "Volatile file creation in .lustre/fid/"
18207
18208 test_187a() {
18209         remote_mds_nodsh && skip "remote MDS with nodsh"
18210         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18211                 skip "Need MDS version at least 2.3.0"
18212
18213         local dir0=$DIR/$tdir/$testnum
18214         mkdir -p $dir0 || error "creating dir $dir0"
18215
18216         local file=$dir0/file1
18217         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18218         local dv1=$($LFS data_version $file)
18219         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18220         local dv2=$($LFS data_version $file)
18221         [[ $dv1 != $dv2 ]] ||
18222                 error "data version did not change on write $dv1 == $dv2"
18223
18224         # clean up
18225         rm -f $file1
18226 }
18227 run_test 187a "Test data version change"
18228
18229 test_187b() {
18230         remote_mds_nodsh && skip "remote MDS with nodsh"
18231         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18232                 skip "Need MDS version at least 2.3.0"
18233
18234         local dir0=$DIR/$tdir/$testnum
18235         mkdir -p $dir0 || error "creating dir $dir0"
18236
18237         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18238         [[ ${DV[0]} != ${DV[1]} ]] ||
18239                 error "data version did not change on write"\
18240                       " ${DV[0]} == ${DV[1]}"
18241
18242         # clean up
18243         rm -f $file1
18244 }
18245 run_test 187b "Test data version change on volatile file"
18246
18247 test_200() {
18248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18249         remote_mgs_nodsh && skip "remote MGS with nodsh"
18250         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18251
18252         local POOL=${POOL:-cea1}
18253         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18254         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18255         # Pool OST targets
18256         local first_ost=0
18257         local last_ost=$(($OSTCOUNT - 1))
18258         local ost_step=2
18259         local ost_list=$(seq $first_ost $ost_step $last_ost)
18260         local ost_range="$first_ost $last_ost $ost_step"
18261         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18262         local file_dir=$POOL_ROOT/file_tst
18263         local subdir=$test_path/subdir
18264         local rc=0
18265
18266         while : ; do
18267                 # former test_200a test_200b
18268                 pool_add $POOL                          || { rc=$? ; break; }
18269                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18270                 # former test_200c test_200d
18271                 mkdir -p $test_path
18272                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18273                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18274                 mkdir -p $subdir
18275                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18276                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18277                                                         || { rc=$? ; break; }
18278                 # former test_200e test_200f
18279                 local files=$((OSTCOUNT*3))
18280                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18281                                                         || { rc=$? ; break; }
18282                 pool_create_files $POOL $file_dir $files "$ost_list" \
18283                                                         || { rc=$? ; break; }
18284                 # former test_200g test_200h
18285                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18286                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18287
18288                 # former test_201a test_201b test_201c
18289                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18290
18291                 local f=$test_path/$tfile
18292                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18293                 pool_remove $POOL $f                    || { rc=$? ; break; }
18294                 break
18295         done
18296
18297         destroy_test_pools
18298
18299         return $rc
18300 }
18301 run_test 200 "OST pools"
18302
18303 # usage: default_attr <count | size | offset>
18304 default_attr() {
18305         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18306 }
18307
18308 # usage: check_default_stripe_attr
18309 check_default_stripe_attr() {
18310         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18311         case $1 in
18312         --stripe-count|-c)
18313                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18314         --stripe-size|-S)
18315                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18316         --stripe-index|-i)
18317                 EXPECTED=-1;;
18318         *)
18319                 error "unknown getstripe attr '$1'"
18320         esac
18321
18322         [ $ACTUAL == $EXPECTED ] ||
18323                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18324 }
18325
18326 test_204a() {
18327         test_mkdir $DIR/$tdir
18328         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18329
18330         check_default_stripe_attr --stripe-count
18331         check_default_stripe_attr --stripe-size
18332         check_default_stripe_attr --stripe-index
18333 }
18334 run_test 204a "Print default stripe attributes"
18335
18336 test_204b() {
18337         test_mkdir $DIR/$tdir
18338         $LFS setstripe --stripe-count 1 $DIR/$tdir
18339
18340         check_default_stripe_attr --stripe-size
18341         check_default_stripe_attr --stripe-index
18342 }
18343 run_test 204b "Print default stripe size and offset"
18344
18345 test_204c() {
18346         test_mkdir $DIR/$tdir
18347         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18348
18349         check_default_stripe_attr --stripe-count
18350         check_default_stripe_attr --stripe-index
18351 }
18352 run_test 204c "Print default stripe count and offset"
18353
18354 test_204d() {
18355         test_mkdir $DIR/$tdir
18356         $LFS setstripe --stripe-index 0 $DIR/$tdir
18357
18358         check_default_stripe_attr --stripe-count
18359         check_default_stripe_attr --stripe-size
18360 }
18361 run_test 204d "Print default stripe count and size"
18362
18363 test_204e() {
18364         test_mkdir $DIR/$tdir
18365         $LFS setstripe -d $DIR/$tdir
18366
18367         check_default_stripe_attr --stripe-count --raw
18368         check_default_stripe_attr --stripe-size --raw
18369         check_default_stripe_attr --stripe-index --raw
18370 }
18371 run_test 204e "Print raw stripe attributes"
18372
18373 test_204f() {
18374         test_mkdir $DIR/$tdir
18375         $LFS setstripe --stripe-count 1 $DIR/$tdir
18376
18377         check_default_stripe_attr --stripe-size --raw
18378         check_default_stripe_attr --stripe-index --raw
18379 }
18380 run_test 204f "Print raw stripe size and offset"
18381
18382 test_204g() {
18383         test_mkdir $DIR/$tdir
18384         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18385
18386         check_default_stripe_attr --stripe-count --raw
18387         check_default_stripe_attr --stripe-index --raw
18388 }
18389 run_test 204g "Print raw stripe count and offset"
18390
18391 test_204h() {
18392         test_mkdir $DIR/$tdir
18393         $LFS setstripe --stripe-index 0 $DIR/$tdir
18394
18395         check_default_stripe_attr --stripe-count --raw
18396         check_default_stripe_attr --stripe-size --raw
18397 }
18398 run_test 204h "Print raw stripe count and size"
18399
18400 # Figure out which job scheduler is being used, if any,
18401 # or use a fake one
18402 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18403         JOBENV=SLURM_JOB_ID
18404 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18405         JOBENV=LSB_JOBID
18406 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18407         JOBENV=PBS_JOBID
18408 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18409         JOBENV=LOADL_STEP_ID
18410 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18411         JOBENV=JOB_ID
18412 else
18413         $LCTL list_param jobid_name > /dev/null 2>&1
18414         if [ $? -eq 0 ]; then
18415                 JOBENV=nodelocal
18416         else
18417                 JOBENV=FAKE_JOBID
18418         fi
18419 fi
18420 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18421
18422 verify_jobstats() {
18423         local cmd=($1)
18424         shift
18425         local facets="$@"
18426
18427 # we don't really need to clear the stats for this test to work, since each
18428 # command has a unique jobid, but it makes debugging easier if needed.
18429 #       for facet in $facets; do
18430 #               local dev=$(convert_facet2label $facet)
18431 #               # clear old jobstats
18432 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18433 #       done
18434
18435         # use a new JobID for each test, or we might see an old one
18436         [ "$JOBENV" = "FAKE_JOBID" ] &&
18437                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18438
18439         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18440
18441         [ "$JOBENV" = "nodelocal" ] && {
18442                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18443                 $LCTL set_param jobid_name=$FAKE_JOBID
18444                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18445         }
18446
18447         log "Test: ${cmd[*]}"
18448         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18449
18450         if [ $JOBENV = "FAKE_JOBID" ]; then
18451                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18452         else
18453                 ${cmd[*]}
18454         fi
18455
18456         # all files are created on OST0000
18457         for facet in $facets; do
18458                 local stats="*.$(convert_facet2label $facet).job_stats"
18459
18460                 # strip out libtool wrappers for in-tree executables
18461                 if (( $(do_facet $facet lctl get_param $stats |
18462                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18463                         do_facet $facet lctl get_param $stats
18464                         error "No jobstats for $JOBVAL found on $facet::$stats"
18465                 fi
18466         done
18467 }
18468
18469 jobstats_set() {
18470         local new_jobenv=$1
18471
18472         set_persistent_param_and_check client "jobid_var" \
18473                 "$FSNAME.sys.jobid_var" $new_jobenv
18474 }
18475
18476 test_205a() { # Job stats
18477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18478         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18479                 skip "Need MDS version with at least 2.7.1"
18480         remote_mgs_nodsh && skip "remote MGS with nodsh"
18481         remote_mds_nodsh && skip "remote MDS with nodsh"
18482         remote_ost_nodsh && skip "remote OST with nodsh"
18483         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18484                 skip "Server doesn't support jobstats"
18485         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18486
18487         local old_jobenv=$($LCTL get_param -n jobid_var)
18488         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18489
18490         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18491                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18492         else
18493                 stack_trap "do_facet mgs $PERM_CMD \
18494                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18495         fi
18496         changelog_register
18497
18498         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18499                                 mdt.*.job_cleanup_interval | head -n 1)
18500         local new_interval=5
18501         do_facet $SINGLEMDS \
18502                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18503         stack_trap "do_facet $SINGLEMDS \
18504                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18505         local start=$SECONDS
18506
18507         local cmd
18508         # mkdir
18509         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18510         verify_jobstats "$cmd" "$SINGLEMDS"
18511         # rmdir
18512         cmd="rmdir $DIR/$tdir"
18513         verify_jobstats "$cmd" "$SINGLEMDS"
18514         # mkdir on secondary MDT
18515         if [ $MDSCOUNT -gt 1 ]; then
18516                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18517                 verify_jobstats "$cmd" "mds2"
18518         fi
18519         # mknod
18520         cmd="mknod $DIR/$tfile c 1 3"
18521         verify_jobstats "$cmd" "$SINGLEMDS"
18522         # unlink
18523         cmd="rm -f $DIR/$tfile"
18524         verify_jobstats "$cmd" "$SINGLEMDS"
18525         # create all files on OST0000 so verify_jobstats can find OST stats
18526         # open & close
18527         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18528         verify_jobstats "$cmd" "$SINGLEMDS"
18529         # setattr
18530         cmd="touch $DIR/$tfile"
18531         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18532         # write
18533         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18534         verify_jobstats "$cmd" "ost1"
18535         # read
18536         cancel_lru_locks osc
18537         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18538         verify_jobstats "$cmd" "ost1"
18539         # truncate
18540         cmd="$TRUNCATE $DIR/$tfile 0"
18541         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18542         # rename
18543         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18544         verify_jobstats "$cmd" "$SINGLEMDS"
18545         # jobstats expiry - sleep until old stats should be expired
18546         local left=$((new_interval + 5 - (SECONDS - start)))
18547         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18548                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18549                         "0" $left
18550         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18551         verify_jobstats "$cmd" "$SINGLEMDS"
18552         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18553             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18554
18555         # Ensure that jobid are present in changelog (if supported by MDS)
18556         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18557                 changelog_dump | tail -10
18558                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18559                 [ $jobids -eq 9 ] ||
18560                         error "Wrong changelog jobid count $jobids != 9"
18561
18562                 # LU-5862
18563                 JOBENV="disable"
18564                 jobstats_set $JOBENV
18565                 touch $DIR/$tfile
18566                 changelog_dump | grep $tfile
18567                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18568                 [ $jobids -eq 0 ] ||
18569                         error "Unexpected jobids when jobid_var=$JOBENV"
18570         fi
18571
18572         # test '%j' access to environment variable - if supported
18573         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18574                 JOBENV="JOBCOMPLEX"
18575                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18576
18577                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18578         fi
18579
18580         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18581                 JOBENV="JOBCOMPLEX"
18582                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18583
18584                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18585         fi
18586
18587         # test '%j' access to per-session jobid - if supported
18588         if lctl list_param jobid_this_session > /dev/null 2>&1
18589         then
18590                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18591                 lctl set_param jobid_this_session=$USER
18592
18593                 JOBENV="JOBCOMPLEX"
18594                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18595
18596                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18597         fi
18598 }
18599 run_test 205a "Verify job stats"
18600
18601 # LU-13117, LU-13597
18602 test_205b() {
18603         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18604                 skip "Need MDS version at least 2.13.54.91"
18605
18606         job_stats="mdt.*.job_stats"
18607         $LCTL set_param $job_stats=clear
18608         # Setting jobid_var to USER might not be supported
18609         $LCTL set_param jobid_var=USER || true
18610         $LCTL set_param jobid_name="%e.%u"
18611         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18612         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18613                 grep "job_id:.*foolish" &&
18614                         error "Unexpected jobid found"
18615         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18616                 grep "open:.*min.*max.*sum" ||
18617                         error "wrong job_stats format found"
18618 }
18619 run_test 205b "Verify job stats jobid and output format"
18620
18621 # LU-13733
18622 test_205c() {
18623         $LCTL set_param llite.*.stats=0
18624         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18625         $LCTL get_param llite.*.stats
18626         $LCTL get_param llite.*.stats | grep \
18627                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18628                         error "wrong client stats format found"
18629 }
18630 run_test 205c "Verify client stats format"
18631
18632 # LU-1480, LU-1773 and LU-1657
18633 test_206() {
18634         mkdir -p $DIR/$tdir
18635         $LFS setstripe -c -1 $DIR/$tdir
18636 #define OBD_FAIL_LOV_INIT 0x1403
18637         $LCTL set_param fail_loc=0xa0001403
18638         $LCTL set_param fail_val=1
18639         touch $DIR/$tdir/$tfile || true
18640 }
18641 run_test 206 "fail lov_init_raid0() doesn't lbug"
18642
18643 test_207a() {
18644         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18645         local fsz=`stat -c %s $DIR/$tfile`
18646         cancel_lru_locks mdc
18647
18648         # do not return layout in getattr intent
18649 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18650         $LCTL set_param fail_loc=0x170
18651         local sz=`stat -c %s $DIR/$tfile`
18652
18653         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18654
18655         rm -rf $DIR/$tfile
18656 }
18657 run_test 207a "can refresh layout at glimpse"
18658
18659 test_207b() {
18660         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18661         local cksum=`md5sum $DIR/$tfile`
18662         local fsz=`stat -c %s $DIR/$tfile`
18663         cancel_lru_locks mdc
18664         cancel_lru_locks osc
18665
18666         # do not return layout in getattr intent
18667 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18668         $LCTL set_param fail_loc=0x171
18669
18670         # it will refresh layout after the file is opened but before read issues
18671         echo checksum is "$cksum"
18672         echo "$cksum" |md5sum -c --quiet || error "file differs"
18673
18674         rm -rf $DIR/$tfile
18675 }
18676 run_test 207b "can refresh layout at open"
18677
18678 test_208() {
18679         # FIXME: in this test suite, only RD lease is used. This is okay
18680         # for now as only exclusive open is supported. After generic lease
18681         # is done, this test suite should be revised. - Jinshan
18682
18683         remote_mds_nodsh && skip "remote MDS with nodsh"
18684         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18685                 skip "Need MDS version at least 2.4.52"
18686
18687         echo "==== test 1: verify get lease work"
18688         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18689
18690         echo "==== test 2: verify lease can be broken by upcoming open"
18691         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18692         local PID=$!
18693         sleep 2
18694
18695         $MULTIOP $DIR/$tfile oO_RDWR:c
18696         kill -USR1 $PID && wait $PID || error "break lease error"
18697
18698         echo "==== test 3: verify lease can't be granted if an open already exists"
18699         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18700         local PID=$!
18701         sleep 2
18702
18703         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18704         kill -USR1 $PID && wait $PID || error "open file error"
18705
18706         echo "==== test 4: lease can sustain over recovery"
18707         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18708         PID=$!
18709         sleep 2
18710
18711         fail mds1
18712
18713         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18714
18715         echo "==== test 5: lease broken can't be regained by replay"
18716         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18717         PID=$!
18718         sleep 2
18719
18720         # open file to break lease and then recovery
18721         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18722         fail mds1
18723
18724         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18725
18726         rm -f $DIR/$tfile
18727 }
18728 run_test 208 "Exclusive open"
18729
18730 test_209() {
18731         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18732                 skip_env "must have disp_stripe"
18733
18734         touch $DIR/$tfile
18735         sync; sleep 5; sync;
18736
18737         echo 3 > /proc/sys/vm/drop_caches
18738         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18739                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18740         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18741
18742         # open/close 500 times
18743         for i in $(seq 500); do
18744                 cat $DIR/$tfile
18745         done
18746
18747         echo 3 > /proc/sys/vm/drop_caches
18748         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18749                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18750         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18751
18752         echo "before: $req_before, after: $req_after"
18753         [ $((req_after - req_before)) -ge 300 ] &&
18754                 error "open/close requests are not freed"
18755         return 0
18756 }
18757 run_test 209 "read-only open/close requests should be freed promptly"
18758
18759 test_210() {
18760         local pid
18761
18762         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18763         pid=$!
18764         sleep 1
18765
18766         $LFS getstripe $DIR/$tfile
18767         kill -USR1 $pid
18768         wait $pid || error "multiop failed"
18769
18770         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18771         pid=$!
18772         sleep 1
18773
18774         $LFS getstripe $DIR/$tfile
18775         kill -USR1 $pid
18776         wait $pid || error "multiop failed"
18777 }
18778 run_test 210 "lfs getstripe does not break leases"
18779
18780 test_212() {
18781         size=`date +%s`
18782         size=$((size % 8192 + 1))
18783         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18784         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18785         rm -f $DIR/f212 $DIR/f212.xyz
18786 }
18787 run_test 212 "Sendfile test ============================================"
18788
18789 test_213() {
18790         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18791         cancel_lru_locks osc
18792         lctl set_param fail_loc=0x8000040f
18793         # generate a read lock
18794         cat $DIR/$tfile > /dev/null
18795         # write to the file, it will try to cancel the above read lock.
18796         cat /etc/hosts >> $DIR/$tfile
18797 }
18798 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18799
18800 test_214() { # for bug 20133
18801         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18802         for (( i=0; i < 340; i++ )) ; do
18803                 touch $DIR/$tdir/d214c/a$i
18804         done
18805
18806         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18807         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18808         ls $DIR/d214c || error "ls $DIR/d214c failed"
18809         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18810         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18811 }
18812 run_test 214 "hash-indexed directory test - bug 20133"
18813
18814 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18815 create_lnet_proc_files() {
18816         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18817 }
18818
18819 # counterpart of create_lnet_proc_files
18820 remove_lnet_proc_files() {
18821         rm -f $TMP/lnet_$1.sys
18822 }
18823
18824 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18825 # 3rd arg as regexp for body
18826 check_lnet_proc_stats() {
18827         local l=$(cat "$TMP/lnet_$1" |wc -l)
18828         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18829
18830         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18831 }
18832
18833 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18834 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18835 # optional and can be regexp for 2nd line (lnet.routes case)
18836 check_lnet_proc_entry() {
18837         local blp=2          # blp stands for 'position of 1st line of body'
18838         [ -z "$5" ] || blp=3 # lnet.routes case
18839
18840         local l=$(cat "$TMP/lnet_$1" |wc -l)
18841         # subtracting one from $blp because the body can be empty
18842         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18843
18844         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18845                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18846
18847         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18848                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18849
18850         # bail out if any unexpected line happened
18851         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18852         [ "$?" != 0 ] || error "$2 misformatted"
18853 }
18854
18855 test_215() { # for bugs 18102, 21079, 21517
18856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18857
18858         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18859         local P='[1-9][0-9]*'           # positive numeric
18860         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18861         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18862         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18863         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18864
18865         local L1 # regexp for 1st line
18866         local L2 # regexp for 2nd line (optional)
18867         local BR # regexp for the rest (body)
18868
18869         # lnet.stats should look as 11 space-separated non-negative numerics
18870         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18871         create_lnet_proc_files "stats"
18872         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18873         remove_lnet_proc_files "stats"
18874
18875         # lnet.routes should look like this:
18876         # Routing disabled/enabled
18877         # net hops priority state router
18878         # where net is a string like tcp0, hops > 0, priority >= 0,
18879         # state is up/down,
18880         # router is a string like 192.168.1.1@tcp2
18881         L1="^Routing (disabled|enabled)$"
18882         L2="^net +hops +priority +state +router$"
18883         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18884         create_lnet_proc_files "routes"
18885         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18886         remove_lnet_proc_files "routes"
18887
18888         # lnet.routers should look like this:
18889         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18890         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18891         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18892         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18893         L1="^ref +rtr_ref +alive +router$"
18894         BR="^$P +$P +(up|down) +$NID$"
18895         create_lnet_proc_files "routers"
18896         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18897         remove_lnet_proc_files "routers"
18898
18899         # lnet.peers should look like this:
18900         # nid refs state last max rtr min tx min queue
18901         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18902         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18903         # numeric (0 or >0 or <0), queue >= 0.
18904         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18905         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18906         create_lnet_proc_files "peers"
18907         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18908         remove_lnet_proc_files "peers"
18909
18910         # lnet.buffers  should look like this:
18911         # pages count credits min
18912         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18913         L1="^pages +count +credits +min$"
18914         BR="^ +$N +$N +$I +$I$"
18915         create_lnet_proc_files "buffers"
18916         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18917         remove_lnet_proc_files "buffers"
18918
18919         # lnet.nis should look like this:
18920         # nid status alive refs peer rtr max tx min
18921         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18922         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18923         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18924         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18925         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18926         create_lnet_proc_files "nis"
18927         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18928         remove_lnet_proc_files "nis"
18929
18930         # can we successfully write to lnet.stats?
18931         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18932 }
18933 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18934
18935 test_216() { # bug 20317
18936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18937         remote_ost_nodsh && skip "remote OST with nodsh"
18938
18939         local node
18940         local facets=$(get_facets OST)
18941         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18942
18943         save_lustre_params client "osc.*.contention_seconds" > $p
18944         save_lustre_params $facets \
18945                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18946         save_lustre_params $facets \
18947                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18948         save_lustre_params $facets \
18949                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18950         clear_stats osc.*.osc_stats
18951
18952         # agressive lockless i/o settings
18953         do_nodes $(comma_list $(osts_nodes)) \
18954                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18955                         ldlm.namespaces.filter-*.contended_locks=0 \
18956                         ldlm.namespaces.filter-*.contention_seconds=60"
18957         lctl set_param -n osc.*.contention_seconds=60
18958
18959         $DIRECTIO write $DIR/$tfile 0 10 4096
18960         $CHECKSTAT -s 40960 $DIR/$tfile
18961
18962         # disable lockless i/o
18963         do_nodes $(comma_list $(osts_nodes)) \
18964                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18965                         ldlm.namespaces.filter-*.contended_locks=32 \
18966                         ldlm.namespaces.filter-*.contention_seconds=0"
18967         lctl set_param -n osc.*.contention_seconds=0
18968         clear_stats osc.*.osc_stats
18969
18970         dd if=/dev/zero of=$DIR/$tfile count=0
18971         $CHECKSTAT -s 0 $DIR/$tfile
18972
18973         restore_lustre_params <$p
18974         rm -f $p
18975         rm $DIR/$tfile
18976 }
18977 run_test 216 "check lockless direct write updates file size and kms correctly"
18978
18979 test_217() { # bug 22430
18980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18981
18982         local node
18983         local nid
18984
18985         for node in $(nodes_list); do
18986                 nid=$(host_nids_address $node $NETTYPE)
18987                 if [[ $nid = *-* ]] ; then
18988                         echo "lctl ping $(h2nettype $nid)"
18989                         lctl ping $(h2nettype $nid)
18990                 else
18991                         echo "skipping $node (no hyphen detected)"
18992                 fi
18993         done
18994 }
18995 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18996
18997 test_218() {
18998        # do directio so as not to populate the page cache
18999        log "creating a 10 Mb file"
19000        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19001        log "starting reads"
19002        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19003        log "truncating the file"
19004        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19005        log "killing dd"
19006        kill %+ || true # reads might have finished
19007        echo "wait until dd is finished"
19008        wait
19009        log "removing the temporary file"
19010        rm -rf $DIR/$tfile || error "tmp file removal failed"
19011 }
19012 run_test 218 "parallel read and truncate should not deadlock"
19013
19014 test_219() {
19015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19016
19017         # write one partial page
19018         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19019         # set no grant so vvp_io_commit_write will do sync write
19020         $LCTL set_param fail_loc=0x411
19021         # write a full page at the end of file
19022         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19023
19024         $LCTL set_param fail_loc=0
19025         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19026         $LCTL set_param fail_loc=0x411
19027         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19028
19029         # LU-4201
19030         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19031         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19032 }
19033 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19034
19035 test_220() { #LU-325
19036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19037         remote_ost_nodsh && skip "remote OST with nodsh"
19038         remote_mds_nodsh && skip "remote MDS with nodsh"
19039         remote_mgs_nodsh && skip "remote MGS with nodsh"
19040
19041         local OSTIDX=0
19042
19043         # create on MDT0000 so the last_id and next_id are correct
19044         mkdir_on_mdt0 $DIR/$tdir
19045         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19046         OST=${OST%_UUID}
19047
19048         # on the mdt's osc
19049         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19050         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19051                         osp.$mdtosc_proc1.prealloc_last_id)
19052         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19053                         osp.$mdtosc_proc1.prealloc_next_id)
19054
19055         $LFS df -i
19056
19057         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19058         #define OBD_FAIL_OST_ENOINO              0x229
19059         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19060         create_pool $FSNAME.$TESTNAME || return 1
19061         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19062
19063         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19064
19065         MDSOBJS=$((last_id - next_id))
19066         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19067
19068         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19069         echo "OST still has $count kbytes free"
19070
19071         echo "create $MDSOBJS files @next_id..."
19072         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19073
19074         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19075                         osp.$mdtosc_proc1.prealloc_last_id)
19076         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19077                         osp.$mdtosc_proc1.prealloc_next_id)
19078
19079         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19080         $LFS df -i
19081
19082         echo "cleanup..."
19083
19084         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19085         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19086
19087         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19088                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19089         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19090                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19091         echo "unlink $MDSOBJS files @$next_id..."
19092         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19093 }
19094 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19095
19096 test_221() {
19097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19098
19099         dd if=`which date` of=$MOUNT/date oflag=sync
19100         chmod +x $MOUNT/date
19101
19102         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19103         $LCTL set_param fail_loc=0x80001401
19104
19105         $MOUNT/date > /dev/null
19106         rm -f $MOUNT/date
19107 }
19108 run_test 221 "make sure fault and truncate race to not cause OOM"
19109
19110 test_222a () {
19111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19112
19113         rm -rf $DIR/$tdir
19114         test_mkdir $DIR/$tdir
19115         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19116         createmany -o $DIR/$tdir/$tfile 10
19117         cancel_lru_locks mdc
19118         cancel_lru_locks osc
19119         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19120         $LCTL set_param fail_loc=0x31a
19121         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19122         $LCTL set_param fail_loc=0
19123         rm -r $DIR/$tdir
19124 }
19125 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19126
19127 test_222b () {
19128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19129
19130         rm -rf $DIR/$tdir
19131         test_mkdir $DIR/$tdir
19132         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19133         createmany -o $DIR/$tdir/$tfile 10
19134         cancel_lru_locks mdc
19135         cancel_lru_locks osc
19136         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19137         $LCTL set_param fail_loc=0x31a
19138         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19139         $LCTL set_param fail_loc=0
19140 }
19141 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19142
19143 test_223 () {
19144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19145
19146         rm -rf $DIR/$tdir
19147         test_mkdir $DIR/$tdir
19148         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19149         createmany -o $DIR/$tdir/$tfile 10
19150         cancel_lru_locks mdc
19151         cancel_lru_locks osc
19152         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19153         $LCTL set_param fail_loc=0x31b
19154         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19155         $LCTL set_param fail_loc=0
19156         rm -r $DIR/$tdir
19157 }
19158 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19159
19160 test_224a() { # LU-1039, MRP-303
19161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19162         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19163         $LCTL set_param fail_loc=0x508
19164         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19165         $LCTL set_param fail_loc=0
19166         df $DIR
19167 }
19168 run_test 224a "Don't panic on bulk IO failure"
19169
19170 test_224bd_sub() { # LU-1039, MRP-303
19171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19172         local timeout=$1
19173
19174         shift
19175         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19176
19177         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19178
19179         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19180         cancel_lru_locks osc
19181         set_checksums 0
19182         stack_trap "set_checksums $ORIG_CSUM" EXIT
19183         local at_max_saved=0
19184
19185         # adaptive timeouts may prevent seeing the issue
19186         if at_is_enabled; then
19187                 at_max_saved=$(at_max_get mds)
19188                 at_max_set 0 mds client
19189                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19190         fi
19191
19192         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19193         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19194         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19195
19196         do_facet ost1 $LCTL set_param fail_loc=0
19197         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19198         df $DIR
19199 }
19200
19201 test_224b() {
19202         test_224bd_sub 3 error "dd failed"
19203 }
19204 run_test 224b "Don't panic on bulk IO failure"
19205
19206 test_224c() { # LU-6441
19207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19208         remote_mds_nodsh && skip "remote MDS with nodsh"
19209
19210         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19211         save_writethrough $p
19212         set_cache writethrough on
19213
19214         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19215         local at_max=$($LCTL get_param -n at_max)
19216         local timeout=$($LCTL get_param -n timeout)
19217         local test_at="at_max"
19218         local param_at="$FSNAME.sys.at_max"
19219         local test_timeout="timeout"
19220         local param_timeout="$FSNAME.sys.timeout"
19221
19222         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19223
19224         set_persistent_param_and_check client "$test_at" "$param_at" 0
19225         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19226
19227         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19228         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19229         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19230         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19231         sync
19232         do_facet ost1 "$LCTL set_param fail_loc=0"
19233
19234         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19235         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19236                 $timeout
19237
19238         $LCTL set_param -n $pages_per_rpc
19239         restore_lustre_params < $p
19240         rm -f $p
19241 }
19242 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19243
19244 test_224d() { # LU-11169
19245         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19246 }
19247 run_test 224d "Don't corrupt data on bulk IO timeout"
19248
19249 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19250 test_225a () {
19251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19252         if [ -z ${MDSSURVEY} ]; then
19253                 skip_env "mds-survey not found"
19254         fi
19255         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19256                 skip "Need MDS version at least 2.2.51"
19257
19258         local mds=$(facet_host $SINGLEMDS)
19259         local target=$(do_nodes $mds 'lctl dl' |
19260                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19261
19262         local cmd1="file_count=1000 thrhi=4"
19263         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19264         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19265         local cmd="$cmd1 $cmd2 $cmd3"
19266
19267         rm -f ${TMP}/mds_survey*
19268         echo + $cmd
19269         eval $cmd || error "mds-survey with zero-stripe failed"
19270         cat ${TMP}/mds_survey*
19271         rm -f ${TMP}/mds_survey*
19272 }
19273 run_test 225a "Metadata survey sanity with zero-stripe"
19274
19275 test_225b () {
19276         if [ -z ${MDSSURVEY} ]; then
19277                 skip_env "mds-survey not found"
19278         fi
19279         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19280                 skip "Need MDS version at least 2.2.51"
19281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19282         remote_mds_nodsh && skip "remote MDS with nodsh"
19283         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19284                 skip_env "Need to mount OST to test"
19285         fi
19286
19287         local mds=$(facet_host $SINGLEMDS)
19288         local target=$(do_nodes $mds 'lctl dl' |
19289                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19290
19291         local cmd1="file_count=1000 thrhi=4"
19292         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19293         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19294         local cmd="$cmd1 $cmd2 $cmd3"
19295
19296         rm -f ${TMP}/mds_survey*
19297         echo + $cmd
19298         eval $cmd || error "mds-survey with stripe_count failed"
19299         cat ${TMP}/mds_survey*
19300         rm -f ${TMP}/mds_survey*
19301 }
19302 run_test 225b "Metadata survey sanity with stripe_count = 1"
19303
19304 mcreate_path2fid () {
19305         local mode=$1
19306         local major=$2
19307         local minor=$3
19308         local name=$4
19309         local desc=$5
19310         local path=$DIR/$tdir/$name
19311         local fid
19312         local rc
19313         local fid_path
19314
19315         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19316                 error "cannot create $desc"
19317
19318         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19319         rc=$?
19320         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19321
19322         fid_path=$($LFS fid2path $MOUNT $fid)
19323         rc=$?
19324         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19325
19326         [ "$path" == "$fid_path" ] ||
19327                 error "fid2path returned $fid_path, expected $path"
19328
19329         echo "pass with $path and $fid"
19330 }
19331
19332 test_226a () {
19333         rm -rf $DIR/$tdir
19334         mkdir -p $DIR/$tdir
19335
19336         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19337         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19338         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19339         mcreate_path2fid 0040666 0 0 dir "directory"
19340         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19341         mcreate_path2fid 0100666 0 0 file "regular file"
19342         mcreate_path2fid 0120666 0 0 link "symbolic link"
19343         mcreate_path2fid 0140666 0 0 sock "socket"
19344 }
19345 run_test 226a "call path2fid and fid2path on files of all type"
19346
19347 test_226b () {
19348         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19349
19350         local MDTIDX=1
19351
19352         rm -rf $DIR/$tdir
19353         mkdir -p $DIR/$tdir
19354         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19355                 error "create remote directory failed"
19356         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19357         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19358                                 "character special file (null)"
19359         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19360                                 "character special file (no device)"
19361         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19362         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19363                                 "block special file (loop)"
19364         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19365         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19366         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19367 }
19368 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19369
19370 test_226c () {
19371         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19372         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19373                 skip "Need MDS version at least 2.13.55"
19374
19375         local submnt=/mnt/submnt
19376         local srcfile=/etc/passwd
19377         local dstfile=$submnt/passwd
19378         local path
19379         local fid
19380
19381         rm -rf $DIR/$tdir
19382         rm -rf $submnt
19383         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19384                 error "create remote directory failed"
19385         mkdir -p $submnt || error "create $submnt failed"
19386         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19387                 error "mount $submnt failed"
19388         stack_trap "umount $submnt" EXIT
19389
19390         cp $srcfile $dstfile
19391         fid=$($LFS path2fid $dstfile)
19392         path=$($LFS fid2path $submnt "$fid")
19393         [ "$path" = "$dstfile" ] ||
19394                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19395 }
19396 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19397
19398 # LU-1299 Executing or running ldd on a truncated executable does not
19399 # cause an out-of-memory condition.
19400 test_227() {
19401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19402         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19403
19404         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19405         chmod +x $MOUNT/date
19406
19407         $MOUNT/date > /dev/null
19408         ldd $MOUNT/date > /dev/null
19409         rm -f $MOUNT/date
19410 }
19411 run_test 227 "running truncated executable does not cause OOM"
19412
19413 # LU-1512 try to reuse idle OI blocks
19414 test_228a() {
19415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19416         remote_mds_nodsh && skip "remote MDS with nodsh"
19417         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19418
19419         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19420         local myDIR=$DIR/$tdir
19421
19422         mkdir -p $myDIR
19423         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19424         $LCTL set_param fail_loc=0x80001002
19425         createmany -o $myDIR/t- 10000
19426         $LCTL set_param fail_loc=0
19427         # The guard is current the largest FID holder
19428         touch $myDIR/guard
19429         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19430                     tr -d '[')
19431         local IDX=$(($SEQ % 64))
19432
19433         do_facet $SINGLEMDS sync
19434         # Make sure journal flushed.
19435         sleep 6
19436         local blk1=$(do_facet $SINGLEMDS \
19437                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19438                      grep Blockcount | awk '{print $4}')
19439
19440         # Remove old files, some OI blocks will become idle.
19441         unlinkmany $myDIR/t- 10000
19442         # Create new files, idle OI blocks should be reused.
19443         createmany -o $myDIR/t- 2000
19444         do_facet $SINGLEMDS sync
19445         # Make sure journal flushed.
19446         sleep 6
19447         local blk2=$(do_facet $SINGLEMDS \
19448                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19449                      grep Blockcount | awk '{print $4}')
19450
19451         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19452 }
19453 run_test 228a "try to reuse idle OI blocks"
19454
19455 test_228b() {
19456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19457         remote_mds_nodsh && skip "remote MDS with nodsh"
19458         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19459
19460         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19461         local myDIR=$DIR/$tdir
19462
19463         mkdir -p $myDIR
19464         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19465         $LCTL set_param fail_loc=0x80001002
19466         createmany -o $myDIR/t- 10000
19467         $LCTL set_param fail_loc=0
19468         # The guard is current the largest FID holder
19469         touch $myDIR/guard
19470         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19471                     tr -d '[')
19472         local IDX=$(($SEQ % 64))
19473
19474         do_facet $SINGLEMDS sync
19475         # Make sure journal flushed.
19476         sleep 6
19477         local blk1=$(do_facet $SINGLEMDS \
19478                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19479                      grep Blockcount | awk '{print $4}')
19480
19481         # Remove old files, some OI blocks will become idle.
19482         unlinkmany $myDIR/t- 10000
19483
19484         # stop the MDT
19485         stop $SINGLEMDS || error "Fail to stop MDT."
19486         # remount the MDT
19487         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19488                 error "Fail to start MDT."
19489
19490         df $MOUNT || error "Fail to df."
19491         # Create new files, idle OI blocks should be reused.
19492         createmany -o $myDIR/t- 2000
19493         do_facet $SINGLEMDS sync
19494         # Make sure journal flushed.
19495         sleep 6
19496         local blk2=$(do_facet $SINGLEMDS \
19497                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19498                      grep Blockcount | awk '{print $4}')
19499
19500         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19501 }
19502 run_test 228b "idle OI blocks can be reused after MDT restart"
19503
19504 #LU-1881
19505 test_228c() {
19506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19507         remote_mds_nodsh && skip "remote MDS with nodsh"
19508         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19509
19510         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19511         local myDIR=$DIR/$tdir
19512
19513         mkdir -p $myDIR
19514         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19515         $LCTL set_param fail_loc=0x80001002
19516         # 20000 files can guarantee there are index nodes in the OI file
19517         createmany -o $myDIR/t- 20000
19518         $LCTL set_param fail_loc=0
19519         # The guard is current the largest FID holder
19520         touch $myDIR/guard
19521         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19522                     tr -d '[')
19523         local IDX=$(($SEQ % 64))
19524
19525         do_facet $SINGLEMDS sync
19526         # Make sure journal flushed.
19527         sleep 6
19528         local blk1=$(do_facet $SINGLEMDS \
19529                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19530                      grep Blockcount | awk '{print $4}')
19531
19532         # Remove old files, some OI blocks will become idle.
19533         unlinkmany $myDIR/t- 20000
19534         rm -f $myDIR/guard
19535         # The OI file should become empty now
19536
19537         # Create new files, idle OI blocks should be reused.
19538         createmany -o $myDIR/t- 2000
19539         do_facet $SINGLEMDS sync
19540         # Make sure journal flushed.
19541         sleep 6
19542         local blk2=$(do_facet $SINGLEMDS \
19543                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19544                      grep Blockcount | awk '{print $4}')
19545
19546         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19547 }
19548 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19549
19550 test_229() { # LU-2482, LU-3448
19551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19552         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19553         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19554                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19555
19556         rm -f $DIR/$tfile
19557
19558         # Create a file with a released layout and stripe count 2.
19559         $MULTIOP $DIR/$tfile H2c ||
19560                 error "failed to create file with released layout"
19561
19562         $LFS getstripe -v $DIR/$tfile
19563
19564         local pattern=$($LFS getstripe -L $DIR/$tfile)
19565         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19566
19567         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19568                 error "getstripe"
19569         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19570         stat $DIR/$tfile || error "failed to stat released file"
19571
19572         chown $RUNAS_ID $DIR/$tfile ||
19573                 error "chown $RUNAS_ID $DIR/$tfile failed"
19574
19575         chgrp $RUNAS_ID $DIR/$tfile ||
19576                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19577
19578         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19579         rm $DIR/$tfile || error "failed to remove released file"
19580 }
19581 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19582
19583 test_230a() {
19584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19585         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19586         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19587                 skip "Need MDS version at least 2.11.52"
19588
19589         local MDTIDX=1
19590
19591         test_mkdir $DIR/$tdir
19592         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19593         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19594         [ $mdt_idx -ne 0 ] &&
19595                 error "create local directory on wrong MDT $mdt_idx"
19596
19597         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19598                         error "create remote directory failed"
19599         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19600         [ $mdt_idx -ne $MDTIDX ] &&
19601                 error "create remote directory on wrong MDT $mdt_idx"
19602
19603         createmany -o $DIR/$tdir/test_230/t- 10 ||
19604                 error "create files on remote directory failed"
19605         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19606         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19607         rm -r $DIR/$tdir || error "unlink remote directory failed"
19608 }
19609 run_test 230a "Create remote directory and files under the remote directory"
19610
19611 test_230b() {
19612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19613         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19614         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19615                 skip "Need MDS version at least 2.11.52"
19616
19617         local MDTIDX=1
19618         local mdt_index
19619         local i
19620         local file
19621         local pid
19622         local stripe_count
19623         local migrate_dir=$DIR/$tdir/migrate_dir
19624         local other_dir=$DIR/$tdir/other_dir
19625
19626         test_mkdir $DIR/$tdir
19627         test_mkdir -i0 -c1 $migrate_dir
19628         test_mkdir -i0 -c1 $other_dir
19629         for ((i=0; i<10; i++)); do
19630                 mkdir -p $migrate_dir/dir_${i}
19631                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19632                         error "create files under remote dir failed $i"
19633         done
19634
19635         cp /etc/passwd $migrate_dir/$tfile
19636         cp /etc/passwd $other_dir/$tfile
19637         chattr +SAD $migrate_dir
19638         chattr +SAD $migrate_dir/$tfile
19639
19640         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19641         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19642         local old_dir_mode=$(stat -c%f $migrate_dir)
19643         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19644
19645         mkdir -p $migrate_dir/dir_default_stripe2
19646         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19647         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19648
19649         mkdir -p $other_dir
19650         ln $migrate_dir/$tfile $other_dir/luna
19651         ln $migrate_dir/$tfile $migrate_dir/sofia
19652         ln $other_dir/$tfile $migrate_dir/david
19653         ln -s $migrate_dir/$tfile $other_dir/zachary
19654         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19655         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19656
19657         local len
19658         local lnktgt
19659
19660         # inline symlink
19661         for len in 58 59 60; do
19662                 lnktgt=$(str_repeat 'l' $len)
19663                 touch $migrate_dir/$lnktgt
19664                 ln -s $lnktgt $migrate_dir/${len}char_ln
19665         done
19666
19667         # PATH_MAX
19668         for len in 4094 4095; do
19669                 lnktgt=$(str_repeat 'l' $len)
19670                 ln -s $lnktgt $migrate_dir/${len}char_ln
19671         done
19672
19673         # NAME_MAX
19674         for len in 254 255; do
19675                 touch $migrate_dir/$(str_repeat 'l' $len)
19676         done
19677
19678         $LFS migrate -m $MDTIDX $migrate_dir ||
19679                 error "fails on migrating remote dir to MDT1"
19680
19681         echo "migratate to MDT1, then checking.."
19682         for ((i = 0; i < 10; i++)); do
19683                 for file in $(find $migrate_dir/dir_${i}); do
19684                         mdt_index=$($LFS getstripe -m $file)
19685                         # broken symlink getstripe will fail
19686                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19687                                 error "$file is not on MDT${MDTIDX}"
19688                 done
19689         done
19690
19691         # the multiple link file should still in MDT0
19692         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19693         [ $mdt_index == 0 ] ||
19694                 error "$file is not on MDT${MDTIDX}"
19695
19696         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19697         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19698                 error " expect $old_dir_flag get $new_dir_flag"
19699
19700         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19701         [ "$old_file_flag" = "$new_file_flag" ] ||
19702                 error " expect $old_file_flag get $new_file_flag"
19703
19704         local new_dir_mode=$(stat -c%f $migrate_dir)
19705         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19706                 error "expect mode $old_dir_mode get $new_dir_mode"
19707
19708         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19709         [ "$old_file_mode" = "$new_file_mode" ] ||
19710                 error "expect mode $old_file_mode get $new_file_mode"
19711
19712         diff /etc/passwd $migrate_dir/$tfile ||
19713                 error "$tfile different after migration"
19714
19715         diff /etc/passwd $other_dir/luna ||
19716                 error "luna different after migration"
19717
19718         diff /etc/passwd $migrate_dir/sofia ||
19719                 error "sofia different after migration"
19720
19721         diff /etc/passwd $migrate_dir/david ||
19722                 error "david different after migration"
19723
19724         diff /etc/passwd $other_dir/zachary ||
19725                 error "zachary different after migration"
19726
19727         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19728                 error "${tfile}_ln different after migration"
19729
19730         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19731                 error "${tfile}_ln_other different after migration"
19732
19733         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19734         [ $stripe_count = 2 ] ||
19735                 error "dir strpe_count $d != 2 after migration."
19736
19737         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19738         [ $stripe_count = 2 ] ||
19739                 error "file strpe_count $d != 2 after migration."
19740
19741         #migrate back to MDT0
19742         MDTIDX=0
19743
19744         $LFS migrate -m $MDTIDX $migrate_dir ||
19745                 error "fails on migrating remote dir to MDT0"
19746
19747         echo "migrate back to MDT0, checking.."
19748         for file in $(find $migrate_dir); do
19749                 mdt_index=$($LFS getstripe -m $file)
19750                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19751                         error "$file is not on MDT${MDTIDX}"
19752         done
19753
19754         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19755         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19756                 error " expect $old_dir_flag get $new_dir_flag"
19757
19758         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19759         [ "$old_file_flag" = "$new_file_flag" ] ||
19760                 error " expect $old_file_flag get $new_file_flag"
19761
19762         local new_dir_mode=$(stat -c%f $migrate_dir)
19763         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19764                 error "expect mode $old_dir_mode get $new_dir_mode"
19765
19766         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19767         [ "$old_file_mode" = "$new_file_mode" ] ||
19768                 error "expect mode $old_file_mode get $new_file_mode"
19769
19770         diff /etc/passwd ${migrate_dir}/$tfile ||
19771                 error "$tfile different after migration"
19772
19773         diff /etc/passwd ${other_dir}/luna ||
19774                 error "luna different after migration"
19775
19776         diff /etc/passwd ${migrate_dir}/sofia ||
19777                 error "sofia different after migration"
19778
19779         diff /etc/passwd ${other_dir}/zachary ||
19780                 error "zachary different after migration"
19781
19782         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19783                 error "${tfile}_ln different after migration"
19784
19785         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19786                 error "${tfile}_ln_other different after migration"
19787
19788         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19789         [ $stripe_count = 2 ] ||
19790                 error "dir strpe_count $d != 2 after migration."
19791
19792         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19793         [ $stripe_count = 2 ] ||
19794                 error "file strpe_count $d != 2 after migration."
19795
19796         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19797 }
19798 run_test 230b "migrate directory"
19799
19800 test_230c() {
19801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19802         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19803         remote_mds_nodsh && skip "remote MDS with nodsh"
19804         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19805                 skip "Need MDS version at least 2.11.52"
19806
19807         local MDTIDX=1
19808         local total=3
19809         local mdt_index
19810         local file
19811         local migrate_dir=$DIR/$tdir/migrate_dir
19812
19813         #If migrating directory fails in the middle, all entries of
19814         #the directory is still accessiable.
19815         test_mkdir $DIR/$tdir
19816         test_mkdir -i0 -c1 $migrate_dir
19817         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19818         stat $migrate_dir
19819         createmany -o $migrate_dir/f $total ||
19820                 error "create files under ${migrate_dir} failed"
19821
19822         # fail after migrating top dir, and this will fail only once, so the
19823         # first sub file migration will fail (currently f3), others succeed.
19824         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19825         do_facet mds1 lctl set_param fail_loc=0x1801
19826         local t=$(ls $migrate_dir | wc -l)
19827         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19828                 error "migrate should fail"
19829         local u=$(ls $migrate_dir | wc -l)
19830         [ "$u" == "$t" ] || error "$u != $t during migration"
19831
19832         # add new dir/file should succeed
19833         mkdir $migrate_dir/dir ||
19834                 error "mkdir failed under migrating directory"
19835         touch $migrate_dir/file ||
19836                 error "create file failed under migrating directory"
19837
19838         # add file with existing name should fail
19839         for file in $migrate_dir/f*; do
19840                 stat $file > /dev/null || error "stat $file failed"
19841                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19842                         error "open(O_CREAT|O_EXCL) $file should fail"
19843                 $MULTIOP $file m && error "create $file should fail"
19844                 touch $DIR/$tdir/remote_dir/$tfile ||
19845                         error "touch $tfile failed"
19846                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19847                         error "link $file should fail"
19848                 mdt_index=$($LFS getstripe -m $file)
19849                 if [ $mdt_index == 0 ]; then
19850                         # file failed to migrate is not allowed to rename to
19851                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19852                                 error "rename to $file should fail"
19853                 else
19854                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19855                                 error "rename to $file failed"
19856                 fi
19857                 echo hello >> $file || error "write $file failed"
19858         done
19859
19860         # resume migration with different options should fail
19861         $LFS migrate -m 0 $migrate_dir &&
19862                 error "migrate -m 0 $migrate_dir should fail"
19863
19864         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19865                 error "migrate -c 2 $migrate_dir should fail"
19866
19867         # resume migration should succeed
19868         $LFS migrate -m $MDTIDX $migrate_dir ||
19869                 error "migrate $migrate_dir failed"
19870
19871         echo "Finish migration, then checking.."
19872         for file in $(find $migrate_dir); do
19873                 mdt_index=$($LFS getstripe -m $file)
19874                 [ $mdt_index == $MDTIDX ] ||
19875                         error "$file is not on MDT${MDTIDX}"
19876         done
19877
19878         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19879 }
19880 run_test 230c "check directory accessiblity if migration failed"
19881
19882 test_230d() {
19883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19884         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19885         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19886                 skip "Need MDS version at least 2.11.52"
19887         # LU-11235
19888         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19889
19890         local migrate_dir=$DIR/$tdir/migrate_dir
19891         local old_index
19892         local new_index
19893         local old_count
19894         local new_count
19895         local new_hash
19896         local mdt_index
19897         local i
19898         local j
19899
19900         old_index=$((RANDOM % MDSCOUNT))
19901         old_count=$((MDSCOUNT - old_index))
19902         new_index=$((RANDOM % MDSCOUNT))
19903         new_count=$((MDSCOUNT - new_index))
19904         new_hash=1 # for all_char
19905
19906         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19907         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19908
19909         test_mkdir $DIR/$tdir
19910         test_mkdir -i $old_index -c $old_count $migrate_dir
19911
19912         for ((i=0; i<100; i++)); do
19913                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19914                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19915                         error "create files under remote dir failed $i"
19916         done
19917
19918         echo -n "Migrate from MDT$old_index "
19919         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19920         echo -n "to MDT$new_index"
19921         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19922         echo
19923
19924         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19925         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19926                 error "migrate remote dir error"
19927
19928         echo "Finish migration, then checking.."
19929         for file in $(find $migrate_dir -maxdepth 1); do
19930                 mdt_index=$($LFS getstripe -m $file)
19931                 if [ $mdt_index -lt $new_index ] ||
19932                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19933                         error "$file is on MDT$mdt_index"
19934                 fi
19935         done
19936
19937         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19938 }
19939 run_test 230d "check migrate big directory"
19940
19941 test_230e() {
19942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19943         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19944         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19945                 skip "Need MDS version at least 2.11.52"
19946
19947         local i
19948         local j
19949         local a_fid
19950         local b_fid
19951
19952         mkdir_on_mdt0 $DIR/$tdir
19953         mkdir $DIR/$tdir/migrate_dir
19954         mkdir $DIR/$tdir/other_dir
19955         touch $DIR/$tdir/migrate_dir/a
19956         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19957         ls $DIR/$tdir/other_dir
19958
19959         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19960                 error "migrate dir fails"
19961
19962         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19963         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19964
19965         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19966         [ $mdt_index == 0 ] || error "a is not on MDT0"
19967
19968         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19969                 error "migrate dir fails"
19970
19971         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19972         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19973
19974         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19975         [ $mdt_index == 1 ] || error "a is not on MDT1"
19976
19977         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19978         [ $mdt_index == 1 ] || error "b is not on MDT1"
19979
19980         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19981         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19982
19983         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19984
19985         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19986 }
19987 run_test 230e "migrate mulitple local link files"
19988
19989 test_230f() {
19990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19991         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19992         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19993                 skip "Need MDS version at least 2.11.52"
19994
19995         local a_fid
19996         local ln_fid
19997
19998         mkdir -p $DIR/$tdir
19999         mkdir $DIR/$tdir/migrate_dir
20000         $LFS mkdir -i1 $DIR/$tdir/other_dir
20001         touch $DIR/$tdir/migrate_dir/a
20002         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20003         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20004         ls $DIR/$tdir/other_dir
20005
20006         # a should be migrated to MDT1, since no other links on MDT0
20007         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20008                 error "#1 migrate dir fails"
20009         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20010         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20011         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20012         [ $mdt_index == 1 ] || error "a is not on MDT1"
20013
20014         # a should stay on MDT1, because it is a mulitple link file
20015         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20016                 error "#2 migrate dir fails"
20017         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20018         [ $mdt_index == 1 ] || error "a is not on MDT1"
20019
20020         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20021                 error "#3 migrate dir fails"
20022
20023         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20024         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20025         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20026
20027         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20028         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20029
20030         # a should be migrated to MDT0, since no other links on MDT1
20031         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20032                 error "#4 migrate dir fails"
20033         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20034         [ $mdt_index == 0 ] || error "a is not on MDT0"
20035
20036         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20037 }
20038 run_test 230f "migrate mulitple remote link files"
20039
20040 test_230g() {
20041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20042         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20043         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20044                 skip "Need MDS version at least 2.11.52"
20045
20046         mkdir -p $DIR/$tdir/migrate_dir
20047
20048         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20049                 error "migrating dir to non-exist MDT succeeds"
20050         true
20051 }
20052 run_test 230g "migrate dir to non-exist MDT"
20053
20054 test_230h() {
20055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20056         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20057         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20058                 skip "Need MDS version at least 2.11.52"
20059
20060         local mdt_index
20061
20062         mkdir -p $DIR/$tdir/migrate_dir
20063
20064         $LFS migrate -m1 $DIR &&
20065                 error "migrating mountpoint1 should fail"
20066
20067         $LFS migrate -m1 $DIR/$tdir/.. &&
20068                 error "migrating mountpoint2 should fail"
20069
20070         # same as mv
20071         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20072                 error "migrating $tdir/migrate_dir/.. should fail"
20073
20074         true
20075 }
20076 run_test 230h "migrate .. and root"
20077
20078 test_230i() {
20079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20080         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20081         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20082                 skip "Need MDS version at least 2.11.52"
20083
20084         mkdir -p $DIR/$tdir/migrate_dir
20085
20086         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20087                 error "migration fails with a tailing slash"
20088
20089         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20090                 error "migration fails with two tailing slashes"
20091 }
20092 run_test 230i "lfs migrate -m tolerates trailing slashes"
20093
20094 test_230j() {
20095         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20096         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20097                 skip "Need MDS version at least 2.11.52"
20098
20099         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20100         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20101                 error "create $tfile failed"
20102         cat /etc/passwd > $DIR/$tdir/$tfile
20103
20104         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20105
20106         cmp /etc/passwd $DIR/$tdir/$tfile ||
20107                 error "DoM file mismatch after migration"
20108 }
20109 run_test 230j "DoM file data not changed after dir migration"
20110
20111 test_230k() {
20112         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20113         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20114                 skip "Need MDS version at least 2.11.56"
20115
20116         local total=20
20117         local files_on_starting_mdt=0
20118
20119         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20120         $LFS getdirstripe $DIR/$tdir
20121         for i in $(seq $total); do
20122                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20123                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20124                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20125         done
20126
20127         echo "$files_on_starting_mdt files on MDT0"
20128
20129         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20130         $LFS getdirstripe $DIR/$tdir
20131
20132         files_on_starting_mdt=0
20133         for i in $(seq $total); do
20134                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20135                         error "file $tfile.$i mismatch after migration"
20136                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20137                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20138         done
20139
20140         echo "$files_on_starting_mdt files on MDT1 after migration"
20141         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20142
20143         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20144         $LFS getdirstripe $DIR/$tdir
20145
20146         files_on_starting_mdt=0
20147         for i in $(seq $total); do
20148                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20149                         error "file $tfile.$i mismatch after 2nd migration"
20150                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20151                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20152         done
20153
20154         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20155         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20156
20157         true
20158 }
20159 run_test 230k "file data not changed after dir migration"
20160
20161 test_230l() {
20162         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20163         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20164                 skip "Need MDS version at least 2.11.56"
20165
20166         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20167         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20168                 error "create files under remote dir failed $i"
20169         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20170 }
20171 run_test 230l "readdir between MDTs won't crash"
20172
20173 test_230m() {
20174         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20175         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20176                 skip "Need MDS version at least 2.11.56"
20177
20178         local MDTIDX=1
20179         local mig_dir=$DIR/$tdir/migrate_dir
20180         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20181         local shortstr="b"
20182         local val
20183
20184         echo "Creating files and dirs with xattrs"
20185         test_mkdir $DIR/$tdir
20186         test_mkdir -i0 -c1 $mig_dir
20187         mkdir $mig_dir/dir
20188         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20189                 error "cannot set xattr attr1 on dir"
20190         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20191                 error "cannot set xattr attr2 on dir"
20192         touch $mig_dir/dir/f0
20193         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20194                 error "cannot set xattr attr1 on file"
20195         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20196                 error "cannot set xattr attr2 on file"
20197         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20198         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20199         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20200         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20201         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20202         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20203         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20204         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20205         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20206
20207         echo "Migrating to MDT1"
20208         $LFS migrate -m $MDTIDX $mig_dir ||
20209                 error "fails on migrating dir to MDT1"
20210
20211         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20212         echo "Checking xattrs"
20213         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20214         [ "$val" = $longstr ] ||
20215                 error "expecting xattr1 $longstr on dir, found $val"
20216         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20217         [ "$val" = $shortstr ] ||
20218                 error "expecting xattr2 $shortstr on dir, found $val"
20219         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20220         [ "$val" = $longstr ] ||
20221                 error "expecting xattr1 $longstr on file, found $val"
20222         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20223         [ "$val" = $shortstr ] ||
20224                 error "expecting xattr2 $shortstr on file, found $val"
20225 }
20226 run_test 230m "xattrs not changed after dir migration"
20227
20228 test_230n() {
20229         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20230         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20231                 skip "Need MDS version at least 2.13.53"
20232
20233         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20234         cat /etc/hosts > $DIR/$tdir/$tfile
20235         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20236         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20237
20238         cmp /etc/hosts $DIR/$tdir/$tfile ||
20239                 error "File data mismatch after migration"
20240 }
20241 run_test 230n "Dir migration with mirrored file"
20242
20243 test_230o() {
20244         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20245         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20246                 skip "Need MDS version at least 2.13.52"
20247
20248         local mdts=$(comma_list $(mdts_nodes))
20249         local timeout=100
20250         local restripe_status
20251         local delta
20252         local i
20253
20254         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20255
20256         # in case "crush" hash type is not set
20257         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20258
20259         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20260                            mdt.*MDT0000.enable_dir_restripe)
20261         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20262         stack_trap "do_nodes $mdts $LCTL set_param \
20263                     mdt.*.enable_dir_restripe=$restripe_status"
20264
20265         mkdir $DIR/$tdir
20266         createmany -m $DIR/$tdir/f 100 ||
20267                 error "create files under remote dir failed $i"
20268         createmany -d $DIR/$tdir/d 100 ||
20269                 error "create dirs under remote dir failed $i"
20270
20271         for i in $(seq 2 $MDSCOUNT); do
20272                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20273                 $LFS setdirstripe -c $i $DIR/$tdir ||
20274                         error "split -c $i $tdir failed"
20275                 wait_update $HOSTNAME \
20276                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20277                         error "dir split not finished"
20278                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20279                         awk '/migrate/ {sum += $2} END { print sum }')
20280                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20281                 # delta is around total_files/stripe_count
20282                 (( $delta < 200 / (i - 1) + 4 )) ||
20283                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20284         done
20285 }
20286 run_test 230o "dir split"
20287
20288 test_230p() {
20289         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20290         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20291                 skip "Need MDS version at least 2.13.52"
20292
20293         local mdts=$(comma_list $(mdts_nodes))
20294         local timeout=100
20295         local restripe_status
20296         local delta
20297         local c
20298
20299         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20300
20301         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20302
20303         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20304                            mdt.*MDT0000.enable_dir_restripe)
20305         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20306         stack_trap "do_nodes $mdts $LCTL set_param \
20307                     mdt.*.enable_dir_restripe=$restripe_status"
20308
20309         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20310         createmany -m $DIR/$tdir/f 100 ||
20311                 error "create files under remote dir failed"
20312         createmany -d $DIR/$tdir/d 100 ||
20313                 error "create dirs under remote dir failed"
20314
20315         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20316                 local mdt_hash="crush"
20317
20318                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20319                 $LFS setdirstripe -c $c $DIR/$tdir ||
20320                         error "split -c $c $tdir failed"
20321                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20322                         mdt_hash="$mdt_hash,fixed"
20323                 elif [ $c -eq 1 ]; then
20324                         mdt_hash="none"
20325                 fi
20326                 wait_update $HOSTNAME \
20327                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20328                         error "dir merge not finished"
20329                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20330                         awk '/migrate/ {sum += $2} END { print sum }')
20331                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20332                 # delta is around total_files/stripe_count
20333                 (( delta < 200 / c + 4 )) ||
20334                         error "$delta files migrated >= $((200 / c + 4))"
20335         done
20336 }
20337 run_test 230p "dir merge"
20338
20339 test_230q() {
20340         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20341         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20342                 skip "Need MDS version at least 2.13.52"
20343
20344         local mdts=$(comma_list $(mdts_nodes))
20345         local saved_threshold=$(do_facet mds1 \
20346                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20347         local saved_delta=$(do_facet mds1 \
20348                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20349         local threshold=100
20350         local delta=2
20351         local total=0
20352         local stripe_count=0
20353         local stripe_index
20354         local nr_files
20355         local create
20356
20357         # test with fewer files on ZFS
20358         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20359
20360         stack_trap "do_nodes $mdts $LCTL set_param \
20361                     mdt.*.dir_split_count=$saved_threshold"
20362         stack_trap "do_nodes $mdts $LCTL set_param \
20363                     mdt.*.dir_split_delta=$saved_delta"
20364         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20365         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20366         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20367         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20368         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20369         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20370
20371         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20372         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20373
20374         create=$((threshold * 3 / 2))
20375         while [ $stripe_count -lt $MDSCOUNT ]; do
20376                 createmany -m $DIR/$tdir/f $total $create ||
20377                         error "create sub files failed"
20378                 stat $DIR/$tdir > /dev/null
20379                 total=$((total + create))
20380                 stripe_count=$((stripe_count + delta))
20381                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20382
20383                 wait_update $HOSTNAME \
20384                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20385                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20386
20387                 wait_update $HOSTNAME \
20388                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20389                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20390
20391                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20392                 echo "$nr_files/$total files on MDT$stripe_index after split"
20393                 # allow 10% margin of imbalance with crush hash
20394                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20395                         error "$nr_files files on MDT$stripe_index after split"
20396
20397                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20398                 [ $nr_files -eq $total ] ||
20399                         error "total sub files $nr_files != $total"
20400         done
20401
20402         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20403
20404         echo "fixed layout directory won't auto split"
20405         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20406         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20407                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20408         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20409                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20410 }
20411 run_test 230q "dir auto split"
20412
20413 test_230r() {
20414         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20415         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20416         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20417                 skip "Need MDS version at least 2.13.54"
20418
20419         # maximum amount of local locks:
20420         # parent striped dir - 2 locks
20421         # new stripe in parent to migrate to - 1 lock
20422         # source and target - 2 locks
20423         # Total 5 locks for regular file
20424         mkdir -p $DIR/$tdir
20425         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20426         touch $DIR/$tdir/dir1/eee
20427
20428         # create 4 hardlink for 4 more locks
20429         # Total: 9 locks > RS_MAX_LOCKS (8)
20430         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20431         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20432         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20433         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20434         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20435         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20436         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20437         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20438
20439         cancel_lru_locks mdc
20440
20441         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20442                 error "migrate dir fails"
20443
20444         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20445 }
20446 run_test 230r "migrate with too many local locks"
20447
20448 test_230s() {
20449         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20450                 skip "Need MDS version at least 2.14.52"
20451
20452         local mdts=$(comma_list $(mdts_nodes))
20453         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20454                                 mdt.*MDT0000.enable_dir_restripe)
20455
20456         stack_trap "do_nodes $mdts $LCTL set_param \
20457                     mdt.*.enable_dir_restripe=$restripe_status"
20458
20459         local st
20460         for st in 0 1; do
20461                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20462                 test_mkdir $DIR/$tdir
20463                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20464                         error "$LFS mkdir should return EEXIST if target exists"
20465                 rmdir $DIR/$tdir
20466         done
20467 }
20468 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20469
20470 test_230t()
20471 {
20472         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20473         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20474                 skip "Need MDS version at least 2.14.50"
20475
20476         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20477         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20478         $LFS project -p 1 -s $DIR/$tdir ||
20479                 error "set $tdir project id failed"
20480         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20481                 error "set subdir project id failed"
20482         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20483 }
20484 run_test 230t "migrate directory with project ID set"
20485
20486 test_230u()
20487 {
20488         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20489         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20490                 skip "Need MDS version at least 2.14.53"
20491
20492         local count
20493
20494         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20495         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20496         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20497         for i in $(seq 0 $((MDSCOUNT - 1))); do
20498                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20499                 echo "$count dirs migrated to MDT$i"
20500         done
20501         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20502         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20503 }
20504 run_test 230u "migrate directory by QOS"
20505
20506 test_230v()
20507 {
20508         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20509         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20510                 skip "Need MDS version at least 2.14.53"
20511
20512         local count
20513
20514         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20515         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20516         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20517         for i in $(seq 0 $((MDSCOUNT - 1))); do
20518                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20519                 echo "$count subdirs migrated to MDT$i"
20520                 (( i == 3 )) && (( count > 0 )) &&
20521                         error "subdir shouldn't be migrated to MDT3"
20522         done
20523         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20524         (( count == 3 )) || error "dirs migrated to $count MDTs"
20525 }
20526 run_test 230v "subdir migrated to the MDT where its parent is located"
20527
20528 test_230w() {
20529         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20530         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20531                 skip "Need MDS version at least 2.14.53"
20532
20533         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20534
20535         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20536                 error "migrate failed"
20537
20538         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20539                 error "$tdir stripe count mismatch"
20540
20541         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20542                 error "$tdir/sub is striped"
20543 }
20544 run_test 230w "non-recursive mode dir migration"
20545
20546 test_231a()
20547 {
20548         # For simplicity this test assumes that max_pages_per_rpc
20549         # is the same across all OSCs
20550         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20551         local bulk_size=$((max_pages * PAGE_SIZE))
20552         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20553                                        head -n 1)
20554
20555         mkdir -p $DIR/$tdir
20556         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20557                 error "failed to set stripe with -S ${brw_size}M option"
20558
20559         # clear the OSC stats
20560         $LCTL set_param osc.*.stats=0 &>/dev/null
20561         stop_writeback
20562
20563         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20564         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20565                 oflag=direct &>/dev/null || error "dd failed"
20566
20567         sync; sleep 1; sync # just to be safe
20568         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20569         if [ x$nrpcs != "x1" ]; then
20570                 $LCTL get_param osc.*.stats
20571                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20572         fi
20573
20574         start_writeback
20575         # Drop the OSC cache, otherwise we will read from it
20576         cancel_lru_locks osc
20577
20578         # clear the OSC stats
20579         $LCTL set_param osc.*.stats=0 &>/dev/null
20580
20581         # Client reads $bulk_size.
20582         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20583                 iflag=direct &>/dev/null || error "dd failed"
20584
20585         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20586         if [ x$nrpcs != "x1" ]; then
20587                 $LCTL get_param osc.*.stats
20588                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20589         fi
20590 }
20591 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20592
20593 test_231b() {
20594         mkdir -p $DIR/$tdir
20595         local i
20596         for i in {0..1023}; do
20597                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20598                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20599                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20600         done
20601         sync
20602 }
20603 run_test 231b "must not assert on fully utilized OST request buffer"
20604
20605 test_232a() {
20606         mkdir -p $DIR/$tdir
20607         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20608
20609         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20610         do_facet ost1 $LCTL set_param fail_loc=0x31c
20611
20612         # ignore dd failure
20613         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20614
20615         do_facet ost1 $LCTL set_param fail_loc=0
20616         umount_client $MOUNT || error "umount failed"
20617         mount_client $MOUNT || error "mount failed"
20618         stop ost1 || error "cannot stop ost1"
20619         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20620 }
20621 run_test 232a "failed lock should not block umount"
20622
20623 test_232b() {
20624         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20625                 skip "Need MDS version at least 2.10.58"
20626
20627         mkdir -p $DIR/$tdir
20628         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20629         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20630         sync
20631         cancel_lru_locks osc
20632
20633         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20634         do_facet ost1 $LCTL set_param fail_loc=0x31c
20635
20636         # ignore failure
20637         $LFS data_version $DIR/$tdir/$tfile || true
20638
20639         do_facet ost1 $LCTL set_param fail_loc=0
20640         umount_client $MOUNT || error "umount failed"
20641         mount_client $MOUNT || error "mount failed"
20642         stop ost1 || error "cannot stop ost1"
20643         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20644 }
20645 run_test 232b "failed data version lock should not block umount"
20646
20647 test_233a() {
20648         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20649                 skip "Need MDS version at least 2.3.64"
20650         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20651
20652         local fid=$($LFS path2fid $MOUNT)
20653
20654         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20655                 error "cannot access $MOUNT using its FID '$fid'"
20656 }
20657 run_test 233a "checking that OBF of the FS root succeeds"
20658
20659 test_233b() {
20660         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20661                 skip "Need MDS version at least 2.5.90"
20662         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20663
20664         local fid=$($LFS path2fid $MOUNT/.lustre)
20665
20666         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20667                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20668
20669         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20670         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20671                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20672 }
20673 run_test 233b "checking that OBF of the FS .lustre succeeds"
20674
20675 test_234() {
20676         local p="$TMP/sanityN-$TESTNAME.parameters"
20677         save_lustre_params client "llite.*.xattr_cache" > $p
20678         lctl set_param llite.*.xattr_cache 1 ||
20679                 skip_env "xattr cache is not supported"
20680
20681         mkdir -p $DIR/$tdir || error "mkdir failed"
20682         touch $DIR/$tdir/$tfile || error "touch failed"
20683         # OBD_FAIL_LLITE_XATTR_ENOMEM
20684         $LCTL set_param fail_loc=0x1405
20685         getfattr -n user.attr $DIR/$tdir/$tfile &&
20686                 error "getfattr should have failed with ENOMEM"
20687         $LCTL set_param fail_loc=0x0
20688         rm -rf $DIR/$tdir
20689
20690         restore_lustre_params < $p
20691         rm -f $p
20692 }
20693 run_test 234 "xattr cache should not crash on ENOMEM"
20694
20695 test_235() {
20696         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20697                 skip "Need MDS version at least 2.4.52"
20698
20699         flock_deadlock $DIR/$tfile
20700         local RC=$?
20701         case $RC in
20702                 0)
20703                 ;;
20704                 124) error "process hangs on a deadlock"
20705                 ;;
20706                 *) error "error executing flock_deadlock $DIR/$tfile"
20707                 ;;
20708         esac
20709 }
20710 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20711
20712 #LU-2935
20713 test_236() {
20714         check_swap_layouts_support
20715
20716         local ref1=/etc/passwd
20717         local ref2=/etc/group
20718         local file1=$DIR/$tdir/f1
20719         local file2=$DIR/$tdir/f2
20720
20721         test_mkdir -c1 $DIR/$tdir
20722         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20723         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20724         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20725         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20726         local fd=$(free_fd)
20727         local cmd="exec $fd<>$file2"
20728         eval $cmd
20729         rm $file2
20730         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20731                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20732         cmd="exec $fd>&-"
20733         eval $cmd
20734         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20735
20736         #cleanup
20737         rm -rf $DIR/$tdir
20738 }
20739 run_test 236 "Layout swap on open unlinked file"
20740
20741 # LU-4659 linkea consistency
20742 test_238() {
20743         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20744                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20745                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20746                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20747
20748         touch $DIR/$tfile
20749         ln $DIR/$tfile $DIR/$tfile.lnk
20750         touch $DIR/$tfile.new
20751         mv $DIR/$tfile.new $DIR/$tfile
20752         local fid1=$($LFS path2fid $DIR/$tfile)
20753         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20754         local path1=$($LFS fid2path $FSNAME "$fid1")
20755         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20756         local path2=$($LFS fid2path $FSNAME "$fid2")
20757         [ $tfile.lnk == $path2 ] ||
20758                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20759         rm -f $DIR/$tfile*
20760 }
20761 run_test 238 "Verify linkea consistency"
20762
20763 test_239A() { # was test_239
20764         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20765                 skip "Need MDS version at least 2.5.60"
20766
20767         local list=$(comma_list $(mdts_nodes))
20768
20769         mkdir -p $DIR/$tdir
20770         createmany -o $DIR/$tdir/f- 5000
20771         unlinkmany $DIR/$tdir/f- 5000
20772         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20773                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20774         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20775                         osp.*MDT*.sync_in_flight" | calc_sum)
20776         [ "$changes" -eq 0 ] || error "$changes not synced"
20777 }
20778 run_test 239A "osp_sync test"
20779
20780 test_239a() { #LU-5297
20781         remote_mds_nodsh && skip "remote MDS with nodsh"
20782
20783         touch $DIR/$tfile
20784         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20785         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20786         chgrp $RUNAS_GID $DIR/$tfile
20787         wait_delete_completed
20788 }
20789 run_test 239a "process invalid osp sync record correctly"
20790
20791 test_239b() { #LU-5297
20792         remote_mds_nodsh && skip "remote MDS with nodsh"
20793
20794         touch $DIR/$tfile1
20795         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20796         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20797         chgrp $RUNAS_GID $DIR/$tfile1
20798         wait_delete_completed
20799         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20800         touch $DIR/$tfile2
20801         chgrp $RUNAS_GID $DIR/$tfile2
20802         wait_delete_completed
20803 }
20804 run_test 239b "process osp sync record with ENOMEM error correctly"
20805
20806 test_240() {
20807         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20808         remote_mds_nodsh && skip "remote MDS with nodsh"
20809
20810         mkdir -p $DIR/$tdir
20811
20812         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20813                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20814         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20815                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20816
20817         umount_client $MOUNT || error "umount failed"
20818         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20819         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20820         mount_client $MOUNT || error "failed to mount client"
20821
20822         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20823         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20824 }
20825 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20826
20827 test_241_bio() {
20828         local count=$1
20829         local bsize=$2
20830
20831         for LOOP in $(seq $count); do
20832                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20833                 cancel_lru_locks $OSC || true
20834         done
20835 }
20836
20837 test_241_dio() {
20838         local count=$1
20839         local bsize=$2
20840
20841         for LOOP in $(seq $1); do
20842                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20843                         2>/dev/null
20844         done
20845 }
20846
20847 test_241a() { # was test_241
20848         local bsize=$PAGE_SIZE
20849
20850         (( bsize < 40960 )) && bsize=40960
20851         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20852         ls -la $DIR/$tfile
20853         cancel_lru_locks $OSC
20854         test_241_bio 1000 $bsize &
20855         PID=$!
20856         test_241_dio 1000 $bsize
20857         wait $PID
20858 }
20859 run_test 241a "bio vs dio"
20860
20861 test_241b() {
20862         local bsize=$PAGE_SIZE
20863
20864         (( bsize < 40960 )) && bsize=40960
20865         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20866         ls -la $DIR/$tfile
20867         test_241_dio 1000 $bsize &
20868         PID=$!
20869         test_241_dio 1000 $bsize
20870         wait $PID
20871 }
20872 run_test 241b "dio vs dio"
20873
20874 test_242() {
20875         remote_mds_nodsh && skip "remote MDS with nodsh"
20876
20877         mkdir_on_mdt0 $DIR/$tdir
20878         touch $DIR/$tdir/$tfile
20879
20880         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20881         do_facet mds1 lctl set_param fail_loc=0x105
20882         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20883
20884         do_facet mds1 lctl set_param fail_loc=0
20885         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20886 }
20887 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20888
20889 test_243()
20890 {
20891         test_mkdir $DIR/$tdir
20892         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20893 }
20894 run_test 243 "various group lock tests"
20895
20896 test_244a()
20897 {
20898         test_mkdir $DIR/$tdir
20899         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20900         sendfile_grouplock $DIR/$tdir/$tfile || \
20901                 error "sendfile+grouplock failed"
20902         rm -rf $DIR/$tdir
20903 }
20904 run_test 244a "sendfile with group lock tests"
20905
20906 test_244b()
20907 {
20908         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20909
20910         local threads=50
20911         local size=$((1024*1024))
20912
20913         test_mkdir $DIR/$tdir
20914         for i in $(seq 1 $threads); do
20915                 local file=$DIR/$tdir/file_$((i / 10))
20916                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20917                 local pids[$i]=$!
20918         done
20919         for i in $(seq 1 $threads); do
20920                 wait ${pids[$i]}
20921         done
20922 }
20923 run_test 244b "multi-threaded write with group lock"
20924
20925 test_245() {
20926         local flagname="multi_mod_rpcs"
20927         local connect_data_name="max_mod_rpcs"
20928         local out
20929
20930         # check if multiple modify RPCs flag is set
20931         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20932                 grep "connect_flags:")
20933         echo "$out"
20934
20935         echo "$out" | grep -qw $flagname
20936         if [ $? -ne 0 ]; then
20937                 echo "connect flag $flagname is not set"
20938                 return
20939         fi
20940
20941         # check if multiple modify RPCs data is set
20942         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20943         echo "$out"
20944
20945         echo "$out" | grep -qw $connect_data_name ||
20946                 error "import should have connect data $connect_data_name"
20947 }
20948 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20949
20950 cleanup_247() {
20951         local submount=$1
20952
20953         trap 0
20954         umount_client $submount
20955         rmdir $submount
20956 }
20957
20958 test_247a() {
20959         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20960                 grep -q subtree ||
20961                 skip_env "Fileset feature is not supported"
20962
20963         local submount=${MOUNT}_$tdir
20964
20965         mkdir $MOUNT/$tdir
20966         mkdir -p $submount || error "mkdir $submount failed"
20967         FILESET="$FILESET/$tdir" mount_client $submount ||
20968                 error "mount $submount failed"
20969         trap "cleanup_247 $submount" EXIT
20970         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20971         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20972                 error "read $MOUNT/$tdir/$tfile failed"
20973         cleanup_247 $submount
20974 }
20975 run_test 247a "mount subdir as fileset"
20976
20977 test_247b() {
20978         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20979                 skip_env "Fileset feature is not supported"
20980
20981         local submount=${MOUNT}_$tdir
20982
20983         rm -rf $MOUNT/$tdir
20984         mkdir -p $submount || error "mkdir $submount failed"
20985         SKIP_FILESET=1
20986         FILESET="$FILESET/$tdir" mount_client $submount &&
20987                 error "mount $submount should fail"
20988         rmdir $submount
20989 }
20990 run_test 247b "mount subdir that dose not exist"
20991
20992 test_247c() {
20993         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20994                 skip_env "Fileset feature is not supported"
20995
20996         local submount=${MOUNT}_$tdir
20997
20998         mkdir -p $MOUNT/$tdir/dir1
20999         mkdir -p $submount || error "mkdir $submount failed"
21000         trap "cleanup_247 $submount" EXIT
21001         FILESET="$FILESET/$tdir" mount_client $submount ||
21002                 error "mount $submount failed"
21003         local fid=$($LFS path2fid $MOUNT/)
21004         $LFS fid2path $submount $fid && error "fid2path should fail"
21005         cleanup_247 $submount
21006 }
21007 run_test 247c "running fid2path outside subdirectory root"
21008
21009 test_247d() {
21010         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21011                 skip "Fileset feature is not supported"
21012
21013         local submount=${MOUNT}_$tdir
21014
21015         mkdir -p $MOUNT/$tdir/dir1
21016         mkdir -p $submount || error "mkdir $submount failed"
21017         FILESET="$FILESET/$tdir" mount_client $submount ||
21018                 error "mount $submount failed"
21019         trap "cleanup_247 $submount" EXIT
21020
21021         local td=$submount/dir1
21022         local fid=$($LFS path2fid $td)
21023         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21024
21025         # check that we get the same pathname back
21026         local rootpath
21027         local found
21028         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21029                 echo "$rootpath $fid"
21030                 found=$($LFS fid2path $rootpath "$fid")
21031                 [ -n "found" ] || error "fid2path should succeed"
21032                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21033         done
21034         # check wrong root path format
21035         rootpath=$submount"_wrong"
21036         found=$($LFS fid2path $rootpath "$fid")
21037         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21038
21039         cleanup_247 $submount
21040 }
21041 run_test 247d "running fid2path inside subdirectory root"
21042
21043 # LU-8037
21044 test_247e() {
21045         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21046                 grep -q subtree ||
21047                 skip "Fileset feature is not supported"
21048
21049         local submount=${MOUNT}_$tdir
21050
21051         mkdir $MOUNT/$tdir
21052         mkdir -p $submount || error "mkdir $submount failed"
21053         FILESET="$FILESET/.." mount_client $submount &&
21054                 error "mount $submount should fail"
21055         rmdir $submount
21056 }
21057 run_test 247e "mount .. as fileset"
21058
21059 test_247f() {
21060         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21061         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21062                 skip "Need at least version 2.13.52"
21063         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21064                 skip "Need at least version 2.14.50"
21065         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21066                 grep -q subtree ||
21067                 skip "Fileset feature is not supported"
21068
21069         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21070         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21071                 error "mkdir remote failed"
21072         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21073                 error "mkdir remote/subdir failed"
21074         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21075                 error "mkdir striped failed"
21076         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21077
21078         local submount=${MOUNT}_$tdir
21079
21080         mkdir -p $submount || error "mkdir $submount failed"
21081         stack_trap "rmdir $submount"
21082
21083         local dir
21084         local stat
21085         local fileset=$FILESET
21086         local mdts=$(comma_list $(mdts_nodes))
21087
21088         stat=$(do_facet mds1 $LCTL get_param -n \
21089                 mdt.*MDT0000.enable_remote_subdir_mount)
21090         stack_trap "do_nodes $mdts $LCTL set_param \
21091                 mdt.*.enable_remote_subdir_mount=$stat"
21092
21093         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21094         stack_trap "umount_client $submount"
21095         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21096                 error "mount remote dir $dir should fail"
21097
21098         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21099                 $tdir/striped/. ; do
21100                 FILESET="$fileset/$dir" mount_client $submount ||
21101                         error "mount $dir failed"
21102                 umount_client $submount
21103         done
21104
21105         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21106         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21107                 error "mount $tdir/remote failed"
21108 }
21109 run_test 247f "mount striped or remote directory as fileset"
21110
21111 test_247g() {
21112         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21113         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21114                 skip "Need at least version 2.14.50"
21115
21116         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21117                 error "mkdir $tdir failed"
21118         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21119
21120         local submount=${MOUNT}_$tdir
21121
21122         mkdir -p $submount || error "mkdir $submount failed"
21123         stack_trap "rmdir $submount"
21124
21125         FILESET="$fileset/$tdir" mount_client $submount ||
21126                 error "mount $dir failed"
21127         stack_trap "umount $submount"
21128
21129         local mdts=$(comma_list $(mdts_nodes))
21130
21131         local nrpcs
21132
21133         stat $submount > /dev/null
21134         cancel_lru_locks $MDC
21135         stat $submount > /dev/null
21136         stat $submount/$tfile > /dev/null
21137         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21138         stat $submount/$tfile > /dev/null
21139         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21140                 awk '/getattr/ {sum += $2} END {print sum}')
21141
21142         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21143 }
21144 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21145
21146 test_248a() {
21147         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21148         [ -z "$fast_read_sav" ] && skip "no fast read support"
21149
21150         # create a large file for fast read verification
21151         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21152
21153         # make sure the file is created correctly
21154         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21155                 { rm -f $DIR/$tfile; skip "file creation error"; }
21156
21157         echo "Test 1: verify that fast read is 4 times faster on cache read"
21158
21159         # small read with fast read enabled
21160         $LCTL set_param -n llite.*.fast_read=1
21161         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21162                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21163                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21164         # small read with fast read disabled
21165         $LCTL set_param -n llite.*.fast_read=0
21166         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21167                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21168                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21169
21170         # verify that fast read is 4 times faster for cache read
21171         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21172                 error_not_in_vm "fast read was not 4 times faster: " \
21173                            "$t_fast vs $t_slow"
21174
21175         echo "Test 2: verify the performance between big and small read"
21176         $LCTL set_param -n llite.*.fast_read=1
21177
21178         # 1k non-cache read
21179         cancel_lru_locks osc
21180         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21181                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21182                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21183
21184         # 1M non-cache read
21185         cancel_lru_locks osc
21186         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21187                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21188                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21189
21190         # verify that big IO is not 4 times faster than small IO
21191         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21192                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21193
21194         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21195         rm -f $DIR/$tfile
21196 }
21197 run_test 248a "fast read verification"
21198
21199 test_248b() {
21200         # Default short_io_bytes=16384, try both smaller and larger sizes.
21201         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21202         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21203         echo "bs=53248 count=113 normal buffered write"
21204         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21205                 error "dd of initial data file failed"
21206         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21207
21208         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21209         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21210                 error "dd with sync normal writes failed"
21211         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21212
21213         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21214         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21215                 error "dd with sync small writes failed"
21216         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21217
21218         cancel_lru_locks osc
21219
21220         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21221         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21222         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21223         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21224                 iflag=direct || error "dd with O_DIRECT small read failed"
21225         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21226         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21227                 error "compare $TMP/$tfile.1 failed"
21228
21229         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21230         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21231
21232         # just to see what the maximum tunable value is, and test parsing
21233         echo "test invalid parameter 2MB"
21234         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21235                 error "too-large short_io_bytes allowed"
21236         echo "test maximum parameter 512KB"
21237         # if we can set a larger short_io_bytes, run test regardless of version
21238         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21239                 # older clients may not allow setting it this large, that's OK
21240                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21241                         skip "Need at least client version 2.13.50"
21242                 error "medium short_io_bytes failed"
21243         fi
21244         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21245         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21246
21247         echo "test large parameter 64KB"
21248         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21249         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21250
21251         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21252         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21253                 error "dd with sync large writes failed"
21254         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21255
21256         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21257         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21258         num=$((113 * 4096 / PAGE_SIZE))
21259         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21260         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21261                 error "dd with O_DIRECT large writes failed"
21262         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21263                 error "compare $DIR/$tfile.3 failed"
21264
21265         cancel_lru_locks osc
21266
21267         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21268         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21269                 error "dd with O_DIRECT large read failed"
21270         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21271                 error "compare $TMP/$tfile.2 failed"
21272
21273         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21274         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21275                 error "dd with O_DIRECT large read failed"
21276         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21277                 error "compare $TMP/$tfile.3 failed"
21278 }
21279 run_test 248b "test short_io read and write for both small and large sizes"
21280
21281 test_249() { # LU-7890
21282         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21283                 skip "Need at least version 2.8.54"
21284
21285         rm -f $DIR/$tfile
21286         $LFS setstripe -c 1 $DIR/$tfile
21287         # Offset 2T == 4k * 512M
21288         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21289                 error "dd to 2T offset failed"
21290 }
21291 run_test 249 "Write above 2T file size"
21292
21293 test_250() {
21294         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21295          && skip "no 16TB file size limit on ZFS"
21296
21297         $LFS setstripe -c 1 $DIR/$tfile
21298         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21299         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21300         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21301         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21302                 conv=notrunc,fsync && error "append succeeded"
21303         return 0
21304 }
21305 run_test 250 "Write above 16T limit"
21306
21307 test_251() {
21308         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21309
21310         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21311         #Skip once - writing the first stripe will succeed
21312         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21313         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21314                 error "short write happened"
21315
21316         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21317         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21318                 error "short read happened"
21319
21320         rm -f $DIR/$tfile
21321 }
21322 run_test 251 "Handling short read and write correctly"
21323
21324 test_252() {
21325         remote_mds_nodsh && skip "remote MDS with nodsh"
21326         remote_ost_nodsh && skip "remote OST with nodsh"
21327         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21328                 skip_env "ldiskfs only test"
21329         fi
21330
21331         local tgt
21332         local dev
21333         local out
21334         local uuid
21335         local num
21336         local gen
21337
21338         # check lr_reader on OST0000
21339         tgt=ost1
21340         dev=$(facet_device $tgt)
21341         out=$(do_facet $tgt $LR_READER $dev)
21342         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21343         echo "$out"
21344         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21345         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21346                 error "Invalid uuid returned by $LR_READER on target $tgt"
21347         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21348
21349         # check lr_reader -c on MDT0000
21350         tgt=mds1
21351         dev=$(facet_device $tgt)
21352         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21353                 skip "$LR_READER does not support additional options"
21354         fi
21355         out=$(do_facet $tgt $LR_READER -c $dev)
21356         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21357         echo "$out"
21358         num=$(echo "$out" | grep -c "mdtlov")
21359         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21360                 error "Invalid number of mdtlov clients returned by $LR_READER"
21361         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21362
21363         # check lr_reader -cr on MDT0000
21364         out=$(do_facet $tgt $LR_READER -cr $dev)
21365         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21366         echo "$out"
21367         echo "$out" | grep -q "^reply_data:$" ||
21368                 error "$LR_READER should have returned 'reply_data' section"
21369         num=$(echo "$out" | grep -c "client_generation")
21370         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21371 }
21372 run_test 252 "check lr_reader tool"
21373
21374 test_253() {
21375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21376         remote_mds_nodsh && skip "remote MDS with nodsh"
21377         remote_mgs_nodsh && skip "remote MGS with nodsh"
21378
21379         local ostidx=0
21380         local rc=0
21381         local ost_name=$(ostname_from_index $ostidx)
21382
21383         # on the mdt's osc
21384         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21385         do_facet $SINGLEMDS $LCTL get_param -n \
21386                 osp.$mdtosc_proc1.reserved_mb_high ||
21387                 skip  "remote MDS does not support reserved_mb_high"
21388
21389         rm -rf $DIR/$tdir
21390         wait_mds_ost_sync
21391         wait_delete_completed
21392         mkdir $DIR/$tdir
21393
21394         pool_add $TESTNAME || error "Pool creation failed"
21395         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21396
21397         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21398                 error "Setstripe failed"
21399
21400         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21401
21402         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21403                     grep "watermarks")
21404         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21405
21406         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21407                         osp.$mdtosc_proc1.prealloc_status)
21408         echo "prealloc_status $oa_status"
21409
21410         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21411                 error "File creation should fail"
21412
21413         #object allocation was stopped, but we still able to append files
21414         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21415                 oflag=append || error "Append failed"
21416
21417         rm -f $DIR/$tdir/$tfile.0
21418
21419         # For this test, we want to delete the files we created to go out of
21420         # space but leave the watermark, so we remain nearly out of space
21421         ost_watermarks_enospc_delete_files $tfile $ostidx
21422
21423         wait_delete_completed
21424
21425         sleep_maxage
21426
21427         for i in $(seq 10 12); do
21428                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21429                         2>/dev/null || error "File creation failed after rm"
21430         done
21431
21432         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21433                         osp.$mdtosc_proc1.prealloc_status)
21434         echo "prealloc_status $oa_status"
21435
21436         if (( oa_status != 0 )); then
21437                 error "Object allocation still disable after rm"
21438         fi
21439 }
21440 run_test 253 "Check object allocation limit"
21441
21442 test_254() {
21443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21444         remote_mds_nodsh && skip "remote MDS with nodsh"
21445
21446         local mdt=$(facet_svc $SINGLEMDS)
21447
21448         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21449                 skip "MDS does not support changelog_size"
21450
21451         local cl_user
21452
21453         changelog_register || error "changelog_register failed"
21454
21455         changelog_clear 0 || error "changelog_clear failed"
21456
21457         local size1=$(do_facet $SINGLEMDS \
21458                       $LCTL get_param -n mdd.$mdt.changelog_size)
21459         echo "Changelog size $size1"
21460
21461         rm -rf $DIR/$tdir
21462         $LFS mkdir -i 0 $DIR/$tdir
21463         # change something
21464         mkdir -p $DIR/$tdir/pics/2008/zachy
21465         touch $DIR/$tdir/pics/2008/zachy/timestamp
21466         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21467         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21468         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21469         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21470         rm $DIR/$tdir/pics/desktop.jpg
21471
21472         local size2=$(do_facet $SINGLEMDS \
21473                       $LCTL get_param -n mdd.$mdt.changelog_size)
21474         echo "Changelog size after work $size2"
21475
21476         (( $size2 > $size1 )) ||
21477                 error "new Changelog size=$size2 less than old size=$size1"
21478 }
21479 run_test 254 "Check changelog size"
21480
21481 ladvise_no_type()
21482 {
21483         local type=$1
21484         local file=$2
21485
21486         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21487                 awk -F: '{print $2}' | grep $type > /dev/null
21488         if [ $? -ne 0 ]; then
21489                 return 0
21490         fi
21491         return 1
21492 }
21493
21494 ladvise_no_ioctl()
21495 {
21496         local file=$1
21497
21498         lfs ladvise -a willread $file > /dev/null 2>&1
21499         if [ $? -eq 0 ]; then
21500                 return 1
21501         fi
21502
21503         lfs ladvise -a willread $file 2>&1 |
21504                 grep "Inappropriate ioctl for device" > /dev/null
21505         if [ $? -eq 0 ]; then
21506                 return 0
21507         fi
21508         return 1
21509 }
21510
21511 percent() {
21512         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21513 }
21514
21515 # run a random read IO workload
21516 # usage: random_read_iops <filename> <filesize> <iosize>
21517 random_read_iops() {
21518         local file=$1
21519         local fsize=$2
21520         local iosize=${3:-4096}
21521
21522         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21523                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21524 }
21525
21526 drop_file_oss_cache() {
21527         local file="$1"
21528         local nodes="$2"
21529
21530         $LFS ladvise -a dontneed $file 2>/dev/null ||
21531                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21532 }
21533
21534 ladvise_willread_performance()
21535 {
21536         local repeat=10
21537         local average_origin=0
21538         local average_cache=0
21539         local average_ladvise=0
21540
21541         for ((i = 1; i <= $repeat; i++)); do
21542                 echo "Iter $i/$repeat: reading without willread hint"
21543                 cancel_lru_locks osc
21544                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21545                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21546                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21547                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21548
21549                 cancel_lru_locks osc
21550                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21551                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21552                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21553
21554                 cancel_lru_locks osc
21555                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21556                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21557                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21558                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21559                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21560         done
21561         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21562         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21563         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21564
21565         speedup_cache=$(percent $average_cache $average_origin)
21566         speedup_ladvise=$(percent $average_ladvise $average_origin)
21567
21568         echo "Average uncached read: $average_origin"
21569         echo "Average speedup with OSS cached read: " \
21570                 "$average_cache = +$speedup_cache%"
21571         echo "Average speedup with ladvise willread: " \
21572                 "$average_ladvise = +$speedup_ladvise%"
21573
21574         local lowest_speedup=20
21575         if (( ${average_cache%.*} < $lowest_speedup )); then
21576                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21577                      " got $average_cache%. Skipping ladvise willread check."
21578                 return 0
21579         fi
21580
21581         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21582         # it is still good to run until then to exercise 'ladvise willread'
21583         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21584                 [ "$ost1_FSTYPE" = "zfs" ] &&
21585                 echo "osd-zfs does not support dontneed or drop_caches" &&
21586                 return 0
21587
21588         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21589         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21590                 error_not_in_vm "Speedup with willread is less than " \
21591                         "$lowest_speedup%, got $average_ladvise%"
21592 }
21593
21594 test_255a() {
21595         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21596                 skip "lustre < 2.8.54 does not support ladvise "
21597         remote_ost_nodsh && skip "remote OST with nodsh"
21598
21599         stack_trap "rm -f $DIR/$tfile"
21600         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21601
21602         ladvise_no_type willread $DIR/$tfile &&
21603                 skip "willread ladvise is not supported"
21604
21605         ladvise_no_ioctl $DIR/$tfile &&
21606                 skip "ladvise ioctl is not supported"
21607
21608         local size_mb=100
21609         local size=$((size_mb * 1048576))
21610         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21611                 error "dd to $DIR/$tfile failed"
21612
21613         lfs ladvise -a willread $DIR/$tfile ||
21614                 error "Ladvise failed with no range argument"
21615
21616         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21617                 error "Ladvise failed with no -l or -e argument"
21618
21619         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21620                 error "Ladvise failed with only -e argument"
21621
21622         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21623                 error "Ladvise failed with only -l argument"
21624
21625         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21626                 error "End offset should not be smaller than start offset"
21627
21628         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21629                 error "End offset should not be equal to start offset"
21630
21631         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21632                 error "Ladvise failed with overflowing -s argument"
21633
21634         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21635                 error "Ladvise failed with overflowing -e argument"
21636
21637         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21638                 error "Ladvise failed with overflowing -l argument"
21639
21640         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21641                 error "Ladvise succeeded with conflicting -l and -e arguments"
21642
21643         echo "Synchronous ladvise should wait"
21644         local delay=4
21645 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21646         do_nodes $(comma_list $(osts_nodes)) \
21647                 $LCTL set_param fail_val=$delay fail_loc=0x237
21648
21649         local start_ts=$SECONDS
21650         lfs ladvise -a willread $DIR/$tfile ||
21651                 error "Ladvise failed with no range argument"
21652         local end_ts=$SECONDS
21653         local inteval_ts=$((end_ts - start_ts))
21654
21655         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21656                 error "Synchronous advice didn't wait reply"
21657         fi
21658
21659         echo "Asynchronous ladvise shouldn't wait"
21660         local start_ts=$SECONDS
21661         lfs ladvise -a willread -b $DIR/$tfile ||
21662                 error "Ladvise failed with no range argument"
21663         local end_ts=$SECONDS
21664         local inteval_ts=$((end_ts - start_ts))
21665
21666         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21667                 error "Asynchronous advice blocked"
21668         fi
21669
21670         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21671         ladvise_willread_performance
21672 }
21673 run_test 255a "check 'lfs ladvise -a willread'"
21674
21675 facet_meminfo() {
21676         local facet=$1
21677         local info=$2
21678
21679         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21680 }
21681
21682 test_255b() {
21683         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21684                 skip "lustre < 2.8.54 does not support ladvise "
21685         remote_ost_nodsh && skip "remote OST with nodsh"
21686
21687         stack_trap "rm -f $DIR/$tfile"
21688         lfs setstripe -c 1 -i 0 $DIR/$tfile
21689
21690         ladvise_no_type dontneed $DIR/$tfile &&
21691                 skip "dontneed ladvise is not supported"
21692
21693         ladvise_no_ioctl $DIR/$tfile &&
21694                 skip "ladvise ioctl is not supported"
21695
21696         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21697                 [ "$ost1_FSTYPE" = "zfs" ] &&
21698                 skip "zfs-osd does not support 'ladvise dontneed'"
21699
21700         local size_mb=100
21701         local size=$((size_mb * 1048576))
21702         # In order to prevent disturbance of other processes, only check 3/4
21703         # of the memory usage
21704         local kibibytes=$((size_mb * 1024 * 3 / 4))
21705
21706         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21707                 error "dd to $DIR/$tfile failed"
21708
21709         #force write to complete before dropping OST cache & checking memory
21710         sync
21711
21712         local total=$(facet_meminfo ost1 MemTotal)
21713         echo "Total memory: $total KiB"
21714
21715         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21716         local before_read=$(facet_meminfo ost1 Cached)
21717         echo "Cache used before read: $before_read KiB"
21718
21719         lfs ladvise -a willread $DIR/$tfile ||
21720                 error "Ladvise willread failed"
21721         local after_read=$(facet_meminfo ost1 Cached)
21722         echo "Cache used after read: $after_read KiB"
21723
21724         lfs ladvise -a dontneed $DIR/$tfile ||
21725                 error "Ladvise dontneed again failed"
21726         local no_read=$(facet_meminfo ost1 Cached)
21727         echo "Cache used after dontneed ladvise: $no_read KiB"
21728
21729         if [ $total -lt $((before_read + kibibytes)) ]; then
21730                 echo "Memory is too small, abort checking"
21731                 return 0
21732         fi
21733
21734         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21735                 error "Ladvise willread should use more memory" \
21736                         "than $kibibytes KiB"
21737         fi
21738
21739         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21740                 error "Ladvise dontneed should release more memory" \
21741                         "than $kibibytes KiB"
21742         fi
21743 }
21744 run_test 255b "check 'lfs ladvise -a dontneed'"
21745
21746 test_255c() {
21747         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21748                 skip "lustre < 2.10.50 does not support lockahead"
21749
21750         local ost1_imp=$(get_osc_import_name client ost1)
21751         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21752                          cut -d'.' -f2)
21753         local count
21754         local new_count
21755         local difference
21756         local i
21757         local rc
21758
21759         test_mkdir -p $DIR/$tdir
21760         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21761
21762         #test 10 returns only success/failure
21763         i=10
21764         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21765         rc=$?
21766         if [ $rc -eq 255 ]; then
21767                 error "Ladvise test${i} failed, ${rc}"
21768         fi
21769
21770         #test 11 counts lock enqueue requests, all others count new locks
21771         i=11
21772         count=$(do_facet ost1 \
21773                 $LCTL get_param -n ost.OSS.ost.stats)
21774         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21775
21776         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21777         rc=$?
21778         if [ $rc -eq 255 ]; then
21779                 error "Ladvise test${i} failed, ${rc}"
21780         fi
21781
21782         new_count=$(do_facet ost1 \
21783                 $LCTL get_param -n ost.OSS.ost.stats)
21784         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21785                    awk '{ print $2 }')
21786
21787         difference="$((new_count - count))"
21788         if [ $difference -ne $rc ]; then
21789                 error "Ladvise test${i}, bad enqueue count, returned " \
21790                       "${rc}, actual ${difference}"
21791         fi
21792
21793         for i in $(seq 12 21); do
21794                 # If we do not do this, we run the risk of having too many
21795                 # locks and starting lock cancellation while we are checking
21796                 # lock counts.
21797                 cancel_lru_locks osc
21798
21799                 count=$($LCTL get_param -n \
21800                        ldlm.namespaces.$imp_name.lock_unused_count)
21801
21802                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21803                 rc=$?
21804                 if [ $rc -eq 255 ]; then
21805                         error "Ladvise test ${i} failed, ${rc}"
21806                 fi
21807
21808                 new_count=$($LCTL get_param -n \
21809                        ldlm.namespaces.$imp_name.lock_unused_count)
21810                 difference="$((new_count - count))"
21811
21812                 # Test 15 output is divided by 100 to map down to valid return
21813                 if [ $i -eq 15 ]; then
21814                         rc="$((rc * 100))"
21815                 fi
21816
21817                 if [ $difference -ne $rc ]; then
21818                         error "Ladvise test ${i}, bad lock count, returned " \
21819                               "${rc}, actual ${difference}"
21820                 fi
21821         done
21822
21823         #test 22 returns only success/failure
21824         i=22
21825         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21826         rc=$?
21827         if [ $rc -eq 255 ]; then
21828                 error "Ladvise test${i} failed, ${rc}"
21829         fi
21830 }
21831 run_test 255c "suite of ladvise lockahead tests"
21832
21833 test_256() {
21834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21835         remote_mds_nodsh && skip "remote MDS with nodsh"
21836         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21837         changelog_users $SINGLEMDS | grep "^cl" &&
21838                 skip "active changelog user"
21839
21840         local cl_user
21841         local cat_sl
21842         local mdt_dev
21843
21844         mdt_dev=$(facet_device $SINGLEMDS)
21845         echo $mdt_dev
21846
21847         changelog_register || error "changelog_register failed"
21848
21849         rm -rf $DIR/$tdir
21850         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
21851
21852         changelog_clear 0 || error "changelog_clear failed"
21853
21854         # change something
21855         touch $DIR/$tdir/{1..10}
21856
21857         # stop the MDT
21858         stop $SINGLEMDS || error "Fail to stop MDT"
21859
21860         # remount the MDT
21861         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21862                 error "Fail to start MDT"
21863
21864         #after mount new plainllog is used
21865         touch $DIR/$tdir/{11..19}
21866         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21867         stack_trap "rm -f $tmpfile"
21868         cat_sl=$(do_facet $SINGLEMDS "sync; \
21869                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21870                  llog_reader $tmpfile | grep -c type=1064553b")
21871         do_facet $SINGLEMDS llog_reader $tmpfile
21872
21873         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21874
21875         changelog_clear 0 || error "changelog_clear failed"
21876
21877         cat_sl=$(do_facet $SINGLEMDS "sync; \
21878                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21879                  llog_reader $tmpfile | grep -c type=1064553b")
21880
21881         if (( cat_sl == 2 )); then
21882                 error "Empty plain llog was not deleted from changelog catalog"
21883         elif (( cat_sl != 1 )); then
21884                 error "Active plain llog shouldn't be deleted from catalog"
21885         fi
21886 }
21887 run_test 256 "Check llog delete for empty and not full state"
21888
21889 test_257() {
21890         remote_mds_nodsh && skip "remote MDS with nodsh"
21891         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21892                 skip "Need MDS version at least 2.8.55"
21893
21894         test_mkdir $DIR/$tdir
21895
21896         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21897                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21898         stat $DIR/$tdir
21899
21900 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21901         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21902         local facet=mds$((mdtidx + 1))
21903         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21904         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21905
21906         stop $facet || error "stop MDS failed"
21907         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21908                 error "start MDS fail"
21909         wait_recovery_complete $facet
21910 }
21911 run_test 257 "xattr locks are not lost"
21912
21913 # Verify we take the i_mutex when security requires it
21914 test_258a() {
21915 #define OBD_FAIL_IMUTEX_SEC 0x141c
21916         $LCTL set_param fail_loc=0x141c
21917         touch $DIR/$tfile
21918         chmod u+s $DIR/$tfile
21919         chmod a+rwx $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, failed to take i_mutex, rc=$?"
21924         fi
21925         rm -f $DIR/$tfile
21926 }
21927 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21928
21929 # Verify we do NOT take the i_mutex in the normal case
21930 test_258b() {
21931 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21932         $LCTL set_param fail_loc=0x141d
21933         touch $DIR/$tfile
21934         chmod a+rwx $DIR
21935         chmod a+rw $DIR/$tfile
21936         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21937         RC=$?
21938         if [ $RC -ne 0 ]; then
21939                 error "error, took i_mutex unnecessarily, rc=$?"
21940         fi
21941         rm -f $DIR/$tfile
21942
21943 }
21944 run_test 258b "verify i_mutex security behavior"
21945
21946 test_259() {
21947         local file=$DIR/$tfile
21948         local before
21949         local after
21950
21951         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21952
21953         stack_trap "rm -f $file" EXIT
21954
21955         wait_delete_completed
21956         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21957         echo "before: $before"
21958
21959         $LFS setstripe -i 0 -c 1 $file
21960         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21961         sync_all_data
21962         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21963         echo "after write: $after"
21964
21965 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21966         do_facet ost1 $LCTL set_param fail_loc=0x2301
21967         $TRUNCATE $file 0
21968         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21969         echo "after truncate: $after"
21970
21971         stop ost1
21972         do_facet ost1 $LCTL set_param fail_loc=0
21973         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21974         sleep 2
21975         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21976         echo "after restart: $after"
21977         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21978                 error "missing truncate?"
21979
21980         return 0
21981 }
21982 run_test 259 "crash at delayed truncate"
21983
21984 test_260() {
21985 #define OBD_FAIL_MDC_CLOSE               0x806
21986         $LCTL set_param fail_loc=0x80000806
21987         touch $DIR/$tfile
21988
21989 }
21990 run_test 260 "Check mdc_close fail"
21991
21992 ### Data-on-MDT sanity tests ###
21993 test_270a() {
21994         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21995                 skip "Need MDS version at least 2.10.55 for DoM"
21996
21997         # create DoM file
21998         local dom=$DIR/$tdir/dom_file
21999         local tmp=$DIR/$tdir/tmp_file
22000
22001         mkdir_on_mdt0 $DIR/$tdir
22002
22003         # basic checks for DoM component creation
22004         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22005                 error "Can set MDT layout to non-first entry"
22006
22007         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22008                 error "Can define multiple entries as MDT layout"
22009
22010         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22011
22012         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22013         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22014         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22015
22016         local mdtidx=$($LFS getstripe -m $dom)
22017         local mdtname=MDT$(printf %04x $mdtidx)
22018         local facet=mds$((mdtidx + 1))
22019         local space_check=1
22020
22021         # Skip free space checks with ZFS
22022         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22023
22024         # write
22025         sync
22026         local size_tmp=$((65536 * 3))
22027         local mdtfree1=$(do_facet $facet \
22028                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22029
22030         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22031         # check also direct IO along write
22032         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22033         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22034         sync
22035         cmp $tmp $dom || error "file data is different"
22036         [ $(stat -c%s $dom) == $size_tmp ] ||
22037                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22038         if [ $space_check == 1 ]; then
22039                 local mdtfree2=$(do_facet $facet \
22040                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22041
22042                 # increase in usage from by $size_tmp
22043                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22044                         error "MDT free space wrong after write: " \
22045                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22046         fi
22047
22048         # truncate
22049         local size_dom=10000
22050
22051         $TRUNCATE $dom $size_dom
22052         [ $(stat -c%s $dom) == $size_dom ] ||
22053                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22054         if [ $space_check == 1 ]; then
22055                 mdtfree1=$(do_facet $facet \
22056                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22057                 # decrease in usage from $size_tmp to new $size_dom
22058                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22059                   $(((size_tmp - size_dom) / 1024)) ] ||
22060                         error "MDT free space is wrong after truncate: " \
22061                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22062         fi
22063
22064         # append
22065         cat $tmp >> $dom
22066         sync
22067         size_dom=$((size_dom + size_tmp))
22068         [ $(stat -c%s $dom) == $size_dom ] ||
22069                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22070         if [ $space_check == 1 ]; then
22071                 mdtfree2=$(do_facet $facet \
22072                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22073                 # increase in usage by $size_tmp from previous
22074                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22075                         error "MDT free space is wrong after append: " \
22076                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22077         fi
22078
22079         # delete
22080         rm $dom
22081         if [ $space_check == 1 ]; then
22082                 mdtfree1=$(do_facet $facet \
22083                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22084                 # decrease in usage by $size_dom from previous
22085                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22086                         error "MDT free space is wrong after removal: " \
22087                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22088         fi
22089
22090         # combined striping
22091         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22092                 error "Can't create DoM + OST striping"
22093
22094         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22095         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22096         # check also direct IO along write
22097         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22098         sync
22099         cmp $tmp $dom || error "file data is different"
22100         [ $(stat -c%s $dom) == $size_tmp ] ||
22101                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22102         rm $dom $tmp
22103
22104         return 0
22105 }
22106 run_test 270a "DoM: basic functionality tests"
22107
22108 test_270b() {
22109         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22110                 skip "Need MDS version at least 2.10.55"
22111
22112         local dom=$DIR/$tdir/dom_file
22113         local max_size=1048576
22114
22115         mkdir -p $DIR/$tdir
22116         $LFS setstripe -E $max_size -L mdt $dom
22117
22118         # truncate over the limit
22119         $TRUNCATE $dom $(($max_size + 1)) &&
22120                 error "successful truncate over the maximum size"
22121         # write over the limit
22122         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22123                 error "successful write over the maximum size"
22124         # append over the limit
22125         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22126         echo "12345" >> $dom && error "successful append over the maximum size"
22127         rm $dom
22128
22129         return 0
22130 }
22131 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22132
22133 test_270c() {
22134         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22135                 skip "Need MDS version at least 2.10.55"
22136
22137         mkdir -p $DIR/$tdir
22138         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22139
22140         # check files inherit DoM EA
22141         touch $DIR/$tdir/first
22142         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22143                 error "bad pattern"
22144         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22145                 error "bad stripe count"
22146         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22147                 error "bad stripe size"
22148
22149         # check directory inherits DoM EA and uses it as default
22150         mkdir $DIR/$tdir/subdir
22151         touch $DIR/$tdir/subdir/second
22152         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22153                 error "bad pattern in sub-directory"
22154         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22155                 error "bad stripe count in sub-directory"
22156         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22157                 error "bad stripe size in sub-directory"
22158         return 0
22159 }
22160 run_test 270c "DoM: DoM EA inheritance tests"
22161
22162 test_270d() {
22163         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22164                 skip "Need MDS version at least 2.10.55"
22165
22166         mkdir -p $DIR/$tdir
22167         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22168
22169         # inherit default DoM striping
22170         mkdir $DIR/$tdir/subdir
22171         touch $DIR/$tdir/subdir/f1
22172
22173         # change default directory striping
22174         $LFS setstripe -c 1 $DIR/$tdir/subdir
22175         touch $DIR/$tdir/subdir/f2
22176         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22177                 error "wrong default striping in file 2"
22178         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22179                 error "bad pattern in file 2"
22180         return 0
22181 }
22182 run_test 270d "DoM: change striping from DoM to RAID0"
22183
22184 test_270e() {
22185         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22186                 skip "Need MDS version at least 2.10.55"
22187
22188         mkdir -p $DIR/$tdir/dom
22189         mkdir -p $DIR/$tdir/norm
22190         DOMFILES=20
22191         NORMFILES=10
22192         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22193         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22194
22195         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22196         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22197
22198         # find DoM files by layout
22199         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22200         [ $NUM -eq  $DOMFILES ] ||
22201                 error "lfs find -L: found $NUM, expected $DOMFILES"
22202         echo "Test 1: lfs find 20 DOM files by layout: OK"
22203
22204         # there should be 1 dir with default DOM striping
22205         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22206         [ $NUM -eq  1 ] ||
22207                 error "lfs find -L: found $NUM, expected 1 dir"
22208         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22209
22210         # find DoM files by stripe size
22211         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22212         [ $NUM -eq  $DOMFILES ] ||
22213                 error "lfs find -S: found $NUM, expected $DOMFILES"
22214         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22215
22216         # find files by stripe offset except DoM files
22217         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22218         [ $NUM -eq  $NORMFILES ] ||
22219                 error "lfs find -i: found $NUM, expected $NORMFILES"
22220         echo "Test 5: lfs find no DOM files by stripe index: OK"
22221         return 0
22222 }
22223 run_test 270e "DoM: lfs find with DoM files test"
22224
22225 test_270f() {
22226         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22227                 skip "Need MDS version at least 2.10.55"
22228
22229         local mdtname=${FSNAME}-MDT0000-mdtlov
22230         local dom=$DIR/$tdir/dom_file
22231         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22232                                                 lod.$mdtname.dom_stripesize)
22233         local dom_limit=131072
22234
22235         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22236         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22237                                                 lod.$mdtname.dom_stripesize)
22238         [ ${dom_limit} -eq ${dom_current} ] ||
22239                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22240
22241         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22242         $LFS setstripe -d $DIR/$tdir
22243         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22244                 error "Can't set directory default striping"
22245
22246         # exceed maximum stripe size
22247         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22248                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22249         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22250                 error "Able to create DoM component size more than LOD limit"
22251
22252         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22253         dom_current=$(do_facet mds1 $LCTL get_param -n \
22254                                                 lod.$mdtname.dom_stripesize)
22255         [ 0 -eq ${dom_current} ] ||
22256                 error "Can't set zero DoM stripe limit"
22257         rm $dom
22258
22259         # attempt to create DoM file on server with disabled DoM should
22260         # remove DoM entry from layout and be succeed
22261         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22262                 error "Can't create DoM file (DoM is disabled)"
22263         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22264                 error "File has DoM component while DoM is disabled"
22265         rm $dom
22266
22267         # attempt to create DoM file with only DoM stripe should return error
22268         $LFS setstripe -E $dom_limit -L mdt $dom &&
22269                 error "Able to create DoM-only file while DoM is disabled"
22270
22271         # too low values to be aligned with smallest stripe size 64K
22272         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22273         dom_current=$(do_facet mds1 $LCTL get_param -n \
22274                                                 lod.$mdtname.dom_stripesize)
22275         [ 30000 -eq ${dom_current} ] &&
22276                 error "Can set too small DoM stripe limit"
22277
22278         # 64K is a minimal stripe size in Lustre, expect limit of that size
22279         [ 65536 -eq ${dom_current} ] ||
22280                 error "Limit is not set to 64K but ${dom_current}"
22281
22282         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22283         dom_current=$(do_facet mds1 $LCTL get_param -n \
22284                                                 lod.$mdtname.dom_stripesize)
22285         echo $dom_current
22286         [ 2147483648 -eq ${dom_current} ] &&
22287                 error "Can set too large DoM stripe limit"
22288
22289         do_facet mds1 $LCTL set_param -n \
22290                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22291         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22292                 error "Can't create DoM component size after limit change"
22293         do_facet mds1 $LCTL set_param -n \
22294                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22295         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22296                 error "Can't create DoM file after limit decrease"
22297         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22298                 error "Can create big DoM component after limit decrease"
22299         touch ${dom}_def ||
22300                 error "Can't create file with old default layout"
22301
22302         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22303         return 0
22304 }
22305 run_test 270f "DoM: maximum DoM stripe size checks"
22306
22307 test_270g() {
22308         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22309                 skip "Need MDS version at least 2.13.52"
22310         local dom=$DIR/$tdir/$tfile
22311
22312         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22313         local lodname=${FSNAME}-MDT0000-mdtlov
22314
22315         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22316         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22317         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22318         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22319
22320         local dom_limit=1024
22321         local dom_threshold="50%"
22322
22323         $LFS setstripe -d $DIR/$tdir
22324         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22325                 error "Can't set directory default striping"
22326
22327         do_facet mds1 $LCTL set_param -n \
22328                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22329         # set 0 threshold and create DOM file to change tunable stripesize
22330         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22331         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22332                 error "Failed to create $dom file"
22333         # now tunable dom_cur_stripesize should reach maximum
22334         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22335                                         lod.${lodname}.dom_stripesize_cur_kb)
22336         [[ $dom_current == $dom_limit ]] ||
22337                 error "Current DOM stripesize is not maximum"
22338         rm $dom
22339
22340         # set threshold for further tests
22341         do_facet mds1 $LCTL set_param -n \
22342                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22343         echo "DOM threshold is $dom_threshold free space"
22344         local dom_def
22345         local dom_set
22346         # Spoof bfree to exceed threshold
22347         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22348         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22349         for spfree in 40 20 0 15 30 55; do
22350                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22351                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22352                         error "Failed to create $dom file"
22353                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22354                                         lod.${lodname}.dom_stripesize_cur_kb)
22355                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22356                 [[ $dom_def != $dom_current ]] ||
22357                         error "Default stripe size was not changed"
22358                 if [[ $spfree > 0 ]] ; then
22359                         dom_set=$($LFS getstripe -S $dom)
22360                         [[ $dom_set == $((dom_def * 1024)) ]] ||
22361                                 error "DOM component size is still old"
22362                 else
22363                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22364                                 error "DoM component is set with no free space"
22365                 fi
22366                 rm $dom
22367                 dom_current=$dom_def
22368         done
22369 }
22370 run_test 270g "DoM: default DoM stripe size depends on free space"
22371
22372 test_270h() {
22373         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22374                 skip "Need MDS version at least 2.13.53"
22375
22376         local mdtname=${FSNAME}-MDT0000-mdtlov
22377         local dom=$DIR/$tdir/$tfile
22378         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22379
22380         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22381         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22382
22383         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22384         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22385                 error "can't create OST file"
22386         # mirrored file with DOM entry in the second mirror
22387         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22388                 error "can't create mirror with DoM component"
22389
22390         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22391
22392         # DOM component in the middle and has other enries in the same mirror,
22393         # should succeed but lost DoM component
22394         $LFS setstripe --copy=${dom}_1 $dom ||
22395                 error "Can't create file from OST|DOM mirror layout"
22396         # check new file has no DoM layout after all
22397         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22398                 error "File has DoM component while DoM is disabled"
22399 }
22400 run_test 270h "DoM: DoM stripe removal when disabled on server"
22401
22402 test_270i() {
22403         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22404                 skip "Need MDS version at least 2.14.54"
22405
22406         mkdir $DIR/$tdir
22407         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22408                 error "setstripe should fail" || true
22409 }
22410 run_test 270i "DoM: setting invalid DoM striping should fail"
22411
22412 test_271a() {
22413         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22414                 skip "Need MDS version at least 2.10.55"
22415
22416         local dom=$DIR/$tdir/dom
22417
22418         mkdir -p $DIR/$tdir
22419
22420         $LFS setstripe -E 1024K -L mdt $dom
22421
22422         lctl set_param -n mdc.*.stats=clear
22423         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22424         cat $dom > /dev/null
22425         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22426         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22427         ls $dom
22428         rm -f $dom
22429 }
22430 run_test 271a "DoM: data is cached for read after write"
22431
22432 test_271b() {
22433         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22434                 skip "Need MDS version at least 2.10.55"
22435
22436         local dom=$DIR/$tdir/dom
22437
22438         mkdir -p $DIR/$tdir
22439
22440         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22441
22442         lctl set_param -n mdc.*.stats=clear
22443         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22444         cancel_lru_locks mdc
22445         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22446         # second stat to check size is cached on client
22447         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22448         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22449         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22450         rm -f $dom
22451 }
22452 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22453
22454 test_271ba() {
22455         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22456                 skip "Need MDS version at least 2.10.55"
22457
22458         local dom=$DIR/$tdir/dom
22459
22460         mkdir -p $DIR/$tdir
22461
22462         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22463
22464         lctl set_param -n mdc.*.stats=clear
22465         lctl set_param -n osc.*.stats=clear
22466         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22467         cancel_lru_locks mdc
22468         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22469         # second stat to check size is cached on client
22470         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22471         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22472         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22473         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22474         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22475         rm -f $dom
22476 }
22477 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22478
22479
22480 get_mdc_stats() {
22481         local mdtidx=$1
22482         local param=$2
22483         local mdt=MDT$(printf %04x $mdtidx)
22484
22485         if [ -z $param ]; then
22486                 lctl get_param -n mdc.*$mdt*.stats
22487         else
22488                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22489         fi
22490 }
22491
22492 test_271c() {
22493         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22494                 skip "Need MDS version at least 2.10.55"
22495
22496         local dom=$DIR/$tdir/dom
22497
22498         mkdir -p $DIR/$tdir
22499
22500         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22501
22502         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22503         local facet=mds$((mdtidx + 1))
22504
22505         cancel_lru_locks mdc
22506         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22507         createmany -o $dom 1000
22508         lctl set_param -n mdc.*.stats=clear
22509         smalliomany -w $dom 1000 200
22510         get_mdc_stats $mdtidx
22511         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22512         # Each file has 1 open, 1 IO enqueues, total 2000
22513         # but now we have also +1 getxattr for security.capability, total 3000
22514         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22515         unlinkmany $dom 1000
22516
22517         cancel_lru_locks mdc
22518         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22519         createmany -o $dom 1000
22520         lctl set_param -n mdc.*.stats=clear
22521         smalliomany -w $dom 1000 200
22522         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22523         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22524         # for OPEN and IO lock.
22525         [ $((enq - enq_2)) -ge 1000 ] ||
22526                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22527         unlinkmany $dom 1000
22528         return 0
22529 }
22530 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22531
22532 cleanup_271def_tests() {
22533         trap 0
22534         rm -f $1
22535 }
22536
22537 test_271d() {
22538         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22539                 skip "Need MDS version at least 2.10.57"
22540
22541         local dom=$DIR/$tdir/dom
22542         local tmp=$TMP/$tfile
22543         trap "cleanup_271def_tests $tmp" EXIT
22544
22545         mkdir -p $DIR/$tdir
22546
22547         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22548
22549         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22550
22551         cancel_lru_locks mdc
22552         dd if=/dev/urandom of=$tmp bs=1000 count=1
22553         dd if=$tmp of=$dom bs=1000 count=1
22554         cancel_lru_locks mdc
22555
22556         cat /etc/hosts >> $tmp
22557         lctl set_param -n mdc.*.stats=clear
22558
22559         # append data to the same file it should update local page
22560         echo "Append to the same page"
22561         cat /etc/hosts >> $dom
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         cancel_lru_locks mdc
22574         lctl set_param -n mdc.*.stats=clear
22575
22576         echo "Open and read file"
22577         cat $dom > /dev/null
22578         local num=$(get_mdc_stats $mdtidx ost_read)
22579         local ra=$(get_mdc_stats $mdtidx req_active)
22580         local rw=$(get_mdc_stats $mdtidx req_waittime)
22581
22582         [ -z $num ] || error "$num READ RPC occured"
22583         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22584         echo "... DONE"
22585
22586         # compare content
22587         cmp $tmp $dom || error "file miscompare"
22588
22589         return 0
22590 }
22591 run_test 271d "DoM: read on open (1K file in reply buffer)"
22592
22593 test_271f() {
22594         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22595                 skip "Need MDS version at least 2.10.57"
22596
22597         local dom=$DIR/$tdir/dom
22598         local tmp=$TMP/$tfile
22599         trap "cleanup_271def_tests $tmp" EXIT
22600
22601         mkdir -p $DIR/$tdir
22602
22603         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22604
22605         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22606
22607         cancel_lru_locks mdc
22608         dd if=/dev/urandom of=$tmp bs=265000 count=1
22609         dd if=$tmp of=$dom bs=265000 count=1
22610         cancel_lru_locks mdc
22611         cat /etc/hosts >> $tmp
22612         lctl set_param -n mdc.*.stats=clear
22613
22614         echo "Append to the same page"
22615         cat /etc/hosts >> $dom
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 ] || error "$num READ RPC occured"
22621         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22622         echo "... DONE"
22623
22624         # compare content
22625         cmp $tmp $dom || error "file miscompare"
22626
22627         cancel_lru_locks mdc
22628         lctl set_param -n mdc.*.stats=clear
22629
22630         echo "Open and read file"
22631         cat $dom > /dev/null
22632         local num=$(get_mdc_stats $mdtidx ost_read)
22633         local ra=$(get_mdc_stats $mdtidx req_active)
22634         local rw=$(get_mdc_stats $mdtidx req_waittime)
22635
22636         [ -z $num ] && num=0
22637         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22638         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22639         echo "... DONE"
22640
22641         # compare content
22642         cmp $tmp $dom || error "file miscompare"
22643
22644         return 0
22645 }
22646 run_test 271f "DoM: read on open (200K file and read tail)"
22647
22648 test_271g() {
22649         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22650                 skip "Skipping due to old client or server version"
22651
22652         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22653         # to get layout
22654         $CHECKSTAT -t file $DIR1/$tfile
22655
22656         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22657         MULTIOP_PID=$!
22658         sleep 1
22659         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22660         $LCTL set_param fail_loc=0x80000314
22661         rm $DIR1/$tfile || error "Unlink fails"
22662         RC=$?
22663         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22664         [ $RC -eq 0 ] || error "Failed write to stale object"
22665 }
22666 run_test 271g "Discard DoM data vs client flush race"
22667
22668 test_272a() {
22669         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22670                 skip "Need MDS version at least 2.11.50"
22671
22672         local dom=$DIR/$tdir/dom
22673         mkdir -p $DIR/$tdir
22674
22675         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22676         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22677                 error "failed to write data into $dom"
22678         local old_md5=$(md5sum $dom)
22679
22680         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22681                 error "failed to migrate to the same DoM component"
22682
22683         local new_md5=$(md5sum $dom)
22684
22685         [ "$old_md5" == "$new_md5" ] ||
22686                 error "md5sum differ: $old_md5, $new_md5"
22687
22688         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22689                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22690 }
22691 run_test 272a "DoM migration: new layout with the same DOM component"
22692
22693 test_272b() {
22694         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22695                 skip "Need MDS version at least 2.11.50"
22696
22697         local dom=$DIR/$tdir/dom
22698         mkdir -p $DIR/$tdir
22699         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22700
22701         local mdtidx=$($LFS getstripe -m $dom)
22702         local mdtname=MDT$(printf %04x $mdtidx)
22703         local facet=mds$((mdtidx + 1))
22704
22705         local mdtfree1=$(do_facet $facet \
22706                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22707         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22708                 error "failed to write data into $dom"
22709         local old_md5=$(md5sum $dom)
22710         cancel_lru_locks mdc
22711         local mdtfree1=$(do_facet $facet \
22712                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22713
22714         $LFS migrate -c2 $dom ||
22715                 error "failed to migrate to the new composite layout"
22716         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22717                 error "MDT stripe was not removed"
22718
22719         cancel_lru_locks mdc
22720         local new_md5=$(md5sum $dom)
22721         [ "$old_md5" == "$new_md5" ] ||
22722                 error "$old_md5 != $new_md5"
22723
22724         # Skip free space checks with ZFS
22725         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22726                 local mdtfree2=$(do_facet $facet \
22727                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22728                 [ $mdtfree2 -gt $mdtfree1 ] ||
22729                         error "MDT space is not freed after migration"
22730         fi
22731         return 0
22732 }
22733 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22734
22735 test_272c() {
22736         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22737                 skip "Need MDS version at least 2.11.50"
22738
22739         local dom=$DIR/$tdir/$tfile
22740         mkdir -p $DIR/$tdir
22741         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22742
22743         local mdtidx=$($LFS getstripe -m $dom)
22744         local mdtname=MDT$(printf %04x $mdtidx)
22745         local facet=mds$((mdtidx + 1))
22746
22747         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22748                 error "failed to write data into $dom"
22749         local old_md5=$(md5sum $dom)
22750         cancel_lru_locks mdc
22751         local mdtfree1=$(do_facet $facet \
22752                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22753
22754         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22755                 error "failed to migrate to the new composite layout"
22756         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22757                 error "MDT stripe was not removed"
22758
22759         cancel_lru_locks mdc
22760         local new_md5=$(md5sum $dom)
22761         [ "$old_md5" == "$new_md5" ] ||
22762                 error "$old_md5 != $new_md5"
22763
22764         # Skip free space checks with ZFS
22765         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22766                 local mdtfree2=$(do_facet $facet \
22767                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22768                 [ $mdtfree2 -gt $mdtfree1 ] ||
22769                         error "MDS space is not freed after migration"
22770         fi
22771         return 0
22772 }
22773 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22774
22775 test_272d() {
22776         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22777                 skip "Need MDS version at least 2.12.55"
22778
22779         local dom=$DIR/$tdir/$tfile
22780         mkdir -p $DIR/$tdir
22781         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22782
22783         local mdtidx=$($LFS getstripe -m $dom)
22784         local mdtname=MDT$(printf %04x $mdtidx)
22785         local facet=mds$((mdtidx + 1))
22786
22787         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22788                 error "failed to write data into $dom"
22789         local old_md5=$(md5sum $dom)
22790         cancel_lru_locks mdc
22791         local mdtfree1=$(do_facet $facet \
22792                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22793
22794         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22795                 error "failed mirroring to the new composite layout"
22796         $LFS mirror resync $dom ||
22797                 error "failed mirror resync"
22798         $LFS mirror split --mirror-id 1 -d $dom ||
22799                 error "failed mirror split"
22800
22801         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22802                 error "MDT stripe was not removed"
22803
22804         cancel_lru_locks mdc
22805         local new_md5=$(md5sum $dom)
22806         [ "$old_md5" == "$new_md5" ] ||
22807                 error "$old_md5 != $new_md5"
22808
22809         # Skip free space checks with ZFS
22810         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22811                 local mdtfree2=$(do_facet $facet \
22812                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22813                 [ $mdtfree2 -gt $mdtfree1 ] ||
22814                         error "MDS space is not freed after DOM mirror deletion"
22815         fi
22816         return 0
22817 }
22818 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22819
22820 test_272e() {
22821         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22822                 skip "Need MDS version at least 2.12.55"
22823
22824         local dom=$DIR/$tdir/$tfile
22825         mkdir -p $DIR/$tdir
22826         $LFS setstripe -c 2 $dom
22827
22828         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22829                 error "failed to write data into $dom"
22830         local old_md5=$(md5sum $dom)
22831         cancel_lru_locks
22832
22833         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22834                 error "failed mirroring to the DOM layout"
22835         $LFS mirror resync $dom ||
22836                 error "failed mirror resync"
22837         $LFS mirror split --mirror-id 1 -d $dom ||
22838                 error "failed mirror split"
22839
22840         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22841                 error "MDT stripe wasn't set"
22842
22843         cancel_lru_locks
22844         local new_md5=$(md5sum $dom)
22845         [ "$old_md5" == "$new_md5" ] ||
22846                 error "$old_md5 != $new_md5"
22847
22848         return 0
22849 }
22850 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22851
22852 test_272f() {
22853         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22854                 skip "Need MDS version at least 2.12.55"
22855
22856         local dom=$DIR/$tdir/$tfile
22857         mkdir -p $DIR/$tdir
22858         $LFS setstripe -c 2 $dom
22859
22860         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22861                 error "failed to write data into $dom"
22862         local old_md5=$(md5sum $dom)
22863         cancel_lru_locks
22864
22865         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22866                 error "failed migrating to the DOM file"
22867
22868         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22869                 error "MDT stripe wasn't set"
22870
22871         cancel_lru_locks
22872         local new_md5=$(md5sum $dom)
22873         [ "$old_md5" != "$new_md5" ] &&
22874                 error "$old_md5 != $new_md5"
22875
22876         return 0
22877 }
22878 run_test 272f "DoM migration: OST-striped file to DOM file"
22879
22880 test_273a() {
22881         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22882                 skip "Need MDS version at least 2.11.50"
22883
22884         # Layout swap cannot be done if either file has DOM component,
22885         # this will never be supported, migration should be used instead
22886
22887         local dom=$DIR/$tdir/$tfile
22888         mkdir -p $DIR/$tdir
22889
22890         $LFS setstripe -c2 ${dom}_plain
22891         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22892         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22893                 error "can swap layout with DoM component"
22894         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22895                 error "can swap layout with DoM component"
22896
22897         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22898         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22899                 error "can swap layout with DoM component"
22900         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22901                 error "can swap layout with DoM component"
22902         return 0
22903 }
22904 run_test 273a "DoM: layout swapping should fail with DOM"
22905
22906 test_273b() {
22907         mkdir -p $DIR/$tdir
22908         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22909
22910 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22911         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22912
22913         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22914 }
22915 run_test 273b "DoM: race writeback and object destroy"
22916
22917 test_275() {
22918         remote_ost_nodsh && skip "remote OST with nodsh"
22919         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22920                 skip "Need OST version >= 2.10.57"
22921
22922         local file=$DIR/$tfile
22923         local oss
22924
22925         oss=$(comma_list $(osts_nodes))
22926
22927         dd if=/dev/urandom of=$file bs=1M count=2 ||
22928                 error "failed to create a file"
22929         cancel_lru_locks osc
22930
22931         #lock 1
22932         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22933                 error "failed to read a file"
22934
22935 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22936         $LCTL set_param fail_loc=0x8000031f
22937
22938         cancel_lru_locks osc &
22939         sleep 1
22940
22941 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22942         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22943         #IO takes another lock, but matches the PENDING one
22944         #and places it to the IO RPC
22945         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22946                 error "failed to read a file with PENDING lock"
22947 }
22948 run_test 275 "Read on a canceled duplicate lock"
22949
22950 test_276() {
22951         remote_ost_nodsh && skip "remote OST with nodsh"
22952         local pid
22953
22954         do_facet ost1 "(while true; do \
22955                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22956                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22957         pid=$!
22958
22959         for LOOP in $(seq 20); do
22960                 stop ost1
22961                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22962         done
22963         kill -9 $pid
22964         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22965                 rm $TMP/sanity_276_pid"
22966 }
22967 run_test 276 "Race between mount and obd_statfs"
22968
22969 test_277() {
22970         $LCTL set_param ldlm.namespaces.*.lru_size=0
22971         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22972         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22973                         grep ^used_mb | awk '{print $2}')
22974         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22975         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22976                 oflag=direct conv=notrunc
22977         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22978                         grep ^used_mb | awk '{print $2}')
22979         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22980 }
22981 run_test 277 "Direct IO shall drop page cache"
22982
22983 test_278() {
22984         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22985         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22986         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22987                 skip "needs the same host for mdt1 mdt2" && return
22988
22989         local pid1
22990         local pid2
22991
22992 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22993         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22994         stop mds2 &
22995         pid2=$!
22996
22997         stop mds1
22998
22999         echo "Starting MDTs"
23000         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23001         wait $pid2
23002 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23003 #will return NULL
23004         do_facet mds2 $LCTL set_param fail_loc=0
23005
23006         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23007         wait_recovery_complete mds2
23008 }
23009 run_test 278 "Race starting MDS between MDTs stop/start"
23010
23011 test_280() {
23012         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23013                 skip "Need MGS version at least 2.13.52"
23014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23015         combined_mgs_mds || skip "needs combined MGS/MDT"
23016
23017         umount_client $MOUNT
23018 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23019         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23020
23021         mount_client $MOUNT &
23022         sleep 1
23023         stop mgs || error "stop mgs failed"
23024         #for a race mgs would crash
23025         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23026         # make sure we unmount client before remounting
23027         wait
23028         umount_client $MOUNT
23029         mount_client $MOUNT || error "mount client failed"
23030 }
23031 run_test 280 "Race between MGS umount and client llog processing"
23032
23033 cleanup_test_300() {
23034         trap 0
23035         umask $SAVE_UMASK
23036 }
23037 test_striped_dir() {
23038         local mdt_index=$1
23039         local stripe_count
23040         local stripe_index
23041
23042         mkdir -p $DIR/$tdir
23043
23044         SAVE_UMASK=$(umask)
23045         trap cleanup_test_300 RETURN EXIT
23046
23047         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23048                                                 $DIR/$tdir/striped_dir ||
23049                 error "set striped dir error"
23050
23051         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23052         [ "$mode" = "755" ] || error "expect 755 got $mode"
23053
23054         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23055                 error "getdirstripe failed"
23056         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23057         if [ "$stripe_count" != "2" ]; then
23058                 error "1:stripe_count is $stripe_count, expect 2"
23059         fi
23060         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23061         if [ "$stripe_count" != "2" ]; then
23062                 error "2:stripe_count is $stripe_count, expect 2"
23063         fi
23064
23065         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23066         if [ "$stripe_index" != "$mdt_index" ]; then
23067                 error "stripe_index is $stripe_index, expect $mdt_index"
23068         fi
23069
23070         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23071                 error "nlink error after create striped dir"
23072
23073         mkdir $DIR/$tdir/striped_dir/a
23074         mkdir $DIR/$tdir/striped_dir/b
23075
23076         stat $DIR/$tdir/striped_dir/a ||
23077                 error "create dir under striped dir failed"
23078         stat $DIR/$tdir/striped_dir/b ||
23079                 error "create dir under striped dir failed"
23080
23081         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23082                 error "nlink error after mkdir"
23083
23084         rmdir $DIR/$tdir/striped_dir/a
23085         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23086                 error "nlink error after rmdir"
23087
23088         rmdir $DIR/$tdir/striped_dir/b
23089         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23090                 error "nlink error after rmdir"
23091
23092         chattr +i $DIR/$tdir/striped_dir
23093         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23094                 error "immutable flags not working under striped dir!"
23095         chattr -i $DIR/$tdir/striped_dir
23096
23097         rmdir $DIR/$tdir/striped_dir ||
23098                 error "rmdir striped dir error"
23099
23100         cleanup_test_300
23101
23102         true
23103 }
23104
23105 test_300a() {
23106         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23107                 skip "skipped for lustre < 2.7.0"
23108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23109         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23110
23111         test_striped_dir 0 || error "failed on striped dir on MDT0"
23112         test_striped_dir 1 || error "failed on striped dir on MDT0"
23113 }
23114 run_test 300a "basic striped dir sanity test"
23115
23116 test_300b() {
23117         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23118                 skip "skipped for lustre < 2.7.0"
23119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23120         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23121
23122         local i
23123         local mtime1
23124         local mtime2
23125         local mtime3
23126
23127         test_mkdir $DIR/$tdir || error "mkdir fail"
23128         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23129                 error "set striped dir error"
23130         for i in {0..9}; do
23131                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23132                 sleep 1
23133                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23134                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23135                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23136                 sleep 1
23137                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23138                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23139                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23140         done
23141         true
23142 }
23143 run_test 300b "check ctime/mtime for striped dir"
23144
23145 test_300c() {
23146         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23147                 skip "skipped for lustre < 2.7.0"
23148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23149         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23150
23151         local file_count
23152
23153         mkdir_on_mdt0 $DIR/$tdir
23154         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23155                 error "set striped dir error"
23156
23157         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23158                 error "chown striped dir failed"
23159
23160         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23161                 error "create 5k files failed"
23162
23163         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23164
23165         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23166
23167         rm -rf $DIR/$tdir
23168 }
23169 run_test 300c "chown && check ls under striped directory"
23170
23171 test_300d() {
23172         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23173                 skip "skipped for lustre < 2.7.0"
23174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23175         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23176
23177         local stripe_count
23178         local file
23179
23180         mkdir -p $DIR/$tdir
23181         $LFS setstripe -c 2 $DIR/$tdir
23182
23183         #local striped directory
23184         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23185                 error "set striped dir error"
23186         #look at the directories for debug purposes
23187         ls -l $DIR/$tdir
23188         $LFS getdirstripe $DIR/$tdir
23189         ls -l $DIR/$tdir/striped_dir
23190         $LFS getdirstripe $DIR/$tdir/striped_dir
23191         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23192                 error "create 10 files failed"
23193
23194         #remote striped directory
23195         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23196                 error "set striped dir error"
23197         #look at the directories for debug purposes
23198         ls -l $DIR/$tdir
23199         $LFS getdirstripe $DIR/$tdir
23200         ls -l $DIR/$tdir/remote_striped_dir
23201         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23202         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23203                 error "create 10 files failed"
23204
23205         for file in $(find $DIR/$tdir); do
23206                 stripe_count=$($LFS getstripe -c $file)
23207                 [ $stripe_count -eq 2 ] ||
23208                         error "wrong stripe $stripe_count for $file"
23209         done
23210
23211         rm -rf $DIR/$tdir
23212 }
23213 run_test 300d "check default stripe under striped directory"
23214
23215 test_300e() {
23216         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23217                 skip "Need MDS version at least 2.7.55"
23218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23219         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23220
23221         local stripe_count
23222         local file
23223
23224         mkdir -p $DIR/$tdir
23225
23226         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23227                 error "set striped dir error"
23228
23229         touch $DIR/$tdir/striped_dir/a
23230         touch $DIR/$tdir/striped_dir/b
23231         touch $DIR/$tdir/striped_dir/c
23232
23233         mkdir $DIR/$tdir/striped_dir/dir_a
23234         mkdir $DIR/$tdir/striped_dir/dir_b
23235         mkdir $DIR/$tdir/striped_dir/dir_c
23236
23237         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23238                 error "set striped adir under striped dir error"
23239
23240         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23241                 error "set striped bdir under striped dir error"
23242
23243         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23244                 error "set striped cdir under striped dir error"
23245
23246         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23247                 error "rename dir under striped dir fails"
23248
23249         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23250                 error "rename dir under different stripes fails"
23251
23252         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23253                 error "rename file under striped dir should succeed"
23254
23255         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23256                 error "rename dir under striped dir should succeed"
23257
23258         rm -rf $DIR/$tdir
23259 }
23260 run_test 300e "check rename under striped directory"
23261
23262 test_300f() {
23263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23264         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23265         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23266                 skip "Need MDS version at least 2.7.55"
23267
23268         local stripe_count
23269         local file
23270
23271         rm -rf $DIR/$tdir
23272         mkdir -p $DIR/$tdir
23273
23274         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23275                 error "set striped dir error"
23276
23277         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23278                 error "set striped dir error"
23279
23280         touch $DIR/$tdir/striped_dir/a
23281         mkdir $DIR/$tdir/striped_dir/dir_a
23282         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23283                 error "create striped dir under striped dir fails"
23284
23285         touch $DIR/$tdir/striped_dir1/b
23286         mkdir $DIR/$tdir/striped_dir1/dir_b
23287         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23288                 error "create striped dir under striped dir fails"
23289
23290         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23291                 error "rename dir under different striped dir should fail"
23292
23293         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23294                 error "rename striped dir under diff striped dir should fail"
23295
23296         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23297                 error "rename file under diff striped dirs fails"
23298
23299         rm -rf $DIR/$tdir
23300 }
23301 run_test 300f "check rename cross striped directory"
23302
23303 test_300_check_default_striped_dir()
23304 {
23305         local dirname=$1
23306         local default_count=$2
23307         local default_index=$3
23308         local stripe_count
23309         local stripe_index
23310         local dir_stripe_index
23311         local dir
23312
23313         echo "checking $dirname $default_count $default_index"
23314         $LFS setdirstripe -D -c $default_count -i $default_index \
23315                                 -H all_char $DIR/$tdir/$dirname ||
23316                 error "set default stripe on striped dir error"
23317         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23318         [ $stripe_count -eq $default_count ] ||
23319                 error "expect $default_count get $stripe_count for $dirname"
23320
23321         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23322         [ $stripe_index -eq $default_index ] ||
23323                 error "expect $default_index get $stripe_index for $dirname"
23324
23325         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23326                                                 error "create dirs failed"
23327
23328         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23329         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23330         for dir in $(find $DIR/$tdir/$dirname/*); do
23331                 stripe_count=$($LFS getdirstripe -c $dir)
23332                 (( $stripe_count == $default_count )) ||
23333                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23334                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23335                 error "stripe count $default_count != $stripe_count for $dir"
23336
23337                 stripe_index=$($LFS getdirstripe -i $dir)
23338                 [ $default_index -eq -1 ] ||
23339                         [ $stripe_index -eq $default_index ] ||
23340                         error "$stripe_index != $default_index for $dir"
23341
23342                 #check default stripe
23343                 stripe_count=$($LFS getdirstripe -D -c $dir)
23344                 [ $stripe_count -eq $default_count ] ||
23345                 error "default count $default_count != $stripe_count for $dir"
23346
23347                 stripe_index=$($LFS getdirstripe -D -i $dir)
23348                 [ $stripe_index -eq $default_index ] ||
23349                 error "default index $default_index != $stripe_index for $dir"
23350         done
23351         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23352 }
23353
23354 test_300g() {
23355         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23356         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23357                 skip "Need MDS version at least 2.7.55"
23358
23359         local dir
23360         local stripe_count
23361         local stripe_index
23362
23363         mkdir_on_mdt0 $DIR/$tdir
23364         mkdir $DIR/$tdir/normal_dir
23365
23366         #Checking when client cache stripe index
23367         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23368         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23369                 error "create striped_dir failed"
23370
23371         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23372                 error "create dir0 fails"
23373         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23374         [ $stripe_index -eq 0 ] ||
23375                 error "dir0 expect index 0 got $stripe_index"
23376
23377         mkdir $DIR/$tdir/striped_dir/dir1 ||
23378                 error "create dir1 fails"
23379         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23380         [ $stripe_index -eq 1 ] ||
23381                 error "dir1 expect index 1 got $stripe_index"
23382
23383         #check default stripe count/stripe index
23384         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23385         test_300_check_default_striped_dir normal_dir 1 0
23386         test_300_check_default_striped_dir normal_dir -1 1
23387         test_300_check_default_striped_dir normal_dir 2 -1
23388
23389         #delete default stripe information
23390         echo "delete default stripeEA"
23391         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23392                 error "set default stripe on striped dir error"
23393
23394         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23395         for dir in $(find $DIR/$tdir/normal_dir/*); do
23396                 stripe_count=$($LFS getdirstripe -c $dir)
23397                 [ $stripe_count -eq 0 ] ||
23398                         error "expect 1 get $stripe_count for $dir"
23399         done
23400 }
23401 run_test 300g "check default striped directory for normal directory"
23402
23403 test_300h() {
23404         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23405         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23406                 skip "Need MDS version at least 2.7.55"
23407
23408         local dir
23409         local stripe_count
23410
23411         mkdir $DIR/$tdir
23412         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23413                 error "set striped dir error"
23414
23415         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23416         test_300_check_default_striped_dir striped_dir 1 0
23417         test_300_check_default_striped_dir striped_dir -1 1
23418         test_300_check_default_striped_dir striped_dir 2 -1
23419
23420         #delete default stripe information
23421         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23422                 error "set default stripe on striped dir error"
23423
23424         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23425         for dir in $(find $DIR/$tdir/striped_dir/*); do
23426                 stripe_count=$($LFS getdirstripe -c $dir)
23427                 [ $stripe_count -eq 0 ] ||
23428                         error "expect 1 get $stripe_count for $dir"
23429         done
23430 }
23431 run_test 300h "check default striped directory for striped directory"
23432
23433 test_300i() {
23434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23435         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23436         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23437                 skip "Need MDS version at least 2.7.55"
23438
23439         local stripe_count
23440         local file
23441
23442         mkdir $DIR/$tdir
23443
23444         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23445                 error "set striped dir error"
23446
23447         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23448                 error "create files under striped dir failed"
23449
23450         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23451                 error "set striped hashdir error"
23452
23453         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23454                 error "create dir0 under hash dir failed"
23455         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23456                 error "create dir1 under hash dir failed"
23457         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23458                 error "create dir2 under hash dir failed"
23459
23460         # unfortunately, we need to umount to clear dir layout cache for now
23461         # once we fully implement dir layout, we can drop this
23462         umount_client $MOUNT || error "umount failed"
23463         mount_client $MOUNT || error "mount failed"
23464
23465         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23466         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23467         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23468
23469         #set the stripe to be unknown hash type
23470         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23471         $LCTL set_param fail_loc=0x1901
23472         for ((i = 0; i < 10; i++)); do
23473                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23474                         error "stat f-$i failed"
23475                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23476         done
23477
23478         touch $DIR/$tdir/striped_dir/f0 &&
23479                 error "create under striped dir with unknown hash should fail"
23480
23481         $LCTL set_param fail_loc=0
23482
23483         umount_client $MOUNT || error "umount failed"
23484         mount_client $MOUNT || error "mount failed"
23485
23486         return 0
23487 }
23488 run_test 300i "client handle unknown hash type striped directory"
23489
23490 test_300j() {
23491         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23493         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23494                 skip "Need MDS version at least 2.7.55"
23495
23496         local stripe_count
23497         local file
23498
23499         mkdir $DIR/$tdir
23500
23501         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23502         $LCTL set_param fail_loc=0x1702
23503         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23504                 error "set striped dir error"
23505
23506         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23507                 error "create files under striped dir failed"
23508
23509         $LCTL set_param fail_loc=0
23510
23511         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23512
23513         return 0
23514 }
23515 run_test 300j "test large update record"
23516
23517 test_300k() {
23518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23519         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23520         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23521                 skip "Need MDS version at least 2.7.55"
23522
23523         # this test needs a huge transaction
23524         local kb
23525         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23526              osd*.$FSNAME-MDT0000.kbytestotal")
23527         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23528
23529         local stripe_count
23530         local file
23531
23532         mkdir $DIR/$tdir
23533
23534         #define OBD_FAIL_LARGE_STRIPE   0x1703
23535         $LCTL set_param fail_loc=0x1703
23536         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23537                 error "set striped dir error"
23538         $LCTL set_param fail_loc=0
23539
23540         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23541                 error "getstripeddir fails"
23542         rm -rf $DIR/$tdir/striped_dir ||
23543                 error "unlink striped dir fails"
23544
23545         return 0
23546 }
23547 run_test 300k "test large striped directory"
23548
23549 test_300l() {
23550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23551         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23552         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23553                 skip "Need MDS version at least 2.7.55"
23554
23555         local stripe_index
23556
23557         test_mkdir -p $DIR/$tdir/striped_dir
23558         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23559                         error "chown $RUNAS_ID failed"
23560         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23561                 error "set default striped dir failed"
23562
23563         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23564         $LCTL set_param fail_loc=0x80000158
23565         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23566
23567         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23568         [ $stripe_index -eq 1 ] ||
23569                 error "expect 1 get $stripe_index for $dir"
23570 }
23571 run_test 300l "non-root user to create dir under striped dir with stale layout"
23572
23573 test_300m() {
23574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23575         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23576         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23577                 skip "Need MDS version at least 2.7.55"
23578
23579         mkdir -p $DIR/$tdir/striped_dir
23580         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23581                 error "set default stripes dir error"
23582
23583         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23584
23585         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23586         [ $stripe_count -eq 0 ] ||
23587                         error "expect 0 get $stripe_count for a"
23588
23589         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23590                 error "set default stripes dir error"
23591
23592         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23593
23594         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23595         [ $stripe_count -eq 0 ] ||
23596                         error "expect 0 get $stripe_count for b"
23597
23598         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23599                 error "set default stripes dir error"
23600
23601         mkdir $DIR/$tdir/striped_dir/c &&
23602                 error "default stripe_index is invalid, mkdir c should fails"
23603
23604         rm -rf $DIR/$tdir || error "rmdir fails"
23605 }
23606 run_test 300m "setstriped directory on single MDT FS"
23607
23608 cleanup_300n() {
23609         local list=$(comma_list $(mdts_nodes))
23610
23611         trap 0
23612         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23613 }
23614
23615 test_300n() {
23616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23617         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23618         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23619                 skip "Need MDS version at least 2.7.55"
23620         remote_mds_nodsh && skip "remote MDS with nodsh"
23621
23622         local stripe_index
23623         local list=$(comma_list $(mdts_nodes))
23624
23625         trap cleanup_300n RETURN EXIT
23626         mkdir -p $DIR/$tdir
23627         chmod 777 $DIR/$tdir
23628         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23629                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23630                 error "create striped dir succeeds with gid=0"
23631
23632         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23633         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23634                 error "create striped dir fails with gid=-1"
23635
23636         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23637         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23638                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23639                 error "set default striped dir succeeds with gid=0"
23640
23641
23642         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23643         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23644                 error "set default striped dir fails with gid=-1"
23645
23646
23647         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23648         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23649                                         error "create test_dir fails"
23650         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23651                                         error "create test_dir1 fails"
23652         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23653                                         error "create test_dir2 fails"
23654         cleanup_300n
23655 }
23656 run_test 300n "non-root user to create dir under striped dir with default EA"
23657
23658 test_300o() {
23659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23660         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23661         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23662                 skip "Need MDS version at least 2.7.55"
23663
23664         local numfree1
23665         local numfree2
23666
23667         mkdir -p $DIR/$tdir
23668
23669         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23670         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23671         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23672                 skip "not enough free inodes $numfree1 $numfree2"
23673         fi
23674
23675         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23676         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23677         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23678                 skip "not enough free space $numfree1 $numfree2"
23679         fi
23680
23681         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23682                 error "setdirstripe fails"
23683
23684         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23685                 error "create dirs fails"
23686
23687         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23688         ls $DIR/$tdir/striped_dir > /dev/null ||
23689                 error "ls striped dir fails"
23690         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23691                 error "unlink big striped dir fails"
23692 }
23693 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23694
23695 test_300p() {
23696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23697         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23698         remote_mds_nodsh && skip "remote MDS with nodsh"
23699
23700         mkdir_on_mdt0 $DIR/$tdir
23701
23702         #define OBD_FAIL_OUT_ENOSPC     0x1704
23703         do_facet mds2 lctl set_param fail_loc=0x80001704
23704         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23705                  && error "create striped directory should fail"
23706
23707         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23708
23709         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23710         true
23711 }
23712 run_test 300p "create striped directory without space"
23713
23714 test_300q() {
23715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23716         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23717
23718         local fd=$(free_fd)
23719         local cmd="exec $fd<$tdir"
23720         cd $DIR
23721         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23722         eval $cmd
23723         cmd="exec $fd<&-"
23724         trap "eval $cmd" EXIT
23725         cd $tdir || error "cd $tdir fails"
23726         rmdir  ../$tdir || error "rmdir $tdir fails"
23727         mkdir local_dir && error "create dir succeeds"
23728         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23729         eval $cmd
23730         return 0
23731 }
23732 run_test 300q "create remote directory under orphan directory"
23733
23734 test_300r() {
23735         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23736                 skip "Need MDS version at least 2.7.55" && return
23737         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23738
23739         mkdir $DIR/$tdir
23740
23741         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23742                 error "set striped dir error"
23743
23744         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23745                 error "getstripeddir fails"
23746
23747         local stripe_count
23748         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23749                       awk '/lmv_stripe_count:/ { print $2 }')
23750
23751         [ $MDSCOUNT -ne $stripe_count ] &&
23752                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23753
23754         rm -rf $DIR/$tdir/striped_dir ||
23755                 error "unlink striped dir fails"
23756 }
23757 run_test 300r "test -1 striped directory"
23758
23759 test_300s_helper() {
23760         local count=$1
23761
23762         local stripe_dir=$DIR/$tdir/striped_dir.$count
23763
23764         $LFS mkdir -c $count $stripe_dir ||
23765                 error "lfs mkdir -c error"
23766
23767         $LFS getdirstripe $stripe_dir ||
23768                 error "lfs getdirstripe fails"
23769
23770         local stripe_count
23771         stripe_count=$($LFS getdirstripe $stripe_dir |
23772                       awk '/lmv_stripe_count:/ { print $2 }')
23773
23774         [ $count -ne $stripe_count ] &&
23775                 error_noexit "bad stripe count $stripe_count expected $count"
23776
23777         local dupe_stripes
23778         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23779                 awk '/0x/ {count[$1] += 1}; END {
23780                         for (idx in count) {
23781                                 if (count[idx]>1) {
23782                                         print "index " idx " count " count[idx]
23783                                 }
23784                         }
23785                 }')
23786
23787         if [[ -n "$dupe_stripes" ]] ; then
23788                 lfs getdirstripe $stripe_dir
23789                 error_noexit "Dupe MDT above: $dupe_stripes "
23790         fi
23791
23792         rm -rf $stripe_dir ||
23793                 error_noexit "unlink $stripe_dir fails"
23794 }
23795
23796 test_300s() {
23797         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23798                 skip "Need MDS version at least 2.7.55" && return
23799         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23800
23801         mkdir $DIR/$tdir
23802         for count in $(seq 2 $MDSCOUNT); do
23803                 test_300s_helper $count
23804         done
23805 }
23806 run_test 300s "test lfs mkdir -c without -i"
23807
23808 test_300t() {
23809         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
23810                 skip "need MDS 2.14.55 or later"
23811         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
23812
23813         local testdir="$DIR/$tdir/striped_dir"
23814         local dir1=$testdir/dir1
23815         local dir2=$testdir/dir2
23816
23817         mkdir -p $testdir
23818
23819         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
23820                 error "failed to set default stripe count for $testdir"
23821
23822         mkdir $dir1
23823         local stripe_count=$($LFS getdirstripe -c $dir1)
23824
23825         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
23826
23827         local max_count=$((MDSCOUNT - 1))
23828         local mdts=$(comma_list $(mdts_nodes))
23829
23830         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
23831         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
23832
23833         mkdir $dir2
23834         stripe_count=$($LFS getdirstripe -c $dir2)
23835
23836         (( $stripe_count == $max_count )) || error "wrong stripe count"
23837 }
23838 run_test 300t "test max_mdt_stripecount"
23839
23840 prepare_remote_file() {
23841         mkdir $DIR/$tdir/src_dir ||
23842                 error "create remote source failed"
23843
23844         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23845                  error "cp to remote source failed"
23846         touch $DIR/$tdir/src_dir/a
23847
23848         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23849                 error "create remote target dir failed"
23850
23851         touch $DIR/$tdir/tgt_dir/b
23852
23853         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23854                 error "rename dir cross MDT failed!"
23855
23856         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23857                 error "src_child still exists after rename"
23858
23859         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23860                 error "missing file(a) after rename"
23861
23862         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23863                 error "diff after rename"
23864 }
23865
23866 test_310a() {
23867         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23869
23870         local remote_file=$DIR/$tdir/tgt_dir/b
23871
23872         mkdir -p $DIR/$tdir
23873
23874         prepare_remote_file || error "prepare remote file failed"
23875
23876         #open-unlink file
23877         $OPENUNLINK $remote_file $remote_file ||
23878                 error "openunlink $remote_file failed"
23879         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23880 }
23881 run_test 310a "open unlink remote file"
23882
23883 test_310b() {
23884         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
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 $DIR/$tfile Ouc || error "mulitop failed"
23895         $CHECKSTAT -t file $remote_file || error "check file failed"
23896 }
23897 run_test 310b "unlink remote file with multiple links while open"
23898
23899 test_310c() {
23900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23901         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23902
23903         local remote_file=$DIR/$tdir/tgt_dir/b
23904
23905         mkdir -p $DIR/$tdir
23906
23907         prepare_remote_file || error "prepare remote file failed"
23908
23909         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23910         multiop_bg_pause $remote_file O_uc ||
23911                         error "mulitop failed for remote file"
23912         MULTIPID=$!
23913         $MULTIOP $DIR/$tfile Ouc
23914         kill -USR1 $MULTIPID
23915         wait $MULTIPID
23916 }
23917 run_test 310c "open-unlink remote file with multiple links"
23918
23919 #LU-4825
23920 test_311() {
23921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23922         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23923         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23924                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23925         remote_mds_nodsh && skip "remote MDS with nodsh"
23926
23927         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23928         local mdts=$(comma_list $(mdts_nodes))
23929
23930         mkdir -p $DIR/$tdir
23931         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23932         createmany -o $DIR/$tdir/$tfile. 1000
23933
23934         # statfs data is not real time, let's just calculate it
23935         old_iused=$((old_iused + 1000))
23936
23937         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23938                         osp.*OST0000*MDT0000.create_count")
23939         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23940                                 osp.*OST0000*MDT0000.max_create_count")
23941         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23942
23943         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23944         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23945         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23946
23947         unlinkmany $DIR/$tdir/$tfile. 1000
23948
23949         do_nodes $mdts "$LCTL set_param -n \
23950                         osp.*OST0000*.max_create_count=$max_count"
23951         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23952                 do_nodes $mdts "$LCTL set_param -n \
23953                                 osp.*OST0000*.create_count=$count"
23954         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23955                         grep "=0" && error "create_count is zero"
23956
23957         local new_iused
23958         for i in $(seq 120); do
23959                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23960                 # system may be too busy to destroy all objs in time, use
23961                 # a somewhat small value to not fail autotest
23962                 [ $((old_iused - new_iused)) -gt 400 ] && break
23963                 sleep 1
23964         done
23965
23966         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23967         [ $((old_iused - new_iused)) -gt 400 ] ||
23968                 error "objs not destroyed after unlink"
23969 }
23970 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23971
23972 zfs_oid_to_objid()
23973 {
23974         local ost=$1
23975         local objid=$2
23976
23977         local vdevdir=$(dirname $(facet_vdevice $ost))
23978         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23979         local zfs_zapid=$(do_facet $ost $cmd |
23980                           grep -w "/O/0/d$((objid%32))" -C 5 |
23981                           awk '/Object/{getline; print $1}')
23982         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23983                           awk "/$objid = /"'{printf $3}')
23984
23985         echo $zfs_objid
23986 }
23987
23988 zfs_object_blksz() {
23989         local ost=$1
23990         local objid=$2
23991
23992         local vdevdir=$(dirname $(facet_vdevice $ost))
23993         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23994         local blksz=$(do_facet $ost $cmd $objid |
23995                       awk '/dblk/{getline; printf $4}')
23996
23997         case "${blksz: -1}" in
23998                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23999                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24000                 *) ;;
24001         esac
24002
24003         echo $blksz
24004 }
24005
24006 test_312() { # LU-4856
24007         remote_ost_nodsh && skip "remote OST with nodsh"
24008         [ "$ost1_FSTYPE" = "zfs" ] ||
24009                 skip_env "the test only applies to zfs"
24010
24011         local max_blksz=$(do_facet ost1 \
24012                           $ZFS get -p recordsize $(facet_device ost1) |
24013                           awk '!/VALUE/{print $3}')
24014
24015         # to make life a little bit easier
24016         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24017         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24018
24019         local tf=$DIR/$tdir/$tfile
24020         touch $tf
24021         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24022
24023         # Get ZFS object id
24024         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24025         # block size change by sequential overwrite
24026         local bs
24027
24028         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24029                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24030
24031                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24032                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24033         done
24034         rm -f $tf
24035
24036         # block size change by sequential append write
24037         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24038         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24039         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24040         local count
24041
24042         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24043                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24044                         oflag=sync conv=notrunc
24045
24046                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24047                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24048                         error "blksz error, actual $blksz, " \
24049                                 "expected: 2 * $count * $PAGE_SIZE"
24050         done
24051         rm -f $tf
24052
24053         # random write
24054         touch $tf
24055         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24056         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24057
24058         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24059         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24060         [ $blksz -eq $PAGE_SIZE ] ||
24061                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24062
24063         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24064         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24065         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24066
24067         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24068         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24069         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24070 }
24071 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24072
24073 test_313() {
24074         remote_ost_nodsh && skip "remote OST with nodsh"
24075
24076         local file=$DIR/$tfile
24077
24078         rm -f $file
24079         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24080
24081         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24082         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24083         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24084                 error "write should failed"
24085         do_facet ost1 "$LCTL set_param fail_loc=0"
24086         rm -f $file
24087 }
24088 run_test 313 "io should fail after last_rcvd update fail"
24089
24090 test_314() {
24091         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24092
24093         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24094         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24095         rm -f $DIR/$tfile
24096         wait_delete_completed
24097         do_facet ost1 "$LCTL set_param fail_loc=0"
24098 }
24099 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24100
24101 test_315() { # LU-618
24102         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24103
24104         local file=$DIR/$tfile
24105         rm -f $file
24106
24107         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24108                 error "multiop file write failed"
24109         $MULTIOP $file oO_RDONLY:r4063232_c &
24110         PID=$!
24111
24112         sleep 2
24113
24114         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24115         kill -USR1 $PID
24116
24117         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24118         rm -f $file
24119 }
24120 run_test 315 "read should be accounted"
24121
24122 test_316() {
24123         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24124         large_xattr_enabled || skip_env "ea_inode feature disabled"
24125
24126         rm -rf $DIR/$tdir/d
24127         mkdir -p $DIR/$tdir/d
24128         chown nobody $DIR/$tdir/d
24129         touch $DIR/$tdir/d/file
24130
24131         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
24132 }
24133 run_test 316 "lfs mv"
24134
24135 test_317() {
24136         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24137                 skip "Need MDS version at least 2.11.53"
24138         if [ "$ost1_FSTYPE" == "zfs" ]; then
24139                 skip "LU-10370: no implementation for ZFS"
24140         fi
24141
24142         local trunc_sz
24143         local grant_blk_size
24144
24145         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24146                         awk '/grant_block_size:/ { print $2; exit; }')
24147         #
24148         # Create File of size 5M. Truncate it to below size's and verify
24149         # blocks count.
24150         #
24151         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24152                 error "Create file $DIR/$tfile failed"
24153         stack_trap "rm -f $DIR/$tfile" EXIT
24154
24155         for trunc_sz in 2097152 4097 4000 509 0; do
24156                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24157                         error "truncate $tfile to $trunc_sz failed"
24158                 local sz=$(stat --format=%s $DIR/$tfile)
24159                 local blk=$(stat --format=%b $DIR/$tfile)
24160                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24161                                      grant_blk_size) * 8))
24162
24163                 if [[ $blk -ne $trunc_blk ]]; then
24164                         $(which stat) $DIR/$tfile
24165                         error "Expected Block $trunc_blk got $blk for $tfile"
24166                 fi
24167
24168                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24169                         error "Expected Size $trunc_sz got $sz for $tfile"
24170         done
24171
24172         #
24173         # sparse file test
24174         # Create file with a hole and write actual 65536 bytes which aligned
24175         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24176         #
24177         local bs=65536
24178         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24179                 error "Create file : $DIR/$tfile"
24180
24181         #
24182         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24183         # blocks. The block count must drop to 8.
24184         #
24185         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - \
24186                 ((bs - grant_blk_size) + 1)))
24187         $TRUNCATE $DIR/$tfile $trunc_sz ||
24188                 error "truncate $tfile to $trunc_sz failed"
24189
24190         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24191         sz=$(stat --format=%s $DIR/$tfile)
24192         blk=$(stat --format=%b $DIR/$tfile)
24193
24194         if [[ $blk -ne $trunc_bsz ]]; then
24195                 $(which stat) $DIR/$tfile
24196                 error "Expected Block $trunc_bsz got $blk for $tfile"
24197         fi
24198
24199         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24200                 error "Expected Size $trunc_sz got $sz for $tfile"
24201 }
24202 run_test 317 "Verify blocks get correctly update after truncate"
24203
24204 test_318() {
24205         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24206         local old_max_active=$($LCTL get_param -n \
24207                             ${llite_name}.max_read_ahead_async_active \
24208                             2>/dev/null)
24209
24210         $LCTL set_param llite.*.max_read_ahead_async_active=256
24211         local max_active=$($LCTL get_param -n \
24212                            ${llite_name}.max_read_ahead_async_active \
24213                            2>/dev/null)
24214         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24215
24216         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24217                 error "set max_read_ahead_async_active should succeed"
24218
24219         $LCTL set_param llite.*.max_read_ahead_async_active=512
24220         max_active=$($LCTL get_param -n \
24221                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24222         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24223
24224         # restore @max_active
24225         [ $old_max_active -ne 0 ] && $LCTL set_param \
24226                 llite.*.max_read_ahead_async_active=$old_max_active
24227
24228         local old_threshold=$($LCTL get_param -n \
24229                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24230         local max_per_file_mb=$($LCTL get_param -n \
24231                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24232
24233         local invalid=$(($max_per_file_mb + 1))
24234         $LCTL set_param \
24235                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24236                         && error "set $invalid should fail"
24237
24238         local valid=$(($invalid - 1))
24239         $LCTL set_param \
24240                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24241                         error "set $valid should succeed"
24242         local threshold=$($LCTL get_param -n \
24243                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24244         [ $threshold -eq $valid ] || error \
24245                 "expect threshold $valid got $threshold"
24246         $LCTL set_param \
24247                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24248 }
24249 run_test 318 "Verify async readahead tunables"
24250
24251 test_319() {
24252         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
24253
24254         local before=$(date +%s)
24255         local evict
24256         local mdir=$DIR/$tdir
24257         local file=$mdir/xxx
24258
24259         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24260         touch $file
24261
24262 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24263         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24264         $LFS mv -m1 $file &
24265
24266         sleep 1
24267         dd if=$file of=/dev/null
24268         wait
24269         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24270           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24271
24272         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24273 }
24274 run_test 319 "lost lease lock on migrate error"
24275
24276 test_398a() { # LU-4198
24277         local ost1_imp=$(get_osc_import_name client ost1)
24278         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24279                          cut -d'.' -f2)
24280
24281         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24282         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24283
24284         # request a new lock on client
24285         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24286
24287         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24288         local lock_count=$($LCTL get_param -n \
24289                            ldlm.namespaces.$imp_name.lru_size)
24290         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24291
24292         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24293
24294         # no lock cached, should use lockless IO and not enqueue new lock
24295         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24296         lock_count=$($LCTL get_param -n \
24297                      ldlm.namespaces.$imp_name.lru_size)
24298         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24299 }
24300 run_test 398a "direct IO should cancel lock otherwise lockless"
24301
24302 test_398b() { # LU-4198
24303         which fio || skip_env "no fio installed"
24304         $LFS setstripe -c -1 $DIR/$tfile
24305
24306         local size=12
24307         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24308
24309         local njobs=4
24310         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
24311         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24312                 --numjobs=$njobs --fallocate=none \
24313                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24314                 --filename=$DIR/$tfile &
24315         bg_pid=$!
24316
24317         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
24318         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
24319                 --numjobs=$njobs --fallocate=none \
24320                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24321                 --filename=$DIR/$tfile || true
24322         wait $bg_pid
24323
24324         rm -f $DIR/$tfile
24325 }
24326 run_test 398b "DIO and buffer IO race"
24327
24328 test_398c() { # LU-4198
24329         local ost1_imp=$(get_osc_import_name client ost1)
24330         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24331                          cut -d'.' -f2)
24332
24333         which fio || skip_env "no fio installed"
24334
24335         saved_debug=$($LCTL get_param -n debug)
24336         $LCTL set_param debug=0
24337
24338         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24339         ((size /= 1024)) # by megabytes
24340         ((size /= 2)) # write half of the OST at most
24341         [ $size -gt 40 ] && size=40 #reduce test time anyway
24342
24343         $LFS setstripe -c 1 $DIR/$tfile
24344
24345         # it seems like ldiskfs reserves more space than necessary if the
24346         # writing blocks are not mapped, so it extends the file firstly
24347         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24348         cancel_lru_locks osc
24349
24350         # clear and verify rpc_stats later
24351         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24352
24353         local njobs=4
24354         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24355         fio --name=rand-write --rw=randwrite --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 write error"
24360
24361         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24362                 error "Locks were requested while doing AIO"
24363
24364         # get the percentage of 1-page I/O
24365         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24366                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24367                 awk '{print $7}')
24368         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24369
24370         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24371         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24372                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24373                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24374                 --filename=$DIR/$tfile
24375         [ $? -eq 0 ] || error "fio mixed read write error"
24376
24377         echo "AIO with large block size ${size}M"
24378         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24379                 --numjobs=1 --fallocate=none --ioengine=libaio \
24380                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24381                 --filename=$DIR/$tfile
24382         [ $? -eq 0 ] || error "fio large block size failed"
24383
24384         rm -f $DIR/$tfile
24385         $LCTL set_param debug="$saved_debug"
24386 }
24387 run_test 398c "run fio to test AIO"
24388
24389 test_398d() { #  LU-13846
24390         which aiocp || skip_env "no aiocp installed"
24391         local aio_file=$DIR/$tfile.aio
24392
24393         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24394
24395         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24396         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24397         stack_trap "rm -f $DIR/$tfile $aio_file"
24398
24399         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24400
24401         # make sure we don't crash and fail properly
24402         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24403                 error "aio not aligned with PAGE SIZE should fail"
24404
24405         rm -f $DIR/$tfile $aio_file
24406 }
24407 run_test 398d "run aiocp to verify block size > stripe size"
24408
24409 test_398e() {
24410         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24411         touch $DIR/$tfile.new
24412         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24413 }
24414 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24415
24416 test_398f() { #  LU-14687
24417         which aiocp || skip_env "no aiocp installed"
24418         local aio_file=$DIR/$tfile.aio
24419
24420         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24421
24422         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24423         stack_trap "rm -f $DIR/$tfile $aio_file"
24424
24425         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24426         $LCTL set_param fail_loc=0x1418
24427         # make sure we don't crash and fail properly
24428         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24429                 error "aio with page allocation failure succeeded"
24430         $LCTL set_param fail_loc=0
24431         diff $DIR/$tfile $aio_file
24432         [[ $? != 0 ]] || error "no diff after failed aiocp"
24433 }
24434 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24435
24436 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24437 # stripe and i/o size must be > stripe size
24438 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24439 # single RPC in flight.  This test shows async DIO submission is working by
24440 # showing multiple RPCs in flight.
24441 test_398g() { #  LU-13798
24442         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24443
24444         # We need to do some i/o first to acquire enough grant to put our RPCs
24445         # in flight; otherwise a new connection may not have enough grant
24446         # available
24447         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24448                 error "parallel dio failed"
24449         stack_trap "rm -f $DIR/$tfile"
24450
24451         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24452         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24453         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24454         stack_trap "$LCTL set_param -n $pages_per_rpc"
24455
24456         # Recreate file so it's empty
24457         rm -f $DIR/$tfile
24458         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24459         #Pause rpc completion to guarantee we see multiple rpcs in flight
24460         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24461         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24462         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24463
24464         # Clear rpc stats
24465         $LCTL set_param osc.*.rpc_stats=c
24466
24467         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24468                 error "parallel dio failed"
24469         stack_trap "rm -f $DIR/$tfile"
24470
24471         $LCTL get_param osc.*-OST0000-*.rpc_stats
24472         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24473                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24474                 grep "8:" | awk '{print $8}')
24475         # We look at the "8 rpcs in flight" field, and verify A) it is present
24476         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24477         # as expected for an 8M DIO to a file with 1M stripes.
24478         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24479
24480         # Verify turning off parallel dio works as expected
24481         # Clear rpc stats
24482         $LCTL set_param osc.*.rpc_stats=c
24483         $LCTL set_param llite.*.parallel_dio=0
24484         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24485
24486         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24487                 error "dio with parallel dio disabled failed"
24488
24489         # Ideally, we would see only one RPC in flight here, but there is an
24490         # unavoidable race between i/o completion and RPC in flight counting,
24491         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24492         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24493         # So instead we just verify it's always < 8.
24494         $LCTL get_param osc.*-OST0000-*.rpc_stats
24495         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24496                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24497                 grep '^$' -B1 | grep . | awk '{print $1}')
24498         [ $ret != "8:" ] ||
24499                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24500 }
24501 run_test 398g "verify parallel dio async RPC submission"
24502
24503 test_398h() { #  LU-13798
24504         local dio_file=$DIR/$tfile.dio
24505
24506         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24507
24508         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24509         stack_trap "rm -f $DIR/$tfile $dio_file"
24510
24511         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24512                 error "parallel dio failed"
24513         diff $DIR/$tfile $dio_file
24514         [[ $? == 0 ]] || error "file diff after aiocp"
24515 }
24516 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24517
24518 test_398i() { #  LU-13798
24519         local dio_file=$DIR/$tfile.dio
24520
24521         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24522
24523         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24524         stack_trap "rm -f $DIR/$tfile $dio_file"
24525
24526         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24527         $LCTL set_param fail_loc=0x1418
24528         # make sure we don't crash and fail properly
24529         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24530                 error "parallel dio page allocation failure succeeded"
24531         diff $DIR/$tfile $dio_file
24532         [[ $? != 0 ]] || error "no diff after failed aiocp"
24533 }
24534 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24535
24536 test_398j() { #  LU-13798
24537         # Stripe size > RPC size but less than i/o size tests split across
24538         # stripes and RPCs for individual i/o op
24539         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24540
24541         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24542         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24543         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24544         stack_trap "$LCTL set_param -n $pages_per_rpc"
24545
24546         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24547                 error "parallel dio write failed"
24548         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24549
24550         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24551                 error "parallel dio read failed"
24552         diff $DIR/$tfile $DIR/$tfile.2
24553         [[ $? == 0 ]] || error "file diff after parallel dio read"
24554 }
24555 run_test 398j "test parallel dio where stripe size > rpc_size"
24556
24557 test_398k() { #  LU-13798
24558         wait_delete_completed
24559         wait_mds_ost_sync
24560
24561         # 4 stripe file; we will cause out of space on OST0
24562         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24563
24564         # Fill OST0 (if it's not too large)
24565         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24566                    head -n1)
24567         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24568                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24569         fi
24570         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24571         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24572                 error "dd should fill OST0"
24573         stack_trap "rm -f $DIR/$tfile.1"
24574
24575         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24576         err=$?
24577
24578         ls -la $DIR/$tfile
24579         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24580                 error "file is not 0 bytes in size"
24581
24582         # dd above should not succeed, but don't error until here so we can
24583         # get debug info above
24584         [[ $err != 0 ]] ||
24585                 error "parallel dio write with enospc succeeded"
24586         stack_trap "rm -f $DIR/$tfile"
24587 }
24588 run_test 398k "test enospc on first stripe"
24589
24590 test_398l() { #  LU-13798
24591         wait_delete_completed
24592         wait_mds_ost_sync
24593
24594         # 4 stripe file; we will cause out of space on OST0
24595         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24596         # happens on the second i/o chunk we issue
24597         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24598
24599         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24600         stack_trap "rm -f $DIR/$tfile"
24601
24602         # Fill OST0 (if it's not too large)
24603         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24604                    head -n1)
24605         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24606                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24607         fi
24608         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24609         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24610                 error "dd should fill OST0"
24611         stack_trap "rm -f $DIR/$tfile.1"
24612
24613         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24614         err=$?
24615         stack_trap "rm -f $DIR/$tfile.2"
24616
24617         # Check that short write completed as expected
24618         ls -la $DIR/$tfile.2
24619         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24620                 error "file is not 1M in size"
24621
24622         # dd above should not succeed, but don't error until here so we can
24623         # get debug info above
24624         [[ $err != 0 ]] ||
24625                 error "parallel dio write with enospc succeeded"
24626
24627         # Truncate source file to same length as output file and diff them
24628         $TRUNCATE $DIR/$tfile 1048576
24629         diff $DIR/$tfile $DIR/$tfile.2
24630         [[ $? == 0 ]] || error "data incorrect after short write"
24631 }
24632 run_test 398l "test enospc on intermediate stripe/RPC"
24633
24634 test_398m() { #  LU-13798
24635         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24636
24637         # Set up failure on OST0, the first stripe:
24638         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24639         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24640         # So this fail_val specifies OST0
24641         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24642         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24643
24644         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24645                 error "parallel dio write with failure on first stripe succeeded"
24646         stack_trap "rm -f $DIR/$tfile"
24647         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24648
24649         # Place data in file for read
24650         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24651                 error "parallel dio write failed"
24652
24653         # Fail read on OST0, first stripe
24654         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24655         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24656         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24657                 error "parallel dio read with error on first stripe succeeded"
24658         rm -f $DIR/$tfile.2
24659         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24660
24661         # Switch to testing on OST1, second stripe
24662         # Clear file contents, maintain striping
24663         echo > $DIR/$tfile
24664         # Set up failure on OST1, second stripe:
24665         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24666         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24667
24668         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24669                 error "parallel dio write with failure on first stripe succeeded"
24670         stack_trap "rm -f $DIR/$tfile"
24671         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24672
24673         # Place data in file for read
24674         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24675                 error "parallel dio write failed"
24676
24677         # Fail read on OST1, second stripe
24678         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24679         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24680         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24681                 error "parallel dio read with error on first stripe succeeded"
24682         rm -f $DIR/$tfile.2
24683         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24684 }
24685 run_test 398m "test RPC failures with parallel dio"
24686
24687 # Parallel submission of DIO should not cause problems for append, but it's
24688 # important to verify.
24689 test_398n() { #  LU-13798
24690         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24691
24692         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24693                 error "dd to create source file failed"
24694         stack_trap "rm -f $DIR/$tfile"
24695
24696         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24697                 error "parallel dio write with failure on second stripe succeeded"
24698         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24699         diff $DIR/$tfile $DIR/$tfile.1
24700         [[ $? == 0 ]] || error "data incorrect after append"
24701
24702 }
24703 run_test 398n "test append with parallel DIO"
24704
24705 test_fake_rw() {
24706         local read_write=$1
24707         if [ "$read_write" = "write" ]; then
24708                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24709         elif [ "$read_write" = "read" ]; then
24710                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24711         else
24712                 error "argument error"
24713         fi
24714
24715         # turn off debug for performance testing
24716         local saved_debug=$($LCTL get_param -n debug)
24717         $LCTL set_param debug=0
24718
24719         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24720
24721         # get ost1 size - $FSNAME-OST0000
24722         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24723         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24724         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24725
24726         if [ "$read_write" = "read" ]; then
24727                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24728         fi
24729
24730         local start_time=$(date +%s.%N)
24731         $dd_cmd bs=1M count=$blocks oflag=sync ||
24732                 error "real dd $read_write error"
24733         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24734
24735         if [ "$read_write" = "write" ]; then
24736                 rm -f $DIR/$tfile
24737         fi
24738
24739         # define OBD_FAIL_OST_FAKE_RW           0x238
24740         do_facet ost1 $LCTL set_param fail_loc=0x238
24741
24742         local start_time=$(date +%s.%N)
24743         $dd_cmd bs=1M count=$blocks oflag=sync ||
24744                 error "fake dd $read_write error"
24745         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24746
24747         if [ "$read_write" = "write" ]; then
24748                 # verify file size
24749                 cancel_lru_locks osc
24750                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24751                         error "$tfile size not $blocks MB"
24752         fi
24753         do_facet ost1 $LCTL set_param fail_loc=0
24754
24755         echo "fake $read_write $duration_fake vs. normal $read_write" \
24756                 "$duration in seconds"
24757         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24758                 error_not_in_vm "fake write is slower"
24759
24760         $LCTL set_param -n debug="$saved_debug"
24761         rm -f $DIR/$tfile
24762 }
24763 test_399a() { # LU-7655 for OST fake write
24764         remote_ost_nodsh && skip "remote OST with nodsh"
24765
24766         test_fake_rw write
24767 }
24768 run_test 399a "fake write should not be slower than normal write"
24769
24770 test_399b() { # LU-8726 for OST fake read
24771         remote_ost_nodsh && skip "remote OST with nodsh"
24772         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24773                 skip_env "ldiskfs only test"
24774         fi
24775
24776         test_fake_rw read
24777 }
24778 run_test 399b "fake read should not be slower than normal read"
24779
24780 test_400a() { # LU-1606, was conf-sanity test_74
24781         if ! which $CC > /dev/null 2>&1; then
24782                 skip_env "$CC is not installed"
24783         fi
24784
24785         local extra_flags=''
24786         local out=$TMP/$tfile
24787         local prefix=/usr/include/lustre
24788         local prog
24789
24790         # Oleg removes c files in his test rig so test if any c files exist
24791         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24792                 skip_env "Needed c test files are missing"
24793
24794         if ! [[ -d $prefix ]]; then
24795                 # Assume we're running in tree and fixup the include path.
24796                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24797                 extra_flags+=" -L$LUSTRE/utils/.lib"
24798         fi
24799
24800         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24801                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24802                         error "client api broken"
24803         done
24804         rm -f $out
24805 }
24806 run_test 400a "Lustre client api program can compile and link"
24807
24808 test_400b() { # LU-1606, LU-5011
24809         local header
24810         local out=$TMP/$tfile
24811         local prefix=/usr/include/linux/lustre
24812
24813         # We use a hard coded prefix so that this test will not fail
24814         # when run in tree. There are headers in lustre/include/lustre/
24815         # that are not packaged (like lustre_idl.h) and have more
24816         # complicated include dependencies (like config.h and lnet/types.h).
24817         # Since this test about correct packaging we just skip them when
24818         # they don't exist (see below) rather than try to fixup cppflags.
24819
24820         if ! which $CC > /dev/null 2>&1; then
24821                 skip_env "$CC is not installed"
24822         fi
24823
24824         for header in $prefix/*.h; do
24825                 if ! [[ -f "$header" ]]; then
24826                         continue
24827                 fi
24828
24829                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24830                         continue # lustre_ioctl.h is internal header
24831                 fi
24832
24833                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24834                         error "cannot compile '$header'"
24835         done
24836         rm -f $out
24837 }
24838 run_test 400b "packaged headers can be compiled"
24839
24840 test_401a() { #LU-7437
24841         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24842         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24843
24844         #count the number of parameters by "list_param -R"
24845         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24846         #count the number of parameters by listing proc files
24847         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24848         echo "proc_dirs='$proc_dirs'"
24849         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24850         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24851                       sort -u | wc -l)
24852
24853         [ $params -eq $procs ] ||
24854                 error "found $params parameters vs. $procs proc files"
24855
24856         # test the list_param -D option only returns directories
24857         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24858         #count the number of parameters by listing proc directories
24859         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24860                 sort -u | wc -l)
24861
24862         [ $params -eq $procs ] ||
24863                 error "found $params parameters vs. $procs proc files"
24864 }
24865 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24866
24867 test_401b() {
24868         # jobid_var may not allow arbitrary values, so use jobid_name
24869         # if available
24870         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24871                 local testname=jobid_name tmp='testing%p'
24872         else
24873                 local testname=jobid_var tmp=testing
24874         fi
24875
24876         local save=$($LCTL get_param -n $testname)
24877
24878         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24879                 error "no error returned when setting bad parameters"
24880
24881         local jobid_new=$($LCTL get_param -n foe $testname baz)
24882         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24883
24884         $LCTL set_param -n fog=bam $testname=$save bat=fog
24885         local jobid_old=$($LCTL get_param -n foe $testname bag)
24886         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24887 }
24888 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24889
24890 test_401c() {
24891         # jobid_var may not allow arbitrary values, so use jobid_name
24892         # if available
24893         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24894                 local testname=jobid_name
24895         else
24896                 local testname=jobid_var
24897         fi
24898
24899         local jobid_var_old=$($LCTL get_param -n $testname)
24900         local jobid_var_new
24901
24902         $LCTL set_param $testname= &&
24903                 error "no error returned for 'set_param a='"
24904
24905         jobid_var_new=$($LCTL get_param -n $testname)
24906         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24907                 error "$testname was changed by setting without value"
24908
24909         $LCTL set_param $testname &&
24910                 error "no error returned for 'set_param a'"
24911
24912         jobid_var_new=$($LCTL get_param -n $testname)
24913         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24914                 error "$testname was changed by setting without value"
24915 }
24916 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24917
24918 test_401d() {
24919         # jobid_var may not allow arbitrary values, so use jobid_name
24920         # if available
24921         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24922                 local testname=jobid_name new_value='foo=bar%p'
24923         else
24924                 local testname=jobid_var new_valuie=foo=bar
24925         fi
24926
24927         local jobid_var_old=$($LCTL get_param -n $testname)
24928         local jobid_var_new
24929
24930         $LCTL set_param $testname=$new_value ||
24931                 error "'set_param a=b' did not accept a value containing '='"
24932
24933         jobid_var_new=$($LCTL get_param -n $testname)
24934         [[ "$jobid_var_new" == "$new_value" ]] ||
24935                 error "'set_param a=b' failed on a value containing '='"
24936
24937         # Reset the $testname to test the other format
24938         $LCTL set_param $testname=$jobid_var_old
24939         jobid_var_new=$($LCTL get_param -n $testname)
24940         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24941                 error "failed to reset $testname"
24942
24943         $LCTL set_param $testname $new_value ||
24944                 error "'set_param a b' did not accept a value containing '='"
24945
24946         jobid_var_new=$($LCTL get_param -n $testname)
24947         [[ "$jobid_var_new" == "$new_value" ]] ||
24948                 error "'set_param a b' failed on a value containing '='"
24949
24950         $LCTL set_param $testname $jobid_var_old
24951         jobid_var_new=$($LCTL get_param -n $testname)
24952         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24953                 error "failed to reset $testname"
24954 }
24955 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24956
24957 test_401e() { # LU-14779
24958         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24959                 error "lctl list_param MGC* failed"
24960         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24961         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24962                 error "lctl get_param lru_size failed"
24963 }
24964 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24965
24966 test_402() {
24967         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24968         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24969                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24970         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24971                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24972                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24973         remote_mds_nodsh && skip "remote MDS with nodsh"
24974
24975         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24976 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24977         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24978         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24979                 echo "Touch failed - OK"
24980 }
24981 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24982
24983 test_403() {
24984         local file1=$DIR/$tfile.1
24985         local file2=$DIR/$tfile.2
24986         local tfile=$TMP/$tfile
24987
24988         rm -f $file1 $file2 $tfile
24989
24990         touch $file1
24991         ln $file1 $file2
24992
24993         # 30 sec OBD_TIMEOUT in ll_getattr()
24994         # right before populating st_nlink
24995         $LCTL set_param fail_loc=0x80001409
24996         stat -c %h $file1 > $tfile &
24997
24998         # create an alias, drop all locks and reclaim the dentry
24999         < $file2
25000         cancel_lru_locks mdc
25001         cancel_lru_locks osc
25002         sysctl -w vm.drop_caches=2
25003
25004         wait
25005
25006         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25007
25008         rm -f $tfile $file1 $file2
25009 }
25010 run_test 403 "i_nlink should not drop to zero due to aliasing"
25011
25012 test_404() { # LU-6601
25013         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25014                 skip "Need server version newer than 2.8.52"
25015         remote_mds_nodsh && skip "remote MDS with nodsh"
25016
25017         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25018                 awk '/osp .*-osc-MDT/ { print $4}')
25019
25020         local osp
25021         for osp in $mosps; do
25022                 echo "Deactivate: " $osp
25023                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25024                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25025                         awk -vp=$osp '$4 == p { print $2 }')
25026                 [ $stat = IN ] || {
25027                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25028                         error "deactivate error"
25029                 }
25030                 echo "Activate: " $osp
25031                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25032                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25033                         awk -vp=$osp '$4 == p { print $2 }')
25034                 [ $stat = UP ] || {
25035                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25036                         error "activate error"
25037                 }
25038         done
25039 }
25040 run_test 404 "validate manual {de}activated works properly for OSPs"
25041
25042 test_405() {
25043         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25044         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25045                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25046                         skip "Layout swap lock is not supported"
25047
25048         check_swap_layouts_support
25049         check_swap_layout_no_dom $DIR
25050
25051         test_mkdir $DIR/$tdir
25052         swap_lock_test -d $DIR/$tdir ||
25053                 error "One layout swap locked test failed"
25054 }
25055 run_test 405 "Various layout swap lock tests"
25056
25057 test_406() {
25058         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25059         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25060         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25062         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25063                 skip "Need MDS version at least 2.8.50"
25064
25065         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25066         local test_pool=$TESTNAME
25067
25068         pool_add $test_pool || error "pool_add failed"
25069         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25070                 error "pool_add_targets failed"
25071
25072         save_layout_restore_at_exit $MOUNT
25073
25074         # parent set default stripe count only, child will stripe from both
25075         # parent and fs default
25076         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25077                 error "setstripe $MOUNT failed"
25078         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25079         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25080         for i in $(seq 10); do
25081                 local f=$DIR/$tdir/$tfile.$i
25082                 touch $f || error "touch failed"
25083                 local count=$($LFS getstripe -c $f)
25084                 [ $count -eq $OSTCOUNT ] ||
25085                         error "$f stripe count $count != $OSTCOUNT"
25086                 local offset=$($LFS getstripe -i $f)
25087                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25088                 local size=$($LFS getstripe -S $f)
25089                 [ $size -eq $((def_stripe_size * 2)) ] ||
25090                         error "$f stripe size $size != $((def_stripe_size * 2))"
25091                 local pool=$($LFS getstripe -p $f)
25092                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25093         done
25094
25095         # change fs default striping, delete parent default striping, now child
25096         # will stripe from new fs default striping only
25097         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25098                 error "change $MOUNT default stripe failed"
25099         $LFS setstripe -c 0 $DIR/$tdir ||
25100                 error "delete $tdir default stripe failed"
25101         for i in $(seq 11 20); do
25102                 local f=$DIR/$tdir/$tfile.$i
25103                 touch $f || error "touch $f failed"
25104                 local count=$($LFS getstripe -c $f)
25105                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25106                 local offset=$($LFS getstripe -i $f)
25107                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25108                 local size=$($LFS getstripe -S $f)
25109                 [ $size -eq $def_stripe_size ] ||
25110                         error "$f stripe size $size != $def_stripe_size"
25111                 local pool=$($LFS getstripe -p $f)
25112                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25113         done
25114
25115         unlinkmany $DIR/$tdir/$tfile. 1 20
25116
25117         local f=$DIR/$tdir/$tfile
25118         pool_remove_all_targets $test_pool $f
25119         pool_remove $test_pool $f
25120 }
25121 run_test 406 "DNE support fs default striping"
25122
25123 test_407() {
25124         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25125         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25126                 skip "Need MDS version at least 2.8.55"
25127         remote_mds_nodsh && skip "remote MDS with nodsh"
25128
25129         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25130                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25131         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25132                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25133         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25134
25135         #define OBD_FAIL_DT_TXN_STOP    0x2019
25136         for idx in $(seq $MDSCOUNT); do
25137                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25138         done
25139         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25140         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25141                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25142         true
25143 }
25144 run_test 407 "transaction fail should cause operation fail"
25145
25146 test_408() {
25147         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25148
25149         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25150         lctl set_param fail_loc=0x8000040a
25151         # let ll_prepare_partial_page() fail
25152         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25153
25154         rm -f $DIR/$tfile
25155
25156         # create at least 100 unused inodes so that
25157         # shrink_icache_memory(0) should not return 0
25158         touch $DIR/$tfile-{0..100}
25159         rm -f $DIR/$tfile-{0..100}
25160         sync
25161
25162         echo 2 > /proc/sys/vm/drop_caches
25163 }
25164 run_test 408 "drop_caches should not hang due to page leaks"
25165
25166 test_409()
25167 {
25168         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25169
25170         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25171         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25172         touch $DIR/$tdir/guard || error "(2) Fail to create"
25173
25174         local PREFIX=$(str_repeat 'A' 128)
25175         echo "Create 1K hard links start at $(date)"
25176         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25177                 error "(3) Fail to hard link"
25178
25179         echo "Links count should be right although linkEA overflow"
25180         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25181         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25182         [ $linkcount -eq 1001 ] ||
25183                 error "(5) Unexpected hard links count: $linkcount"
25184
25185         echo "List all links start at $(date)"
25186         ls -l $DIR/$tdir/foo > /dev/null ||
25187                 error "(6) Fail to list $DIR/$tdir/foo"
25188
25189         echo "Unlink hard links start at $(date)"
25190         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25191                 error "(7) Fail to unlink"
25192         echo "Unlink hard links finished at $(date)"
25193 }
25194 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25195
25196 test_410()
25197 {
25198         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25199                 skip "Need client version at least 2.9.59"
25200         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25201                 skip "Need MODULES build"
25202
25203         # Create a file, and stat it from the kernel
25204         local testfile=$DIR/$tfile
25205         touch $testfile
25206
25207         local run_id=$RANDOM
25208         local my_ino=$(stat --format "%i" $testfile)
25209
25210         # Try to insert the module. This will always fail as the
25211         # module is designed to not be inserted.
25212         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25213             &> /dev/null
25214
25215         # Anything but success is a test failure
25216         dmesg | grep -q \
25217             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25218             error "no inode match"
25219 }
25220 run_test 410 "Test inode number returned from kernel thread"
25221
25222 cleanup_test411_cgroup() {
25223         trap 0
25224         rmdir "$1"
25225 }
25226
25227 test_411() {
25228         local cg_basedir=/sys/fs/cgroup/memory
25229         # LU-9966
25230         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25231                 skip "no setup for cgroup"
25232
25233         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25234                 error "test file creation failed"
25235         cancel_lru_locks osc
25236
25237         # Create a very small memory cgroup to force a slab allocation error
25238         local cgdir=$cg_basedir/osc_slab_alloc
25239         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25240         trap "cleanup_test411_cgroup $cgdir" EXIT
25241         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25242         echo 1M > $cgdir/memory.limit_in_bytes
25243
25244         # Should not LBUG, just be killed by oom-killer
25245         # dd will return 0 even allocation failure in some environment.
25246         # So don't check return value
25247         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25248         cleanup_test411_cgroup $cgdir
25249
25250         return 0
25251 }
25252 run_test 411 "Slab allocation error with cgroup does not LBUG"
25253
25254 test_412() {
25255         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25256         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25257                 skip "Need server version at least 2.10.55"
25258
25259         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25260                 error "mkdir failed"
25261         $LFS getdirstripe $DIR/$tdir
25262         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25263         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25264                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25265         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25266         [ $stripe_count -eq 2 ] ||
25267                 error "expect 2 get $stripe_count"
25268
25269         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25270
25271         local index
25272         local index2
25273
25274         # subdirs should be on the same MDT as parent
25275         for i in $(seq 0 $((MDSCOUNT - 1))); do
25276                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25277                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25278                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25279                 (( index == i )) || error "mdt$i/sub on MDT$index"
25280         done
25281
25282         # stripe offset -1, ditto
25283         for i in {1..10}; do
25284                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25285                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25286                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25287                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25288                 (( index == index2 )) ||
25289                         error "qos$i on MDT$index, sub on MDT$index2"
25290         done
25291
25292         local testdir=$DIR/$tdir/inherit
25293
25294         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25295         # inherit 2 levels
25296         for i in 1 2; do
25297                 testdir=$testdir/s$i
25298                 mkdir $testdir || error "mkdir $testdir failed"
25299                 index=$($LFS getstripe -m $testdir)
25300                 (( index == 1 )) ||
25301                         error "$testdir on MDT$index"
25302         done
25303
25304         # not inherit any more
25305         testdir=$testdir/s3
25306         mkdir $testdir || error "mkdir $testdir failed"
25307         getfattr -d -m dmv $testdir | grep dmv &&
25308                 error "default LMV set on $testdir" || true
25309 }
25310 run_test 412 "mkdir on specific MDTs"
25311
25312 generate_uneven_mdts() {
25313         local threshold=$1
25314         local lmv_qos_maxage
25315         local lod_qos_maxage
25316         local ffree
25317         local bavail
25318         local max
25319         local min
25320         local max_index
25321         local min_index
25322         local tmp
25323         local i
25324
25325         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25326         $LCTL set_param lmv.*.qos_maxage=1
25327         stack_trap "$LCTL set_param \
25328                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25329         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25330                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25331         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25332                 lod.*.mdt_qos_maxage=1
25333         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25334                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25335
25336         echo
25337         echo "Check for uneven MDTs: "
25338
25339         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25340         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25341         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25342
25343         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25344         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25345         max_index=0
25346         min_index=0
25347         for ((i = 1; i < ${#ffree[@]}; i++)); do
25348                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25349                 if [ $tmp -gt $max ]; then
25350                         max=$tmp
25351                         max_index=$i
25352                 fi
25353                 if [ $tmp -lt $min ]; then
25354                         min=$tmp
25355                         min_index=$i
25356                 fi
25357         done
25358
25359         (( ${ffree[min_index]} > 0 )) ||
25360                 skip "no free files in MDT$min_index"
25361         (( ${ffree[min_index]} < 10000000 )) ||
25362                 skip "too many free files in MDT$min_index"
25363
25364         # Check if we need to generate uneven MDTs
25365         local diff=$(((max - min) * 100 / min))
25366         local testdir=$DIR/$tdir-fillmdt
25367         local start
25368
25369         mkdir -p $testdir
25370
25371         i=0
25372         while (( diff < threshold )); do
25373                 # generate uneven MDTs, create till $threshold% diff
25374                 echo -n "weight diff=$diff% must be > $threshold% ..."
25375                 echo "Fill MDT$min_index with 1000 files: loop $i"
25376                 testdir=$DIR/$tdir-fillmdt/$i
25377                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25378                         error "mkdir $testdir failed"
25379                 $LFS setstripe -E 1M -L mdt $testdir ||
25380                         error "setstripe $testdir failed"
25381                 start=$SECONDS
25382                 for F in f.{0..999}; do
25383                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25384                                 /dev/null 2>&1 || error "dd $F failed"
25385                 done
25386
25387                 # wait for QOS to update
25388                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25389
25390                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25391                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25392                 max=$(((${ffree[max_index]} >> 8) * \
25393                         (${bavail[max_index]} * bsize >> 16)))
25394                 min=$(((${ffree[min_index]} >> 8) * \
25395                         (${bavail[min_index]} * bsize >> 16)))
25396                 diff=$(((max - min) * 100 / min))
25397                 i=$((i + 1))
25398         done
25399
25400         echo "MDT filesfree available: ${ffree[@]}"
25401         echo "MDT blocks available: ${bavail[@]}"
25402         echo "weight diff=$diff%"
25403 }
25404
25405 test_qos_mkdir() {
25406         local mkdir_cmd=$1
25407         local stripe_count=$2
25408         local mdts=$(comma_list $(mdts_nodes))
25409
25410         local testdir
25411         local lmv_qos_prio_free
25412         local lmv_qos_threshold_rr
25413         local lmv_qos_maxage
25414         local lod_qos_prio_free
25415         local lod_qos_threshold_rr
25416         local lod_qos_maxage
25417         local count
25418         local i
25419
25420         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25421         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25422         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25423                 head -n1)
25424         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25425         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25426         stack_trap "$LCTL set_param \
25427                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25428         stack_trap "$LCTL set_param \
25429                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25430         stack_trap "$LCTL set_param \
25431                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25432
25433         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25434                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25435         lod_qos_prio_free=${lod_qos_prio_free%%%}
25436         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25437                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25438         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25439         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25440                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25441         stack_trap "do_nodes $mdts $LCTL set_param \
25442                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25443         stack_trap "do_nodes $mdts $LCTL set_param \
25444                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25445         stack_trap "do_nodes $mdts $LCTL set_param \
25446                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25447
25448         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25449         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25450
25451         testdir=$DIR/$tdir-s$stripe_count/rr
25452
25453         local stripe_index=$($LFS getstripe -m $testdir)
25454         local test_mkdir_rr=true
25455
25456         getfattr -d -m dmv -e hex $testdir | grep dmv
25457         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25458                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25459                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25460                         test_mkdir_rr=false
25461         fi
25462
25463         echo
25464         $test_mkdir_rr &&
25465                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25466                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25467
25468         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25469         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25470                 eval $mkdir_cmd $testdir/subdir$i ||
25471                         error "$mkdir_cmd subdir$i failed"
25472         done
25473
25474         for (( i = 0; i < $MDSCOUNT; i++ )); do
25475                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25476                 echo "$count directories created on MDT$i"
25477                 if $test_mkdir_rr; then
25478                         (( $count == 100 )) ||
25479                                 error "subdirs are not evenly distributed"
25480                 elif (( $i == $stripe_index )); then
25481                         (( $count == 100 * MDSCOUNT )) ||
25482                                 error "$count subdirs created on MDT$i"
25483                 else
25484                         (( $count == 0 )) ||
25485                                 error "$count subdirs created on MDT$i"
25486                 fi
25487
25488                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25489                         count=$($LFS getdirstripe $testdir/* |
25490                                 grep -c -P "^\s+$i\t")
25491                         echo "$count stripes created on MDT$i"
25492                         # deviation should < 5% of average
25493                         (( $count >= 95 * stripe_count &&
25494                            $count <= 105 * stripe_count)) ||
25495                                 error "stripes are not evenly distributed"
25496                 fi
25497         done
25498
25499         echo
25500         echo "Check for uneven MDTs: "
25501
25502         local ffree
25503         local bavail
25504         local max
25505         local min
25506         local max_index
25507         local min_index
25508         local tmp
25509
25510         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25511         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25512         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25513
25514         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25515         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25516         max_index=0
25517         min_index=0
25518         for ((i = 1; i < ${#ffree[@]}; i++)); do
25519                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25520                 if [ $tmp -gt $max ]; then
25521                         max=$tmp
25522                         max_index=$i
25523                 fi
25524                 if [ $tmp -lt $min ]; then
25525                         min=$tmp
25526                         min_index=$i
25527                 fi
25528         done
25529
25530         (( ${ffree[min_index]} > 0 )) ||
25531                 skip "no free files in MDT$min_index"
25532         (( ${ffree[min_index]} < 10000000 )) ||
25533                 skip "too many free files in MDT$min_index"
25534
25535         echo "MDT filesfree available: ${ffree[@]}"
25536         echo "MDT blocks available: ${bavail[@]}"
25537         echo "weight diff=$(((max - min) * 100 / min))%"
25538         echo
25539         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25540
25541         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25542         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25543         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25544         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25545         # decrease statfs age, so that it can be updated in time
25546         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25547         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25548
25549         sleep 1
25550
25551         testdir=$DIR/$tdir-s$stripe_count/qos
25552         local num=200
25553
25554         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25555         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25556                 eval $mkdir_cmd $testdir/subdir$i ||
25557                         error "$mkdir_cmd subdir$i failed"
25558         done
25559
25560         max=0
25561         for (( i = 0; i < $MDSCOUNT; i++ )); do
25562                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25563                 (( count > max )) && max=$count
25564                 echo "$count directories created on MDT$i"
25565         done
25566
25567         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25568
25569         # D-value should > 10% of averge
25570         (( max - min > num / 10 )) ||
25571                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25572
25573         # ditto for stripes
25574         if (( stripe_count > 1 )); then
25575                 max=0
25576                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25577                         count=$($LFS getdirstripe $testdir/* |
25578                                 grep -c -P "^\s+$i\t")
25579                         (( count > max )) && max=$count
25580                         echo "$count stripes created on MDT$i"
25581                 done
25582
25583                 min=$($LFS getdirstripe $testdir/* |
25584                         grep -c -P "^\s+$min_index\t")
25585                 (( max - min > num * stripe_count / 10 )) ||
25586                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25587         fi
25588 }
25589
25590 most_full_mdt() {
25591         local ffree
25592         local bavail
25593         local bsize
25594         local min
25595         local min_index
25596         local tmp
25597
25598         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25599         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25600         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25601
25602         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25603         min_index=0
25604         for ((i = 1; i < ${#ffree[@]}; i++)); do
25605                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25606                 (( tmp < min )) && min=$tmp && min_index=$i
25607         done
25608
25609         echo -n $min_index
25610 }
25611
25612 test_413a() {
25613         [ $MDSCOUNT -lt 2 ] &&
25614                 skip "We need at least 2 MDTs for this test"
25615
25616         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25617                 skip "Need server version at least 2.12.52"
25618
25619         local stripe_count
25620
25621         generate_uneven_mdts 100
25622         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25623                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25624                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25625                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25626                         error "mkdir failed"
25627                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25628         done
25629 }
25630 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25631
25632 test_413b() {
25633         [ $MDSCOUNT -lt 2 ] &&
25634                 skip "We need at least 2 MDTs for this test"
25635
25636         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25637                 skip "Need server version at least 2.12.52"
25638
25639         local testdir
25640         local stripe_count
25641
25642         generate_uneven_mdts 100
25643         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25644                 testdir=$DIR/$tdir-s$stripe_count
25645                 mkdir $testdir || error "mkdir $testdir failed"
25646                 mkdir $testdir/rr || error "mkdir rr failed"
25647                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25648                         error "mkdir qos failed"
25649                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25650                         $testdir/rr || error "setdirstripe rr failed"
25651                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25652                         error "setdirstripe failed"
25653                 test_qos_mkdir "mkdir" $stripe_count
25654         done
25655 }
25656 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25657
25658 test_413c() {
25659         (( $MDSCOUNT >= 2 )) ||
25660                 skip "We need at least 2 MDTs for this test"
25661
25662         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25663                 skip "Need server version at least 2.14.51"
25664
25665         local testdir
25666         local inherit
25667         local inherit_rr
25668
25669         testdir=$DIR/${tdir}-s1
25670         mkdir $testdir || error "mkdir $testdir failed"
25671         mkdir $testdir/rr || error "mkdir rr failed"
25672         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25673         # default max_inherit is -1, default max_inherit_rr is 0
25674         $LFS setdirstripe -D -c 1 $testdir/rr ||
25675                 error "setdirstripe rr failed"
25676         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25677                 error "setdirstripe qos failed"
25678         test_qos_mkdir "mkdir" 1
25679
25680         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25681         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25682         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25683         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25684         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25685
25686         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25687         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25688         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25689         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25690         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25691         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25692         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25693                 error "level2 shouldn't have default LMV" || true
25694 }
25695 run_test 413c "mkdir with default LMV max inherit rr"
25696
25697 test_413d() {
25698         (( MDSCOUNT >= 2 )) ||
25699                 skip "We need at least 2 MDTs for this test"
25700
25701         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25702                 skip "Need server version at least 2.14.51"
25703
25704         local lmv_qos_threshold_rr
25705
25706         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25707                 head -n1)
25708         stack_trap "$LCTL set_param \
25709                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25710
25711         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25712         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25713         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25714                 error "$tdir shouldn't have default LMV"
25715         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25716                 error "mkdir sub failed"
25717
25718         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25719
25720         (( count == 100 )) || error "$count subdirs on MDT0"
25721 }
25722 run_test 413d "inherit ROOT default LMV"
25723
25724 test_413e() {
25725         (( MDSCOUNT >= 2 )) ||
25726                 skip "We need at least 2 MDTs for this test"
25727         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25728                 skip "Need server version at least 2.14.55"
25729
25730         local testdir=$DIR/$tdir
25731         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25732         local max_inherit
25733         local sub_max_inherit
25734
25735         mkdir -p $testdir || error "failed to create $testdir"
25736
25737         # set default max-inherit to -1 if stripe count is 0 or 1
25738         $LFS setdirstripe -D -c 1 $testdir ||
25739                 error "failed to set default LMV"
25740         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25741         (( max_inherit == -1 )) ||
25742                 error "wrong max_inherit value $max_inherit"
25743
25744         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25745         $LFS setdirstripe -D -c -1 $testdir ||
25746                 error "failed to set default LMV"
25747         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25748         (( max_inherit > 0 )) ||
25749                 error "wrong max_inherit value $max_inherit"
25750
25751         # and the subdir will decrease the max_inherit by 1
25752         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25753         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
25754         (( sub_max_inherit == max_inherit - 1)) ||
25755                 error "wrong max-inherit of subdir $sub_max_inherit"
25756
25757         # check specified --max-inherit and warning message
25758         stack_trap "rm -f $tmpfile"
25759         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
25760                 error "failed to set default LMV"
25761         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25762         (( max_inherit == -1 )) ||
25763                 error "wrong max_inherit value $max_inherit"
25764
25765         # check the warning messages
25766         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
25767                 error "failed to detect warning string"
25768         fi
25769 }
25770 run_test 413e "check default max-inherit value"
25771
25772 test_413f() {
25773         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
25774
25775         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25776                 skip "Need server version at least 2.14.55"
25777
25778         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
25779                 error "dump $DIR default LMV failed"
25780         stack_trap "setfattr --restore=$TMP/dmv.ea"
25781
25782         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
25783                 error "set $DIR default LMV failed"
25784
25785         local testdir=$DIR/$tdir
25786
25787         local count
25788         local inherit
25789         local inherit_rr
25790
25791         for i in $(seq 3); do
25792                 mkdir $testdir || error "mkdir $testdir failed"
25793                 count=$($LFS getdirstripe -D -c $testdir)
25794                 (( count == 1 )) ||
25795                         error "$testdir default LMV count mismatch $count != 1"
25796                 inherit=$($LFS getdirstripe -D -X $testdir)
25797                 (( inherit == 3 - i )) ||
25798                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
25799                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
25800                 (( inherit_rr == 3 - i )) ||
25801                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
25802                 testdir=$testdir/sub
25803         done
25804
25805         mkdir $testdir || error "mkdir $testdir failed"
25806         count=$($LFS getdirstripe -D -c $testdir)
25807         (( count == 0 )) ||
25808                 error "$testdir default LMV count not zero: $count"
25809 }
25810 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
25811
25812 test_413z() {
25813         local pids=""
25814         local subdir
25815         local pid
25816
25817         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25818                 unlinkmany $subdir/f. 1000 &
25819                 pids="$pids $!"
25820         done
25821
25822         for pid in $pids; do
25823                 wait $pid
25824         done
25825 }
25826 run_test 413z "413 test cleanup"
25827
25828 test_414() {
25829 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25830         $LCTL set_param fail_loc=0x80000521
25831         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25832         rm -f $DIR/$tfile
25833 }
25834 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25835
25836 test_415() {
25837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25838         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25839                 skip "Need server version at least 2.11.52"
25840
25841         # LU-11102
25842         local total
25843         local setattr_pid
25844         local start_time
25845         local end_time
25846         local duration
25847
25848         total=500
25849         # this test may be slow on ZFS
25850         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25851
25852         # though this test is designed for striped directory, let's test normal
25853         # directory too since lock is always saved as CoS lock.
25854         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25855         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25856
25857         (
25858                 while true; do
25859                         touch $DIR/$tdir
25860                 done
25861         ) &
25862         setattr_pid=$!
25863
25864         start_time=$(date +%s)
25865         for i in $(seq $total); do
25866                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25867                         > /dev/null
25868         done
25869         end_time=$(date +%s)
25870         duration=$((end_time - start_time))
25871
25872         kill -9 $setattr_pid
25873
25874         echo "rename $total files took $duration sec"
25875         [ $duration -lt 100 ] || error "rename took $duration sec"
25876 }
25877 run_test 415 "lock revoke is not missing"
25878
25879 test_416() {
25880         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25881                 skip "Need server version at least 2.11.55"
25882
25883         # define OBD_FAIL_OSD_TXN_START    0x19a
25884         do_facet mds1 lctl set_param fail_loc=0x19a
25885
25886         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25887
25888         true
25889 }
25890 run_test 416 "transaction start failure won't cause system hung"
25891
25892 cleanup_417() {
25893         trap 0
25894         do_nodes $(comma_list $(mdts_nodes)) \
25895                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25896         do_nodes $(comma_list $(mdts_nodes)) \
25897                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25898         do_nodes $(comma_list $(mdts_nodes)) \
25899                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25900 }
25901
25902 test_417() {
25903         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25904         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25905                 skip "Need MDS version at least 2.11.56"
25906
25907         trap cleanup_417 RETURN EXIT
25908
25909         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25910         do_nodes $(comma_list $(mdts_nodes)) \
25911                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25912         $LFS migrate -m 0 $DIR/$tdir.1 &&
25913                 error "migrate dir $tdir.1 should fail"
25914
25915         do_nodes $(comma_list $(mdts_nodes)) \
25916                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25917         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25918                 error "create remote dir $tdir.2 should fail"
25919
25920         do_nodes $(comma_list $(mdts_nodes)) \
25921                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25922         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25923                 error "create striped dir $tdir.3 should fail"
25924         true
25925 }
25926 run_test 417 "disable remote dir, striped dir and dir migration"
25927
25928 # Checks that the outputs of df [-i] and lfs df [-i] match
25929 #
25930 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25931 check_lfs_df() {
25932         local dir=$2
25933         local inodes
25934         local df_out
25935         local lfs_df_out
25936         local count
25937         local passed=false
25938
25939         # blocks or inodes
25940         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25941
25942         for count in {1..100}; do
25943                 do_nodes "$CLIENTS" \
25944                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25945                 sync; sleep 0.2
25946
25947                 # read the lines of interest
25948                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25949                         error "df $inodes $dir | tail -n +2 failed"
25950                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25951                         error "lfs df $inodes $dir | grep summary: failed"
25952
25953                 # skip first substrings of each output as they are different
25954                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25955                 # compare the two outputs
25956                 passed=true
25957                 #  skip "available" on MDT until LU-13997 is fixed.
25958                 #for i in {1..5}; do
25959                 for i in 1 2 4 5; do
25960                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25961                 done
25962                 $passed && break
25963         done
25964
25965         if ! $passed; then
25966                 df -P $inodes $dir
25967                 echo
25968                 lfs df $inodes $dir
25969                 error "df and lfs df $1 output mismatch: "      \
25970                       "df ${inodes}: ${df_out[*]}, "            \
25971                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25972         fi
25973 }
25974
25975 test_418() {
25976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25977
25978         local dir=$DIR/$tdir
25979         local numfiles=$((RANDOM % 4096 + 2))
25980         local numblocks=$((RANDOM % 256 + 1))
25981
25982         wait_delete_completed
25983         test_mkdir $dir
25984
25985         # check block output
25986         check_lfs_df blocks $dir
25987         # check inode output
25988         check_lfs_df inodes $dir
25989
25990         # create a single file and retest
25991         echo "Creating a single file and testing"
25992         createmany -o $dir/$tfile- 1 &>/dev/null ||
25993                 error "creating 1 file in $dir failed"
25994         check_lfs_df blocks $dir
25995         check_lfs_df inodes $dir
25996
25997         # create a random number of files
25998         echo "Creating $((numfiles - 1)) files and testing"
25999         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26000                 error "creating $((numfiles - 1)) files in $dir failed"
26001
26002         # write a random number of blocks to the first test file
26003         echo "Writing $numblocks 4K blocks and testing"
26004         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26005                 count=$numblocks &>/dev/null ||
26006                 error "dd to $dir/${tfile}-0 failed"
26007
26008         # retest
26009         check_lfs_df blocks $dir
26010         check_lfs_df inodes $dir
26011
26012         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26013                 error "unlinking $numfiles files in $dir failed"
26014 }
26015 run_test 418 "df and lfs df outputs match"
26016
26017 test_419()
26018 {
26019         local dir=$DIR/$tdir
26020
26021         mkdir -p $dir
26022         touch $dir/file
26023
26024         cancel_lru_locks mdc
26025
26026         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26027         $LCTL set_param fail_loc=0x1410
26028         cat $dir/file
26029         $LCTL set_param fail_loc=0
26030         rm -rf $dir
26031 }
26032 run_test 419 "Verify open file by name doesn't crash kernel"
26033
26034 test_420()
26035 {
26036         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26037                 skip "Need MDS version at least 2.12.53"
26038
26039         local SAVE_UMASK=$(umask)
26040         local dir=$DIR/$tdir
26041         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26042
26043         mkdir -p $dir
26044         umask 0000
26045         mkdir -m03777 $dir/testdir
26046         ls -dn $dir/testdir
26047         # Need to remove trailing '.' when SELinux is enabled
26048         local dirperms=$(ls -dn $dir/testdir |
26049                          awk '{ sub(/\.$/, "", $1); print $1}')
26050         [ $dirperms == "drwxrwsrwt" ] ||
26051                 error "incorrect perms on $dir/testdir"
26052
26053         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26054                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26055         ls -n $dir/testdir/testfile
26056         local fileperms=$(ls -n $dir/testdir/testfile |
26057                           awk '{ sub(/\.$/, "", $1); print $1}')
26058         [ $fileperms == "-rwxr-xr-x" ] ||
26059                 error "incorrect perms on $dir/testdir/testfile"
26060
26061         umask $SAVE_UMASK
26062 }
26063 run_test 420 "clear SGID bit on non-directories for non-members"
26064
26065 test_421a() {
26066         local cnt
26067         local fid1
26068         local fid2
26069
26070         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26071                 skip "Need MDS version at least 2.12.54"
26072
26073         test_mkdir $DIR/$tdir
26074         createmany -o $DIR/$tdir/f 3
26075         cnt=$(ls -1 $DIR/$tdir | wc -l)
26076         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26077
26078         fid1=$(lfs path2fid $DIR/$tdir/f1)
26079         fid2=$(lfs path2fid $DIR/$tdir/f2)
26080         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26081
26082         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26083         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26084
26085         cnt=$(ls -1 $DIR/$tdir | wc -l)
26086         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26087
26088         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26089         createmany -o $DIR/$tdir/f 3
26090         cnt=$(ls -1 $DIR/$tdir | wc -l)
26091         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26092
26093         fid1=$(lfs path2fid $DIR/$tdir/f1)
26094         fid2=$(lfs path2fid $DIR/$tdir/f2)
26095         echo "remove using fsname $FSNAME"
26096         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26097
26098         cnt=$(ls -1 $DIR/$tdir | wc -l)
26099         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26100 }
26101 run_test 421a "simple rm by fid"
26102
26103 test_421b() {
26104         local cnt
26105         local FID1
26106         local FID2
26107
26108         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26109                 skip "Need MDS version at least 2.12.54"
26110
26111         test_mkdir $DIR/$tdir
26112         createmany -o $DIR/$tdir/f 3
26113         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26114         MULTIPID=$!
26115
26116         FID1=$(lfs path2fid $DIR/$tdir/f1)
26117         FID2=$(lfs path2fid $DIR/$tdir/f2)
26118         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26119
26120         kill -USR1 $MULTIPID
26121         wait
26122
26123         cnt=$(ls $DIR/$tdir | wc -l)
26124         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26125 }
26126 run_test 421b "rm by fid on open file"
26127
26128 test_421c() {
26129         local cnt
26130         local FIDS
26131
26132         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26133                 skip "Need MDS version at least 2.12.54"
26134
26135         test_mkdir $DIR/$tdir
26136         createmany -o $DIR/$tdir/f 3
26137         touch $DIR/$tdir/$tfile
26138         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26139         cnt=$(ls -1 $DIR/$tdir | wc -l)
26140         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26141
26142         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26143         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26144
26145         cnt=$(ls $DIR/$tdir | wc -l)
26146         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26147 }
26148 run_test 421c "rm by fid against hardlinked files"
26149
26150 test_421d() {
26151         local cnt
26152         local FIDS
26153
26154         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26155                 skip "Need MDS version at least 2.12.54"
26156
26157         test_mkdir $DIR/$tdir
26158         createmany -o $DIR/$tdir/f 4097
26159         cnt=$(ls -1 $DIR/$tdir | wc -l)
26160         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26161
26162         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26163         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26164
26165         cnt=$(ls $DIR/$tdir | wc -l)
26166         rm -rf $DIR/$tdir
26167         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26168 }
26169 run_test 421d "rmfid en masse"
26170
26171 test_421e() {
26172         local cnt
26173         local FID
26174
26175         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26176         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26177                 skip "Need MDS version at least 2.12.54"
26178
26179         mkdir -p $DIR/$tdir
26180         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26181         createmany -o $DIR/$tdir/striped_dir/f 512
26182         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26183         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26184
26185         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26186                 sed "s/[/][^:]*://g")
26187         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26188
26189         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26190         rm -rf $DIR/$tdir
26191         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26192 }
26193 run_test 421e "rmfid in DNE"
26194
26195 test_421f() {
26196         local cnt
26197         local FID
26198
26199         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26200                 skip "Need MDS version at least 2.12.54"
26201
26202         test_mkdir $DIR/$tdir
26203         touch $DIR/$tdir/f
26204         cnt=$(ls -1 $DIR/$tdir | wc -l)
26205         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26206
26207         FID=$(lfs path2fid $DIR/$tdir/f)
26208         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26209         # rmfid should fail
26210         cnt=$(ls -1 $DIR/$tdir | wc -l)
26211         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26212
26213         chmod a+rw $DIR/$tdir
26214         ls -la $DIR/$tdir
26215         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26216         # rmfid should fail
26217         cnt=$(ls -1 $DIR/$tdir | wc -l)
26218         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26219
26220         rm -f $DIR/$tdir/f
26221         $RUNAS touch $DIR/$tdir/f
26222         FID=$(lfs path2fid $DIR/$tdir/f)
26223         echo "rmfid as root"
26224         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26225         cnt=$(ls -1 $DIR/$tdir | wc -l)
26226         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26227
26228         rm -f $DIR/$tdir/f
26229         $RUNAS touch $DIR/$tdir/f
26230         cnt=$(ls -1 $DIR/$tdir | wc -l)
26231         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26232         FID=$(lfs path2fid $DIR/$tdir/f)
26233         # rmfid w/o user_fid2path mount option should fail
26234         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26235         cnt=$(ls -1 $DIR/$tdir | wc -l)
26236         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26237
26238         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26239         stack_trap "rmdir $tmpdir"
26240         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26241                 error "failed to mount client'"
26242         stack_trap "umount_client $tmpdir"
26243
26244         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26245         # rmfid should succeed
26246         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26247         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26248
26249         # rmfid shouldn't allow to remove files due to dir's permission
26250         chmod a+rwx $tmpdir/$tdir
26251         touch $tmpdir/$tdir/f
26252         ls -la $tmpdir/$tdir
26253         FID=$(lfs path2fid $tmpdir/$tdir/f)
26254         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26255         return 0
26256 }
26257 run_test 421f "rmfid checks permissions"
26258
26259 test_421g() {
26260         local cnt
26261         local FIDS
26262
26263         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26264         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26265                 skip "Need MDS version at least 2.12.54"
26266
26267         mkdir -p $DIR/$tdir
26268         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26269         createmany -o $DIR/$tdir/striped_dir/f 512
26270         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26271         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26272
26273         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26274                 sed "s/[/][^:]*://g")
26275
26276         rm -f $DIR/$tdir/striped_dir/f1*
26277         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26278         removed=$((512 - cnt))
26279
26280         # few files have been just removed, so we expect
26281         # rmfid to fail on their fids
26282         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26283         [ $removed != $errors ] && error "$errors != $removed"
26284
26285         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26286         rm -rf $DIR/$tdir
26287         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26288 }
26289 run_test 421g "rmfid to return errors properly"
26290
26291 test_422() {
26292         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26293         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26294         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26295         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26296         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26297
26298         local amc=$(at_max_get client)
26299         local amo=$(at_max_get mds1)
26300         local timeout=`lctl get_param -n timeout`
26301
26302         at_max_set 0 client
26303         at_max_set 0 mds1
26304
26305 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26306         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26307                         fail_val=$(((2*timeout + 10)*1000))
26308         touch $DIR/$tdir/d3/file &
26309         sleep 2
26310 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26311         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26312                         fail_val=$((2*timeout + 5))
26313         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26314         local pid=$!
26315         sleep 1
26316         kill -9 $pid
26317         sleep $((2 * timeout))
26318         echo kill $pid
26319         kill -9 $pid
26320         lctl mark touch
26321         touch $DIR/$tdir/d2/file3
26322         touch $DIR/$tdir/d2/file4
26323         touch $DIR/$tdir/d2/file5
26324
26325         wait
26326         at_max_set $amc client
26327         at_max_set $amo mds1
26328
26329         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26330         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26331                 error "Watchdog is always throttled"
26332 }
26333 run_test 422 "kill a process with RPC in progress"
26334
26335 stat_test() {
26336     df -h $MOUNT &
26337     df -h $MOUNT &
26338     df -h $MOUNT &
26339     df -h $MOUNT &
26340     df -h $MOUNT &
26341     df -h $MOUNT &
26342 }
26343
26344 test_423() {
26345     local _stats
26346     # ensure statfs cache is expired
26347     sleep 2;
26348
26349     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26350     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26351
26352     return 0
26353 }
26354 run_test 423 "statfs should return a right data"
26355
26356 test_424() {
26357 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26358         $LCTL set_param fail_loc=0x80000522
26359         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26360         rm -f $DIR/$tfile
26361 }
26362 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26363
26364 test_425() {
26365         test_mkdir -c -1 $DIR/$tdir
26366         $LFS setstripe -c -1 $DIR/$tdir
26367
26368         lru_resize_disable "" 100
26369         stack_trap "lru_resize_enable" EXIT
26370
26371         sleep 5
26372
26373         for i in $(seq $((MDSCOUNT * 125))); do
26374                 local t=$DIR/$tdir/$tfile_$i
26375
26376                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26377                         error_noexit "Create file $t"
26378         done
26379         stack_trap "rm -rf $DIR/$tdir" EXIT
26380
26381         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26382                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26383                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26384
26385                 [ $lock_count -le $lru_size ] ||
26386                         error "osc lock count $lock_count > lru size $lru_size"
26387         done
26388
26389         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26390                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26391                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26392
26393                 [ $lock_count -le $lru_size ] ||
26394                         error "mdc lock count $lock_count > lru size $lru_size"
26395         done
26396 }
26397 run_test 425 "lock count should not exceed lru size"
26398
26399 test_426() {
26400         splice-test -r $DIR/$tfile
26401         splice-test -rd $DIR/$tfile
26402         splice-test $DIR/$tfile
26403         splice-test -d $DIR/$tfile
26404 }
26405 run_test 426 "splice test on Lustre"
26406
26407 test_427() {
26408         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26409         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26410                 skip "Need MDS version at least 2.12.4"
26411         local log
26412
26413         mkdir $DIR/$tdir
26414         mkdir $DIR/$tdir/1
26415         mkdir $DIR/$tdir/2
26416         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26417         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26418
26419         $LFS getdirstripe $DIR/$tdir/1/dir
26420
26421         #first setfattr for creating updatelog
26422         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26423
26424 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26425         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26426         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26427         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26428
26429         sleep 2
26430         fail mds2
26431         wait_recovery_complete mds2 $((2*TIMEOUT))
26432
26433         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26434         echo $log | grep "get update log failed" &&
26435                 error "update log corruption is detected" || true
26436 }
26437 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26438
26439 test_428() {
26440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26441         local cache_limit=$CACHE_MAX
26442
26443         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26444         $LCTL set_param -n llite.*.max_cached_mb=64
26445
26446         mkdir $DIR/$tdir
26447         $LFS setstripe -c 1 $DIR/$tdir
26448         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26449         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26450         #test write
26451         for f in $(seq 4); do
26452                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26453         done
26454         wait
26455
26456         cancel_lru_locks osc
26457         # Test read
26458         for f in $(seq 4); do
26459                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26460         done
26461         wait
26462 }
26463 run_test 428 "large block size IO should not hang"
26464
26465 test_429() { # LU-7915 / LU-10948
26466         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26467         local testfile=$DIR/$tfile
26468         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26469         local new_flag=1
26470         local first_rpc
26471         local second_rpc
26472         local third_rpc
26473
26474         $LCTL get_param $ll_opencache_threshold_count ||
26475                 skip "client does not have opencache parameter"
26476
26477         set_opencache $new_flag
26478         stack_trap "restore_opencache"
26479         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26480                 error "enable opencache failed"
26481         touch $testfile
26482         # drop MDC DLM locks
26483         cancel_lru_locks mdc
26484         # clear MDC RPC stats counters
26485         $LCTL set_param $mdc_rpcstats=clear
26486
26487         # According to the current implementation, we need to run 3 times
26488         # open & close file to verify if opencache is enabled correctly.
26489         # 1st, RPCs are sent for lookup/open and open handle is released on
26490         #      close finally.
26491         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26492         #      so open handle won't be released thereafter.
26493         # 3rd, No RPC is sent out.
26494         $MULTIOP $testfile oc || error "multiop failed"
26495         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26496         echo "1st: $first_rpc RPCs in flight"
26497
26498         $MULTIOP $testfile oc || error "multiop failed"
26499         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26500         echo "2nd: $second_rpc RPCs in flight"
26501
26502         $MULTIOP $testfile oc || error "multiop failed"
26503         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26504         echo "3rd: $third_rpc RPCs in flight"
26505
26506         #verify no MDC RPC is sent
26507         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26508 }
26509 run_test 429 "verify if opencache flag on client side does work"
26510
26511 lseek_test_430() {
26512         local offset
26513         local file=$1
26514
26515         # data at [200K, 400K)
26516         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26517                 error "256K->512K dd fails"
26518         # data at [2M, 3M)
26519         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26520                 error "2M->3M dd fails"
26521         # data at [4M, 5M)
26522         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26523                 error "4M->5M dd fails"
26524         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26525         # start at first component hole #1
26526         printf "Seeking hole from 1000 ... "
26527         offset=$(lseek_test -l 1000 $file)
26528         echo $offset
26529         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26530         printf "Seeking data from 1000 ... "
26531         offset=$(lseek_test -d 1000 $file)
26532         echo $offset
26533         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26534
26535         # start at first component data block
26536         printf "Seeking hole from 300000 ... "
26537         offset=$(lseek_test -l 300000 $file)
26538         echo $offset
26539         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26540         printf "Seeking data from 300000 ... "
26541         offset=$(lseek_test -d 300000 $file)
26542         echo $offset
26543         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26544
26545         # start at the first component but beyond end of object size
26546         printf "Seeking hole from 1000000 ... "
26547         offset=$(lseek_test -l 1000000 $file)
26548         echo $offset
26549         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26550         printf "Seeking data from 1000000 ... "
26551         offset=$(lseek_test -d 1000000 $file)
26552         echo $offset
26553         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26554
26555         # start at second component stripe 2 (empty file)
26556         printf "Seeking hole from 1500000 ... "
26557         offset=$(lseek_test -l 1500000 $file)
26558         echo $offset
26559         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26560         printf "Seeking data from 1500000 ... "
26561         offset=$(lseek_test -d 1500000 $file)
26562         echo $offset
26563         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26564
26565         # start at second component stripe 1 (all data)
26566         printf "Seeking hole from 3000000 ... "
26567         offset=$(lseek_test -l 3000000 $file)
26568         echo $offset
26569         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26570         printf "Seeking data from 3000000 ... "
26571         offset=$(lseek_test -d 3000000 $file)
26572         echo $offset
26573         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26574
26575         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26576                 error "2nd dd fails"
26577         echo "Add data block at 640K...1280K"
26578
26579         # start at before new data block, in hole
26580         printf "Seeking hole from 600000 ... "
26581         offset=$(lseek_test -l 600000 $file)
26582         echo $offset
26583         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26584         printf "Seeking data from 600000 ... "
26585         offset=$(lseek_test -d 600000 $file)
26586         echo $offset
26587         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26588
26589         # start at the first component new data block
26590         printf "Seeking hole from 1000000 ... "
26591         offset=$(lseek_test -l 1000000 $file)
26592         echo $offset
26593         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26594         printf "Seeking data from 1000000 ... "
26595         offset=$(lseek_test -d 1000000 $file)
26596         echo $offset
26597         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26598
26599         # start at second component stripe 2, new data
26600         printf "Seeking hole from 1200000 ... "
26601         offset=$(lseek_test -l 1200000 $file)
26602         echo $offset
26603         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26604         printf "Seeking data from 1200000 ... "
26605         offset=$(lseek_test -d 1200000 $file)
26606         echo $offset
26607         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26608
26609         # start beyond file end
26610         printf "Using offset > filesize ... "
26611         lseek_test -l 4000000 $file && error "lseek should fail"
26612         printf "Using offset > filesize ... "
26613         lseek_test -d 4000000 $file && error "lseek should fail"
26614
26615         printf "Done\n\n"
26616 }
26617
26618 test_430a() {
26619         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26620                 skip "MDT does not support SEEK_HOLE"
26621
26622         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26623                 skip "OST does not support SEEK_HOLE"
26624
26625         local file=$DIR/$tdir/$tfile
26626
26627         mkdir -p $DIR/$tdir
26628
26629         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26630         # OST stripe #1 will have continuous data at [1M, 3M)
26631         # OST stripe #2 is empty
26632         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26633         lseek_test_430 $file
26634         rm $file
26635         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26636         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26637         lseek_test_430 $file
26638         rm $file
26639         $LFS setstripe -c2 -S 512K $file
26640         echo "Two stripes, stripe size 512K"
26641         lseek_test_430 $file
26642         rm $file
26643         # FLR with stale mirror
26644         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26645                        -N -c2 -S 1M $file
26646         echo "Mirrored file:"
26647         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26648         echo "Plain 2 stripes 1M"
26649         lseek_test_430 $file
26650         rm $file
26651 }
26652 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26653
26654 test_430b() {
26655         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26656                 skip "OST does not support SEEK_HOLE"
26657
26658         local offset
26659         local file=$DIR/$tdir/$tfile
26660
26661         mkdir -p $DIR/$tdir
26662         # Empty layout lseek should fail
26663         $MCREATE $file
26664         # seek from 0
26665         printf "Seeking hole from 0 ... "
26666         lseek_test -l 0 $file && error "lseek should fail"
26667         printf "Seeking data from 0 ... "
26668         lseek_test -d 0 $file && error "lseek should fail"
26669         rm $file
26670
26671         # 1M-hole file
26672         $LFS setstripe -E 1M -c2 -E eof $file
26673         $TRUNCATE $file 1048576
26674         printf "Seeking hole from 1000000 ... "
26675         offset=$(lseek_test -l 1000000 $file)
26676         echo $offset
26677         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26678         printf "Seeking data from 1000000 ... "
26679         lseek_test -d 1000000 $file && error "lseek should fail"
26680         rm $file
26681
26682         # full component followed by non-inited one
26683         $LFS setstripe -E 1M -c2 -E eof $file
26684         dd if=/dev/urandom of=$file bs=1M count=1
26685         printf "Seeking hole from 1000000 ... "
26686         offset=$(lseek_test -l 1000000 $file)
26687         echo $offset
26688         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26689         printf "Seeking hole from 1048576 ... "
26690         lseek_test -l 1048576 $file && error "lseek should fail"
26691         # init second component and truncate back
26692         echo "123" >> $file
26693         $TRUNCATE $file 1048576
26694         printf "Seeking hole from 1000000 ... "
26695         offset=$(lseek_test -l 1000000 $file)
26696         echo $offset
26697         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26698         printf "Seeking hole from 1048576 ... "
26699         lseek_test -l 1048576 $file && error "lseek should fail"
26700         # boundary checks for big values
26701         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26702         offset=$(lseek_test -d 0 $file.10g)
26703         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26704         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26705         offset=$(lseek_test -d 0 $file.100g)
26706         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26707         return 0
26708 }
26709 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26710
26711 test_430c() {
26712         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26713                 skip "OST does not support SEEK_HOLE"
26714
26715         local file=$DIR/$tdir/$tfile
26716         local start
26717
26718         mkdir -p $DIR/$tdir
26719         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26720
26721         # cp version 8.33+ prefers lseek over fiemap
26722         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26723                 start=$SECONDS
26724                 time cp $file /dev/null
26725                 (( SECONDS - start < 5 )) ||
26726                         error "cp: too long runtime $((SECONDS - start))"
26727
26728         fi
26729         # tar version 1.29+ supports SEEK_HOLE/DATA
26730         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26731                 start=$SECONDS
26732                 time tar cS $file - | cat > /dev/null
26733                 (( SECONDS - start < 5 )) ||
26734                         error "tar: too long runtime $((SECONDS - start))"
26735         fi
26736 }
26737 run_test 430c "lseek: external tools check"
26738
26739 test_431() { # LU-14187
26740         local file=$DIR/$tdir/$tfile
26741
26742         mkdir -p $DIR/$tdir
26743         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26744         dd if=/dev/urandom of=$file bs=4k count=1
26745         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26746         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26747         #define OBD_FAIL_OST_RESTART_IO 0x251
26748         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26749         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26750         cp $file $file.0
26751         cancel_lru_locks
26752         sync_all_data
26753         echo 3 > /proc/sys/vm/drop_caches
26754         diff  $file $file.0 || error "data diff"
26755 }
26756 run_test 431 "Restart transaction for IO"
26757
26758 cleanup_test_432() {
26759         do_facet mgs $LCTL nodemap_activate 0
26760         wait_nm_sync active
26761 }
26762
26763 test_432() {
26764         local tmpdir=$TMP/dir432
26765
26766         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26767                 skip "Need MDS version at least 2.14.52"
26768
26769         stack_trap cleanup_test_432 EXIT
26770         mkdir $DIR/$tdir
26771         mkdir $tmpdir
26772
26773         do_facet mgs $LCTL nodemap_activate 1
26774         wait_nm_sync active
26775         do_facet mgs $LCTL nodemap_modify --name default \
26776                 --property admin --value 1
26777         do_facet mgs $LCTL nodemap_modify --name default \
26778                 --property trusted --value 1
26779         cancel_lru_locks mdc
26780         wait_nm_sync default admin_nodemap
26781         wait_nm_sync default trusted_nodemap
26782
26783         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26784                grep -ci "Operation not permitted") -ne 0 ]; then
26785                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26786         fi
26787 }
26788 run_test 432 "mv dir from outside Lustre"
26789
26790 prep_801() {
26791         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26792         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26793                 skip "Need server version at least 2.9.55"
26794
26795         start_full_debug_logging
26796 }
26797
26798 post_801() {
26799         stop_full_debug_logging
26800 }
26801
26802 barrier_stat() {
26803         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26804                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26805                            awk '/The barrier for/ { print $7 }')
26806                 echo $st
26807         else
26808                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26809                 echo \'$st\'
26810         fi
26811 }
26812
26813 barrier_expired() {
26814         local expired
26815
26816         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26817                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26818                           awk '/will be expired/ { print $7 }')
26819         else
26820                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26821         fi
26822
26823         echo $expired
26824 }
26825
26826 test_801a() {
26827         prep_801
26828
26829         echo "Start barrier_freeze at: $(date)"
26830         #define OBD_FAIL_BARRIER_DELAY          0x2202
26831         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26832         # Do not reduce barrier time - See LU-11873
26833         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26834
26835         sleep 2
26836         local b_status=$(barrier_stat)
26837         echo "Got barrier status at: $(date)"
26838         [ "$b_status" = "'freezing_p1'" ] ||
26839                 error "(1) unexpected barrier status $b_status"
26840
26841         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26842         wait
26843         b_status=$(barrier_stat)
26844         [ "$b_status" = "'frozen'" ] ||
26845                 error "(2) unexpected barrier status $b_status"
26846
26847         local expired=$(barrier_expired)
26848         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26849         sleep $((expired + 3))
26850
26851         b_status=$(barrier_stat)
26852         [ "$b_status" = "'expired'" ] ||
26853                 error "(3) unexpected barrier status $b_status"
26854
26855         # Do not reduce barrier time - See LU-11873
26856         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26857                 error "(4) fail to freeze barrier"
26858
26859         b_status=$(barrier_stat)
26860         [ "$b_status" = "'frozen'" ] ||
26861                 error "(5) unexpected barrier status $b_status"
26862
26863         echo "Start barrier_thaw at: $(date)"
26864         #define OBD_FAIL_BARRIER_DELAY          0x2202
26865         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26866         do_facet mgs $LCTL barrier_thaw $FSNAME &
26867
26868         sleep 2
26869         b_status=$(barrier_stat)
26870         echo "Got barrier status at: $(date)"
26871         [ "$b_status" = "'thawing'" ] ||
26872                 error "(6) unexpected barrier status $b_status"
26873
26874         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26875         wait
26876         b_status=$(barrier_stat)
26877         [ "$b_status" = "'thawed'" ] ||
26878                 error "(7) unexpected barrier status $b_status"
26879
26880         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26881         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26882         do_facet mgs $LCTL barrier_freeze $FSNAME
26883
26884         b_status=$(barrier_stat)
26885         [ "$b_status" = "'failed'" ] ||
26886                 error "(8) unexpected barrier status $b_status"
26887
26888         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26889         do_facet mgs $LCTL barrier_thaw $FSNAME
26890
26891         post_801
26892 }
26893 run_test 801a "write barrier user interfaces and stat machine"
26894
26895 test_801b() {
26896         prep_801
26897
26898         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26899         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
26900         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26901         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26902         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26903
26904         cancel_lru_locks mdc
26905
26906         # 180 seconds should be long enough
26907         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26908
26909         local b_status=$(barrier_stat)
26910         [ "$b_status" = "'frozen'" ] ||
26911                 error "(6) unexpected barrier status $b_status"
26912
26913         mkdir $DIR/$tdir/d0/d10 &
26914         mkdir_pid=$!
26915
26916         touch $DIR/$tdir/d1/f13 &
26917         touch_pid=$!
26918
26919         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26920         ln_pid=$!
26921
26922         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26923         mv_pid=$!
26924
26925         rm -f $DIR/$tdir/d4/f12 &
26926         rm_pid=$!
26927
26928         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26929
26930         # To guarantee taht the 'stat' is not blocked
26931         b_status=$(barrier_stat)
26932         [ "$b_status" = "'frozen'" ] ||
26933                 error "(8) unexpected barrier status $b_status"
26934
26935         # let above commands to run at background
26936         sleep 5
26937
26938         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26939         ps -p $touch_pid || error "(10) touch should be blocked"
26940         ps -p $ln_pid || error "(11) link should be blocked"
26941         ps -p $mv_pid || error "(12) rename should be blocked"
26942         ps -p $rm_pid || error "(13) unlink should be blocked"
26943
26944         b_status=$(barrier_stat)
26945         [ "$b_status" = "'frozen'" ] ||
26946                 error "(14) unexpected barrier status $b_status"
26947
26948         do_facet mgs $LCTL barrier_thaw $FSNAME
26949         b_status=$(barrier_stat)
26950         [ "$b_status" = "'thawed'" ] ||
26951                 error "(15) unexpected barrier status $b_status"
26952
26953         wait $mkdir_pid || error "(16) mkdir should succeed"
26954         wait $touch_pid || error "(17) touch should succeed"
26955         wait $ln_pid || error "(18) link should succeed"
26956         wait $mv_pid || error "(19) rename should succeed"
26957         wait $rm_pid || error "(20) unlink should succeed"
26958
26959         post_801
26960 }
26961 run_test 801b "modification will be blocked by write barrier"
26962
26963 test_801c() {
26964         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26965
26966         prep_801
26967
26968         stop mds2 || error "(1) Fail to stop mds2"
26969
26970         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26971
26972         local b_status=$(barrier_stat)
26973         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26974                 do_facet mgs $LCTL barrier_thaw $FSNAME
26975                 error "(2) unexpected barrier status $b_status"
26976         }
26977
26978         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26979                 error "(3) Fail to rescan barrier bitmap"
26980
26981         # Do not reduce barrier time - See LU-11873
26982         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26983
26984         b_status=$(barrier_stat)
26985         [ "$b_status" = "'frozen'" ] ||
26986                 error "(4) unexpected barrier status $b_status"
26987
26988         do_facet mgs $LCTL barrier_thaw $FSNAME
26989         b_status=$(barrier_stat)
26990         [ "$b_status" = "'thawed'" ] ||
26991                 error "(5) unexpected barrier status $b_status"
26992
26993         local devname=$(mdsdevname 2)
26994
26995         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26996
26997         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26998                 error "(7) Fail to rescan barrier bitmap"
26999
27000         post_801
27001 }
27002 run_test 801c "rescan barrier bitmap"
27003
27004 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27005 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27006 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27007 saved_MOUNT_OPTS=$MOUNT_OPTS
27008
27009 cleanup_802a() {
27010         trap 0
27011
27012         stopall
27013         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27014         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27015         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27016         MOUNT_OPTS=$saved_MOUNT_OPTS
27017         setupall
27018 }
27019
27020 test_802a() {
27021         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27022         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27023         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27024                 skip "Need server version at least 2.9.55"
27025
27026         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27027
27028         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27029
27030         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27031                 error "(2) Fail to copy"
27032
27033         trap cleanup_802a EXIT
27034
27035         # sync by force before remount as readonly
27036         sync; sync_all_data; sleep 3; sync_all_data
27037
27038         stopall
27039
27040         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27041         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27042         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27043
27044         echo "Mount the server as read only"
27045         setupall server_only || error "(3) Fail to start servers"
27046
27047         echo "Mount client without ro should fail"
27048         mount_client $MOUNT &&
27049                 error "(4) Mount client without 'ro' should fail"
27050
27051         echo "Mount client with ro should succeed"
27052         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27053         mount_client $MOUNT ||
27054                 error "(5) Mount client with 'ro' should succeed"
27055
27056         echo "Modify should be refused"
27057         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27058
27059         echo "Read should be allowed"
27060         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27061                 error "(7) Read should succeed under ro mode"
27062
27063         cleanup_802a
27064 }
27065 run_test 802a "simulate readonly device"
27066
27067 test_802b() {
27068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27069         remote_mds_nodsh && skip "remote MDS with nodsh"
27070
27071         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27072                 skip "readonly option not available"
27073
27074         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27075
27076         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27077                 error "(2) Fail to copy"
27078
27079         # write back all cached data before setting MDT to readonly
27080         cancel_lru_locks
27081         sync_all_data
27082
27083         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27084         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27085
27086         echo "Modify should be refused"
27087         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27088
27089         echo "Read should be allowed"
27090         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27091                 error "(7) Read should succeed under ro mode"
27092
27093         # disable readonly
27094         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27095 }
27096 run_test 802b "be able to set MDTs to readonly"
27097
27098 test_803a() {
27099         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27100         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27101                 skip "MDS needs to be newer than 2.10.54"
27102
27103         mkdir_on_mdt0 $DIR/$tdir
27104         # Create some objects on all MDTs to trigger related logs objects
27105         for idx in $(seq $MDSCOUNT); do
27106                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27107                         $DIR/$tdir/dir${idx} ||
27108                         error "Fail to create $DIR/$tdir/dir${idx}"
27109         done
27110
27111         sync; sleep 3
27112         wait_delete_completed # ensure old test cleanups are finished
27113         echo "before create:"
27114         $LFS df -i $MOUNT
27115         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27116
27117         for i in {1..10}; do
27118                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27119                         error "Fail to create $DIR/$tdir/foo$i"
27120         done
27121
27122         sync; sleep 3
27123         echo "after create:"
27124         $LFS df -i $MOUNT
27125         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27126
27127         # allow for an llog to be cleaned up during the test
27128         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27129                 error "before ($before_used) + 10 > after ($after_used)"
27130
27131         for i in {1..10}; do
27132                 rm -rf $DIR/$tdir/foo$i ||
27133                         error "Fail to remove $DIR/$tdir/foo$i"
27134         done
27135
27136         sleep 3 # avoid MDT return cached statfs
27137         wait_delete_completed
27138         echo "after unlink:"
27139         $LFS df -i $MOUNT
27140         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27141
27142         # allow for an llog to be created during the test
27143         [ $after_used -le $((before_used + 1)) ] ||
27144                 error "after ($after_used) > before ($before_used) + 1"
27145 }
27146 run_test 803a "verify agent object for remote object"
27147
27148 test_803b() {
27149         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27150         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27151                 skip "MDS needs to be newer than 2.13.56"
27152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27153
27154         for i in $(seq 0 $((MDSCOUNT - 1))); do
27155                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27156         done
27157
27158         local before=0
27159         local after=0
27160
27161         local tmp
27162
27163         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27164         for i in $(seq 0 $((MDSCOUNT - 1))); do
27165                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27166                         awk '/getattr/ { print $2 }')
27167                 before=$((before + tmp))
27168         done
27169         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27170         for i in $(seq 0 $((MDSCOUNT - 1))); do
27171                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27172                         awk '/getattr/ { print $2 }')
27173                 after=$((after + tmp))
27174         done
27175
27176         [ $before -eq $after ] || error "getattr count $before != $after"
27177 }
27178 run_test 803b "remote object can getattr from cache"
27179
27180 test_804() {
27181         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27182         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27183                 skip "MDS needs to be newer than 2.10.54"
27184         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27185
27186         mkdir -p $DIR/$tdir
27187         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27188                 error "Fail to create $DIR/$tdir/dir0"
27189
27190         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27191         local dev=$(mdsdevname 2)
27192
27193         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27194                 grep ${fid} || error "NOT found agent entry for dir0"
27195
27196         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27197                 error "Fail to create $DIR/$tdir/dir1"
27198
27199         touch $DIR/$tdir/dir1/foo0 ||
27200                 error "Fail to create $DIR/$tdir/dir1/foo0"
27201         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27202         local rc=0
27203
27204         for idx in $(seq $MDSCOUNT); do
27205                 dev=$(mdsdevname $idx)
27206                 do_facet mds${idx} \
27207                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27208                         grep ${fid} && rc=$idx
27209         done
27210
27211         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27212                 error "Fail to rename foo0 to foo1"
27213         if [ $rc -eq 0 ]; then
27214                 for idx in $(seq $MDSCOUNT); do
27215                         dev=$(mdsdevname $idx)
27216                         do_facet mds${idx} \
27217                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27218                         grep ${fid} && rc=$idx
27219                 done
27220         fi
27221
27222         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27223                 error "Fail to rename foo1 to foo2"
27224         if [ $rc -eq 0 ]; then
27225                 for idx in $(seq $MDSCOUNT); do
27226                         dev=$(mdsdevname $idx)
27227                         do_facet mds${idx} \
27228                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27229                         grep ${fid} && rc=$idx
27230                 done
27231         fi
27232
27233         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27234
27235         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27236                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27237         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27238                 error "Fail to rename foo2 to foo0"
27239         unlink $DIR/$tdir/dir1/foo0 ||
27240                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27241         rm -rf $DIR/$tdir/dir0 ||
27242                 error "Fail to rm $DIR/$tdir/dir0"
27243
27244         for idx in $(seq $MDSCOUNT); do
27245                 rc=0
27246
27247                 stop mds${idx}
27248                 dev=$(mdsdevname $idx)
27249                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27250                         rc=$?
27251                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27252                         error "mount mds$idx failed"
27253                 df $MOUNT > /dev/null 2>&1
27254
27255                 # e2fsck should not return error
27256                 [ $rc -eq 0 ] ||
27257                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27258         done
27259 }
27260 run_test 804 "verify agent entry for remote entry"
27261
27262 cleanup_805() {
27263         do_facet $SINGLEMDS zfs set quota=$old $fsset
27264         unlinkmany $DIR/$tdir/f- 1000000
27265         trap 0
27266 }
27267
27268 test_805() {
27269         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27270         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27271         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27272                 skip "netfree not implemented before 0.7"
27273         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27274                 skip "Need MDS version at least 2.10.57"
27275
27276         local fsset
27277         local freekb
27278         local usedkb
27279         local old
27280         local quota
27281         local pref="osd-zfs.$FSNAME-MDT0000."
27282
27283         # limit available space on MDS dataset to meet nospace issue
27284         # quickly. then ZFS 0.7.2 can use reserved space if asked
27285         # properly (using netfree flag in osd_declare_destroy()
27286         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27287         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27288                 gawk '{print $3}')
27289         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27290         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27291         let "usedkb=usedkb-freekb"
27292         let "freekb=freekb/2"
27293         if let "freekb > 5000"; then
27294                 let "freekb=5000"
27295         fi
27296         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27297         trap cleanup_805 EXIT
27298         mkdir_on_mdt0 $DIR/$tdir
27299         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27300                 error "Can't set PFL layout"
27301         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27302         rm -rf $DIR/$tdir || error "not able to remove"
27303         do_facet $SINGLEMDS zfs set quota=$old $fsset
27304         trap 0
27305 }
27306 run_test 805 "ZFS can remove from full fs"
27307
27308 # Size-on-MDS test
27309 check_lsom_data()
27310 {
27311         local file=$1
27312         local expect=$(stat -c %s $file)
27313
27314         check_lsom_size $1 $expect
27315
27316         local blocks=$($LFS getsom -b $file)
27317         expect=$(stat -c %b $file)
27318         [[ $blocks == $expect ]] ||
27319                 error "$file expected blocks: $expect, got: $blocks"
27320 }
27321
27322 check_lsom_size()
27323 {
27324         local size
27325         local expect=$2
27326
27327         cancel_lru_locks mdc
27328
27329         size=$($LFS getsom -s $1)
27330         [[ $size == $expect ]] ||
27331                 error "$file expected size: $expect, got: $size"
27332 }
27333
27334 test_806() {
27335         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27336                 skip "Need MDS version at least 2.11.52"
27337
27338         local bs=1048576
27339
27340         touch $DIR/$tfile || error "touch $tfile failed"
27341
27342         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27343         save_lustre_params client "llite.*.xattr_cache" > $save
27344         lctl set_param llite.*.xattr_cache=0
27345         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27346
27347         # single-threaded write
27348         echo "Test SOM for single-threaded write"
27349         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27350                 error "write $tfile failed"
27351         check_lsom_size $DIR/$tfile $bs
27352
27353         local num=32
27354         local size=$(($num * $bs))
27355         local offset=0
27356         local i
27357
27358         echo "Test SOM for single client multi-threaded($num) write"
27359         $TRUNCATE $DIR/$tfile 0
27360         for ((i = 0; i < $num; i++)); do
27361                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27362                 local pids[$i]=$!
27363                 offset=$((offset + $bs))
27364         done
27365         for (( i=0; i < $num; i++ )); do
27366                 wait ${pids[$i]}
27367         done
27368         check_lsom_size $DIR/$tfile $size
27369
27370         $TRUNCATE $DIR/$tfile 0
27371         for ((i = 0; i < $num; i++)); do
27372                 offset=$((offset - $bs))
27373                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27374                 local pids[$i]=$!
27375         done
27376         for (( i=0; i < $num; i++ )); do
27377                 wait ${pids[$i]}
27378         done
27379         check_lsom_size $DIR/$tfile $size
27380
27381         # multi-client writes
27382         num=$(get_node_count ${CLIENTS//,/ })
27383         size=$(($num * $bs))
27384         offset=0
27385         i=0
27386
27387         echo "Test SOM for multi-client ($num) writes"
27388         $TRUNCATE $DIR/$tfile 0
27389         for client in ${CLIENTS//,/ }; do
27390                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27391                 local pids[$i]=$!
27392                 i=$((i + 1))
27393                 offset=$((offset + $bs))
27394         done
27395         for (( i=0; i < $num; i++ )); do
27396                 wait ${pids[$i]}
27397         done
27398         check_lsom_size $DIR/$tfile $offset
27399
27400         i=0
27401         $TRUNCATE $DIR/$tfile 0
27402         for client in ${CLIENTS//,/ }; do
27403                 offset=$((offset - $bs))
27404                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27405                 local pids[$i]=$!
27406                 i=$((i + 1))
27407         done
27408         for (( i=0; i < $num; i++ )); do
27409                 wait ${pids[$i]}
27410         done
27411         check_lsom_size $DIR/$tfile $size
27412
27413         # verify truncate
27414         echo "Test SOM for truncate"
27415         $TRUNCATE $DIR/$tfile 1048576
27416         check_lsom_size $DIR/$tfile 1048576
27417         $TRUNCATE $DIR/$tfile 1234
27418         check_lsom_size $DIR/$tfile 1234
27419
27420         # verify SOM blocks count
27421         echo "Verify SOM block count"
27422         $TRUNCATE $DIR/$tfile 0
27423         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27424                 error "failed to write file $tfile"
27425         check_lsom_data $DIR/$tfile
27426 }
27427 run_test 806 "Verify Lazy Size on MDS"
27428
27429 test_807() {
27430         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27431         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27432                 skip "Need MDS version at least 2.11.52"
27433
27434         # Registration step
27435         changelog_register || error "changelog_register failed"
27436         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27437         changelog_users $SINGLEMDS | grep -q $cl_user ||
27438                 error "User $cl_user not found in changelog_users"
27439
27440         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27441         save_lustre_params client "llite.*.xattr_cache" > $save
27442         lctl set_param llite.*.xattr_cache=0
27443         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27444
27445         rm -rf $DIR/$tdir || error "rm $tdir failed"
27446         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27447         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27448         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27449         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27450                 error "truncate $tdir/trunc failed"
27451
27452         local bs=1048576
27453         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27454                 error "write $tfile failed"
27455
27456         # multi-client wirtes
27457         local num=$(get_node_count ${CLIENTS//,/ })
27458         local offset=0
27459         local i=0
27460
27461         echo "Test SOM for multi-client ($num) writes"
27462         touch $DIR/$tfile || error "touch $tfile failed"
27463         $TRUNCATE $DIR/$tfile 0
27464         for client in ${CLIENTS//,/ }; do
27465                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27466                 local pids[$i]=$!
27467                 i=$((i + 1))
27468                 offset=$((offset + $bs))
27469         done
27470         for (( i=0; i < $num; i++ )); do
27471                 wait ${pids[$i]}
27472         done
27473
27474         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27475         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27476         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27477         check_lsom_data $DIR/$tdir/trunc
27478         check_lsom_data $DIR/$tdir/single_dd
27479         check_lsom_data $DIR/$tfile
27480
27481         rm -rf $DIR/$tdir
27482         # Deregistration step
27483         changelog_deregister || error "changelog_deregister failed"
27484 }
27485 run_test 807 "verify LSOM syncing tool"
27486
27487 check_som_nologged()
27488 {
27489         local lines=$($LFS changelog $FSNAME-MDT0000 |
27490                 grep 'x=trusted.som' | wc -l)
27491         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27492 }
27493
27494 test_808() {
27495         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27496                 skip "Need MDS version at least 2.11.55"
27497
27498         # Registration step
27499         changelog_register || error "changelog_register failed"
27500
27501         touch $DIR/$tfile || error "touch $tfile failed"
27502         check_som_nologged
27503
27504         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27505                 error "write $tfile failed"
27506         check_som_nologged
27507
27508         $TRUNCATE $DIR/$tfile 1234
27509         check_som_nologged
27510
27511         $TRUNCATE $DIR/$tfile 1048576
27512         check_som_nologged
27513
27514         # Deregistration step
27515         changelog_deregister || error "changelog_deregister failed"
27516 }
27517 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27518
27519 check_som_nodata()
27520 {
27521         $LFS getsom $1
27522         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27523 }
27524
27525 test_809() {
27526         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27527                 skip "Need MDS version at least 2.11.56"
27528
27529         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27530                 error "failed to create DoM-only file $DIR/$tfile"
27531         touch $DIR/$tfile || error "touch $tfile failed"
27532         check_som_nodata $DIR/$tfile
27533
27534         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27535                 error "write $tfile failed"
27536         check_som_nodata $DIR/$tfile
27537
27538         $TRUNCATE $DIR/$tfile 1234
27539         check_som_nodata $DIR/$tfile
27540
27541         $TRUNCATE $DIR/$tfile 4097
27542         check_som_nodata $DIR/$file
27543 }
27544 run_test 809 "Verify no SOM xattr store for DoM-only files"
27545
27546 test_810() {
27547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27548         $GSS && skip_env "could not run with gss"
27549         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27550                 skip "OST < 2.12.58 doesn't align checksum"
27551
27552         set_checksums 1
27553         stack_trap "set_checksums $ORIG_CSUM" EXIT
27554         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27555
27556         local csum
27557         local before
27558         local after
27559         for csum in $CKSUM_TYPES; do
27560                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27561                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27562                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27563                         eval set -- $i
27564                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27565                         before=$(md5sum $DIR/$tfile)
27566                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27567                         after=$(md5sum $DIR/$tfile)
27568                         [ "$before" == "$after" ] ||
27569                                 error "$csum: $before != $after bs=$1 seek=$2"
27570                 done
27571         done
27572 }
27573 run_test 810 "partial page writes on ZFS (LU-11663)"
27574
27575 test_812a() {
27576         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27577                 skip "OST < 2.12.51 doesn't support this fail_loc"
27578
27579         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27580         # ensure ost1 is connected
27581         stat $DIR/$tfile >/dev/null || error "can't stat"
27582         wait_osc_import_state client ost1 FULL
27583         # no locks, no reqs to let the connection idle
27584         cancel_lru_locks osc
27585
27586         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27587 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27588         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27589         wait_osc_import_state client ost1 CONNECTING
27590         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27591
27592         stat $DIR/$tfile >/dev/null || error "can't stat file"
27593 }
27594 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27595
27596 test_812b() { # LU-12378
27597         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27598                 skip "OST < 2.12.51 doesn't support this fail_loc"
27599
27600         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27601         # ensure ost1 is connected
27602         stat $DIR/$tfile >/dev/null || error "can't stat"
27603         wait_osc_import_state client ost1 FULL
27604         # no locks, no reqs to let the connection idle
27605         cancel_lru_locks osc
27606
27607         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27608 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27609         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27610         wait_osc_import_state client ost1 CONNECTING
27611         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27612
27613         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27614         wait_osc_import_state client ost1 IDLE
27615 }
27616 run_test 812b "do not drop no resend request for idle connect"
27617
27618 test_812c() {
27619         local old
27620
27621         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27622
27623         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27624         $LFS getstripe $DIR/$tfile
27625         $LCTL set_param osc.*.idle_timeout=10
27626         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27627         # ensure ost1 is connected
27628         stat $DIR/$tfile >/dev/null || error "can't stat"
27629         wait_osc_import_state client ost1 FULL
27630         # no locks, no reqs to let the connection idle
27631         cancel_lru_locks osc
27632
27633 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27634         $LCTL set_param fail_loc=0x80000533
27635         sleep 15
27636         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27637 }
27638 run_test 812c "idle import vs lock enqueue race"
27639
27640 test_813() {
27641         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27642         [ -z "$file_heat_sav" ] && skip "no file heat support"
27643
27644         local readsample
27645         local writesample
27646         local readbyte
27647         local writebyte
27648         local readsample1
27649         local writesample1
27650         local readbyte1
27651         local writebyte1
27652
27653         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27654         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27655
27656         $LCTL set_param -n llite.*.file_heat=1
27657         echo "Turn on file heat"
27658         echo "Period second: $period_second, Decay percentage: $decay_pct"
27659
27660         echo "QQQQ" > $DIR/$tfile
27661         echo "QQQQ" > $DIR/$tfile
27662         echo "QQQQ" > $DIR/$tfile
27663         cat $DIR/$tfile > /dev/null
27664         cat $DIR/$tfile > /dev/null
27665         cat $DIR/$tfile > /dev/null
27666         cat $DIR/$tfile > /dev/null
27667
27668         local out=$($LFS heat_get $DIR/$tfile)
27669
27670         $LFS heat_get $DIR/$tfile
27671         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27672         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27673         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27674         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27675
27676         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27677         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27678         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27679         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27680
27681         sleep $((period_second + 3))
27682         echo "Sleep $((period_second + 3)) seconds..."
27683         # The recursion formula to calculate the heat of the file f is as
27684         # follow:
27685         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27686         # Where Hi is the heat value in the period between time points i*I and
27687         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27688         # to the weight of Ci.
27689         out=$($LFS heat_get $DIR/$tfile)
27690         $LFS heat_get $DIR/$tfile
27691         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27692         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27693         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27694         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27695
27696         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27697                 error "read sample ($readsample) is wrong"
27698         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27699                 error "write sample ($writesample) is wrong"
27700         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27701                 error "read bytes ($readbyte) is wrong"
27702         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27703                 error "write bytes ($writebyte) is wrong"
27704
27705         echo "QQQQ" > $DIR/$tfile
27706         echo "QQQQ" > $DIR/$tfile
27707         echo "QQQQ" > $DIR/$tfile
27708         cat $DIR/$tfile > /dev/null
27709         cat $DIR/$tfile > /dev/null
27710         cat $DIR/$tfile > /dev/null
27711         cat $DIR/$tfile > /dev/null
27712
27713         sleep $((period_second + 3))
27714         echo "Sleep $((period_second + 3)) seconds..."
27715
27716         out=$($LFS heat_get $DIR/$tfile)
27717         $LFS heat_get $DIR/$tfile
27718         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27719         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27720         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27721         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27722
27723         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27724                 4 * $decay_pct) / 100") -eq 1 ] ||
27725                 error "read sample ($readsample1) is wrong"
27726         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27727                 3 * $decay_pct) / 100") -eq 1 ] ||
27728                 error "write sample ($writesample1) is wrong"
27729         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27730                 20 * $decay_pct) / 100") -eq 1 ] ||
27731                 error "read bytes ($readbyte1) is wrong"
27732         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27733                 15 * $decay_pct) / 100") -eq 1 ] ||
27734                 error "write bytes ($writebyte1) is wrong"
27735
27736         echo "Turn off file heat for the file $DIR/$tfile"
27737         $LFS heat_set -o $DIR/$tfile
27738
27739         echo "QQQQ" > $DIR/$tfile
27740         echo "QQQQ" > $DIR/$tfile
27741         echo "QQQQ" > $DIR/$tfile
27742         cat $DIR/$tfile > /dev/null
27743         cat $DIR/$tfile > /dev/null
27744         cat $DIR/$tfile > /dev/null
27745         cat $DIR/$tfile > /dev/null
27746
27747         out=$($LFS heat_get $DIR/$tfile)
27748         $LFS heat_get $DIR/$tfile
27749         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27750         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27751         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27752         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27753
27754         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27755         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27756         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27757         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27758
27759         echo "Trun on file heat for the file $DIR/$tfile"
27760         $LFS heat_set -O $DIR/$tfile
27761
27762         echo "QQQQ" > $DIR/$tfile
27763         echo "QQQQ" > $DIR/$tfile
27764         echo "QQQQ" > $DIR/$tfile
27765         cat $DIR/$tfile > /dev/null
27766         cat $DIR/$tfile > /dev/null
27767         cat $DIR/$tfile > /dev/null
27768         cat $DIR/$tfile > /dev/null
27769
27770         out=$($LFS heat_get $DIR/$tfile)
27771         $LFS heat_get $DIR/$tfile
27772         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27773         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27774         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27775         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27776
27777         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27778         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27779         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27780         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27781
27782         $LFS heat_set -c $DIR/$tfile
27783         $LCTL set_param -n llite.*.file_heat=0
27784         echo "Turn off file heat support for the Lustre filesystem"
27785
27786         echo "QQQQ" > $DIR/$tfile
27787         echo "QQQQ" > $DIR/$tfile
27788         echo "QQQQ" > $DIR/$tfile
27789         cat $DIR/$tfile > /dev/null
27790         cat $DIR/$tfile > /dev/null
27791         cat $DIR/$tfile > /dev/null
27792         cat $DIR/$tfile > /dev/null
27793
27794         out=$($LFS heat_get $DIR/$tfile)
27795         $LFS heat_get $DIR/$tfile
27796         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27797         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27798         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27799         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27800
27801         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27802         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27803         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27804         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27805
27806         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27807         rm -f $DIR/$tfile
27808 }
27809 run_test 813 "File heat verfication"
27810
27811 test_814()
27812 {
27813         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27814         echo -n y >> $DIR/$tfile
27815         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27816         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27817 }
27818 run_test 814 "sparse cp works as expected (LU-12361)"
27819
27820 test_815()
27821 {
27822         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27823         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27824 }
27825 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27826
27827 test_816() {
27828         local ost1_imp=$(get_osc_import_name client ost1)
27829         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27830                          cut -d'.' -f2)
27831
27832         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27833         # ensure ost1 is connected
27834
27835         stat $DIR/$tfile >/dev/null || error "can't stat"
27836         wait_osc_import_state client ost1 FULL
27837         # no locks, no reqs to let the connection idle
27838         cancel_lru_locks osc
27839         lru_resize_disable osc
27840         local before
27841         local now
27842         before=$($LCTL get_param -n \
27843                  ldlm.namespaces.$imp_name.lru_size)
27844
27845         wait_osc_import_state client ost1 IDLE
27846         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27847         now=$($LCTL get_param -n \
27848               ldlm.namespaces.$imp_name.lru_size)
27849         [ $before == $now ] || error "lru_size changed $before != $now"
27850 }
27851 run_test 816 "do not reset lru_resize on idle reconnect"
27852
27853 cleanup_817() {
27854         umount $tmpdir
27855         exportfs -u localhost:$DIR/nfsexp
27856         rm -rf $DIR/nfsexp
27857 }
27858
27859 test_817() {
27860         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27861
27862         mkdir -p $DIR/nfsexp
27863         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27864                 error "failed to export nfs"
27865
27866         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27867         stack_trap cleanup_817 EXIT
27868
27869         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27870                 error "failed to mount nfs to $tmpdir"
27871
27872         cp /bin/true $tmpdir
27873         $DIR/nfsexp/true || error "failed to execute 'true' command"
27874 }
27875 run_test 817 "nfsd won't cache write lock for exec file"
27876
27877 test_818() {
27878         test_mkdir -i0 -c1 $DIR/$tdir
27879         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
27880         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
27881         stop $SINGLEMDS
27882
27883         # restore osp-syn threads
27884         stack_trap "fail $SINGLEMDS"
27885
27886         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27887         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27888         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27889                 error "start $SINGLEMDS failed"
27890         rm -rf $DIR/$tdir
27891
27892         local testid=$(echo $TESTNAME | tr '_' ' ')
27893
27894         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
27895                 grep "run LFSCK" || error "run LFSCK is not suggested"
27896 }
27897 run_test 818 "unlink with failed llog"
27898
27899 test_819a() {
27900         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27901         cancel_lru_locks osc
27902         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27903         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27904         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27905         rm -f $TDIR/$tfile
27906 }
27907 run_test 819a "too big niobuf in read"
27908
27909 test_819b() {
27910         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27911         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27912         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27913         cancel_lru_locks osc
27914         sleep 1
27915         rm -f $TDIR/$tfile
27916 }
27917 run_test 819b "too big niobuf in write"
27918
27919
27920 function test_820_start_ost() {
27921         sleep 5
27922
27923         for num in $(seq $OSTCOUNT); do
27924                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27925         done
27926 }
27927
27928 test_820() {
27929         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27930
27931         mkdir $DIR/$tdir
27932         umount_client $MOUNT || error "umount failed"
27933         for num in $(seq $OSTCOUNT); do
27934                 stop ost$num
27935         done
27936
27937         # mount client with no active OSTs
27938         # so that the client can't initialize max LOV EA size
27939         # from OSC notifications
27940         mount_client $MOUNT || error "mount failed"
27941         # delay OST starting to keep this 0 max EA size for a while
27942         test_820_start_ost &
27943
27944         # create a directory on MDS2
27945         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27946                 error "Failed to create directory"
27947         # open intent should update default EA size
27948         # see mdc_update_max_ea_from_body()
27949         # notice this is the very first RPC to MDS2
27950         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27951         ret=$?
27952         echo $out
27953         # With SSK, this situation can lead to -EPERM being returned.
27954         # In that case, simply retry.
27955         if [ $ret -ne 0 ] && $SHARED_KEY; then
27956                 if echo "$out" | grep -q "not permitted"; then
27957                         cp /etc/services $DIR/$tdir/mds2
27958                         ret=$?
27959                 fi
27960         fi
27961         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27962 }
27963 run_test 820 "update max EA from open intent"
27964
27965 test_822() {
27966         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27967
27968         save_lustre_params mds1 \
27969                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27970         do_facet $SINGLEMDS "$LCTL set_param -n \
27971                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27972         do_facet $SINGLEMDS "$LCTL set_param -n \
27973                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27974
27975         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27976         local maxage=$(do_facet mds1 $LCTL get_param -n \
27977                        osp.$FSNAME-OST0000*MDT0000.maxage)
27978         sleep $((maxage + 1))
27979
27980         #define OBD_FAIL_NET_ERROR_RPC          0x532
27981         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27982
27983         stack_trap "restore_lustre_params < $p; rm $p"
27984
27985         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27986                       osp.$FSNAME-OST0000*MDT0000.create_count")
27987         for i in $(seq 1 $count); do
27988                 touch $DIR/$tfile.${i} || error "touch failed"
27989         done
27990 }
27991 run_test 822 "test precreate failure"
27992
27993 test_823() {
27994         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27995         local OST_MAX_PRECREATE=20000
27996
27997         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
27998                 skip "Need MDS version at least 2.14.56"
27999
28000         save_lustre_params mds1 \
28001                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28002         do_facet $SINGLEMDS "$LCTL set_param -n \
28003                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28004         do_facet $SINGLEMDS "$LCTL set_param -n \
28005                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28006
28007         stack_trap "restore_lustre_params < $p; rm $p"
28008
28009         do_facet $SINGLEMDS "$LCTL set_param -n \
28010                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28011
28012         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28013                       osp.$FSNAME-OST0000*MDT0000.create_count")
28014         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28015                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28016         local expect_count=$(((($max/2)/256) * 256))
28017
28018         log "setting create_count to 100200:"
28019         log " -result- count: $count with max: $max, expecting: $expect_count"
28020
28021         [[ $count -eq expect_count ]] ||
28022                 error "Create count not set to max precreate."
28023 }
28024 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28025
28026 test_831() {
28027         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28028                 skip "Need MDS version 2.14.56"
28029
28030         local sync_changes=$(do_facet $SINGLEMDS \
28031                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28032
28033         [ "$sync_changes" -gt 100 ] &&
28034                 skip "Sync changes $sync_changes > 100 already"
28035
28036         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28037
28038         $LFS mkdir -i 0 $DIR/$tdir
28039         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28040
28041         save_lustre_params mds1 \
28042                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28043         save_lustre_params mds1 \
28044                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28045
28046         do_facet mds1 "$LCTL set_param -n \
28047                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28048                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28049         stack_trap "restore_lustre_params < $p" EXIT
28050
28051         createmany -o $DIR/$tdir/f- 1000
28052         unlinkmany $DIR/$tdir/f- 1000 &
28053         local UNLINK_PID=$!
28054
28055         while sleep 1; do
28056                 sync_changes=$(do_facet mds1 \
28057                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28058                 # the check in the code is racy, fail the test
28059                 # if the value above the limit by 10.
28060                 [ $sync_changes -gt 110 ] && {
28061                         kill -2 $UNLINK_PID
28062                         wait
28063                         error "osp changes throttling failed, $sync_changes>110"
28064                 }
28065                 kill -0 $UNLINK_PID 2> /dev/null || break
28066         done
28067         wait
28068 }
28069 run_test 831 "throttling unlink/setattr queuing on OSP"
28070
28071 #
28072 # tests that do cleanup/setup should be run at the end
28073 #
28074
28075 test_900() {
28076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28077         local ls
28078
28079         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28080         $LCTL set_param fail_loc=0x903
28081
28082         cancel_lru_locks MGC
28083
28084         FAIL_ON_ERROR=true cleanup
28085         FAIL_ON_ERROR=true setup
28086 }
28087 run_test 900 "umount should not race with any mgc requeue thread"
28088
28089 # LUS-6253/LU-11185
28090 test_901() {
28091         local old
28092         local count
28093         local oldc
28094         local newc
28095         local olds
28096         local news
28097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28098
28099         # some get_param have a bug to handle dot in param name
28100         cancel_lru_locks MGC
28101         old=$(mount -t lustre | wc -l)
28102         # 1 config+sptlrpc
28103         # 2 params
28104         # 3 nodemap
28105         # 4 IR
28106         old=$((old * 4))
28107         oldc=0
28108         count=0
28109         while [ $old -ne $oldc ]; do
28110                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28111                 sleep 1
28112                 ((count++))
28113                 if [ $count -ge $TIMEOUT ]; then
28114                         error "too large timeout"
28115                 fi
28116         done
28117         umount_client $MOUNT || error "umount failed"
28118         mount_client $MOUNT || error "mount failed"
28119         cancel_lru_locks MGC
28120         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28121
28122         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28123
28124         return 0
28125 }
28126 run_test 901 "don't leak a mgc lock on client umount"
28127
28128 # LU-13377
28129 test_902() {
28130         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28131                 skip "client does not have LU-13377 fix"
28132         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28133         $LCTL set_param fail_loc=0x1415
28134         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28135         cancel_lru_locks osc
28136         rm -f $DIR/$tfile
28137 }
28138 run_test 902 "test short write doesn't hang lustre"
28139
28140 # LU-14711
28141 test_903() {
28142         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28143         echo "blah" > $DIR/${tfile}-2
28144         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28145         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28146         $LCTL set_param fail_loc=0x417 fail_val=20
28147
28148         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28149         sleep 1 # To start the destroy
28150         wait_destroy_complete 150 || error "Destroy taking too long"
28151         cat $DIR/$tfile > /dev/null || error "Evicted"
28152 }
28153 run_test 903 "Test long page discard does not cause evictions"
28154
28155 test_904() {
28156         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28157         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28158                 grep -q project || skip "skip project quota not supported"
28159
28160         local testfile="$DIR/$tdir/$tfile"
28161         local xattr="trusted.projid"
28162         local projid
28163         local mdts=$(comma_list $(mdts_nodes))
28164         local saved=$(do_facet mds1 $LCTL get_param -n \
28165                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28166
28167         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28168         stack_trap "do_nodes $mdts $LCTL set_param \
28169                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28170
28171         mkdir -p $DIR/$tdir
28172         touch $testfile
28173         #hide projid xattr on server
28174         $LFS project -p 1 $testfile ||
28175                 error "set $testfile project id failed"
28176         getfattr -m - $testfile | grep $xattr &&
28177                 error "do not show trusted.projid when disabled on server"
28178         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28179         #should be hidden when projid is 0
28180         $LFS project -p 0 $testfile ||
28181                 error "set $testfile project id failed"
28182         getfattr -m - $testfile | grep $xattr &&
28183                 error "do not show trusted.projid with project ID 0"
28184
28185         #still can getxattr explicitly
28186         projid=$(getfattr -n $xattr $testfile |
28187                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28188         [ $projid == "0" ] ||
28189                 error "projid expected 0 not $projid"
28190
28191         #set the projid via setxattr
28192         setfattr -n $xattr -v "1000" $testfile ||
28193                 error "setattr failed with $?"
28194         projid=($($LFS project $testfile))
28195         [ ${projid[0]} == "1000" ] ||
28196                 error "projid expected 1000 not $projid"
28197
28198         #check the new projid via getxattr
28199         $LFS project -p 1001 $testfile ||
28200                 error "set $testfile project id failed"
28201         getfattr -m - $testfile | grep $xattr ||
28202                 error "should show trusted.projid when project ID != 0"
28203         projid=$(getfattr -n $xattr $testfile |
28204                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28205         [ $projid == "1001" ] ||
28206                 error "projid expected 1001 not $projid"
28207
28208         #try to set invalid projid
28209         setfattr -n $xattr -v "4294967295" $testfile &&
28210                 error "set invalid projid should fail"
28211
28212         #remove the xattr means setting projid to 0
28213         setfattr -x $xattr $testfile ||
28214                 error "setfattr failed with $?"
28215         projid=($($LFS project $testfile))
28216         [ ${projid[0]} == "0" ] ||
28217                 error "projid expected 0 not $projid"
28218
28219         #should be hidden when parent has inherit flag and same projid
28220         $LFS project -srp 1002 $DIR/$tdir ||
28221                 error "set $tdir project id failed"
28222         getfattr -m - $testfile | grep $xattr &&
28223                 error "do not show trusted.projid with inherit flag"
28224
28225         #still can getxattr explicitly
28226         projid=$(getfattr -n $xattr $testfile |
28227                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28228         [ $projid == "1002" ] ||
28229                 error "projid expected 1002 not $projid"
28230 }
28231 run_test 904 "virtual project ID xattr"
28232
28233 complete $SECONDS
28234 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28235 check_and_cleanup_lustre
28236 if [ "$I_MOUNTED" != "yes" ]; then
28237         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28238 fi
28239 exit_status