Whamcloud - gitweb
LU-14541 llite: reenable fast_read by default
[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 Index: ${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 "${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 10
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         local pipe="$DIR/$tfile.pipe"
6025         local string="aaaaaa"
6026
6027         mknod $pipe p
6028         echo -n "$string" > $pipe &
6029         local result=$(cat $pipe)
6030         [[ "$result" == "$string" ]] || error "$result != $string"
6031 }
6032 run_test 54d "fifo device works in lustre ======================"
6033
6034 test_54e() {
6035         f="$DIR/f54e"
6036         string="aaaaaa"
6037         cp -aL /dev/console $f
6038         echo $string > $f || error "echo $string to $f failed"
6039 }
6040 run_test 54e "console/tty device works in lustre ======================"
6041
6042 test_56a() {
6043         local numfiles=3
6044         local numdirs=2
6045         local dir=$DIR/$tdir
6046
6047         rm -rf $dir
6048         test_mkdir -p $dir/dir
6049         for i in $(seq $numfiles); do
6050                 touch $dir/file$i
6051                 touch $dir/dir/file$i
6052         done
6053
6054         local numcomp=$($LFS getstripe --component-count $dir)
6055
6056         [[ $numcomp == 0 ]] && numcomp=1
6057
6058         # test lfs getstripe with --recursive
6059         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6060
6061         [[ $filenum -eq $((numfiles * 2)) ]] ||
6062                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6063         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6064         [[ $filenum -eq $numfiles ]] ||
6065                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6066         echo "$LFS getstripe showed obdidx or l_ost_idx"
6067
6068         # test lfs getstripe with file instead of dir
6069         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6070         [[ $filenum -eq 1 ]] ||
6071                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6072         echo "$LFS getstripe file1 passed"
6073
6074         #test lfs getstripe with --verbose
6075         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6076         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6077                 error "$LFS getstripe --verbose $dir: "\
6078                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6079         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6080                 error "$LFS getstripe $dir: showed lmm_magic"
6081
6082         #test lfs getstripe with -v prints lmm_fid
6083         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6084         local countfids=$((numdirs + numfiles * numcomp))
6085         [[ $filenum -eq $countfids ]] ||
6086                 error "$LFS getstripe -v $dir: "\
6087                       "got $filenum want $countfids lmm_fid"
6088         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6089                 error "$LFS getstripe $dir: showed lmm_fid by default"
6090         echo "$LFS getstripe --verbose passed"
6091
6092         #check for FID information
6093         local fid1=$($LFS getstripe --fid $dir/file1)
6094         local fid2=$($LFS getstripe --verbose $dir/file1 |
6095                      awk '/lmm_fid: / { print $2; exit; }')
6096         local fid3=$($LFS path2fid $dir/file1)
6097
6098         [ "$fid1" != "$fid2" ] &&
6099                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6100         [ "$fid1" != "$fid3" ] &&
6101                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6102         echo "$LFS getstripe --fid passed"
6103
6104         #test lfs getstripe with --obd
6105         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6106                 error "$LFS getstripe --obd wrong_uuid: should return error"
6107
6108         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6109
6110         local ostidx=1
6111         local obduuid=$(ostuuid_from_index $ostidx)
6112         local found=$($LFS getstripe -r --obd $obduuid $dir |
6113                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6114
6115         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6116         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6117                 ((filenum--))
6118         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6119                 ((filenum--))
6120
6121         [[ $found -eq $filenum ]] ||
6122                 error "$LFS getstripe --obd: found $found expect $filenum"
6123         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6124                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6125                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6126                 error "$LFS getstripe --obd: should not show file on other obd"
6127         echo "$LFS getstripe --obd passed"
6128 }
6129 run_test 56a "check $LFS getstripe"
6130
6131 test_56b() {
6132         local dir=$DIR/$tdir
6133         local numdirs=3
6134
6135         test_mkdir $dir
6136         for i in $(seq $numdirs); do
6137                 test_mkdir $dir/dir$i
6138         done
6139
6140         # test lfs getdirstripe default mode is non-recursion, which is
6141         # different from lfs getstripe
6142         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6143
6144         [[ $dircnt -eq 1 ]] ||
6145                 error "$LFS getdirstripe: found $dircnt, not 1"
6146         dircnt=$($LFS getdirstripe --recursive $dir |
6147                 grep -c lmv_stripe_count)
6148         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6149                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6150 }
6151 run_test 56b "check $LFS getdirstripe"
6152
6153 test_56c() {
6154         remote_ost_nodsh && skip "remote OST with nodsh"
6155
6156         local ost_idx=0
6157         local ost_name=$(ostname_from_index $ost_idx)
6158         local old_status=$(ost_dev_status $ost_idx)
6159         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6160
6161         [[ -z "$old_status" ]] ||
6162                 skip_env "OST $ost_name is in $old_status status"
6163
6164         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6165         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6166                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6167         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6168                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6169                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6170         fi
6171
6172         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6173                 error "$LFS df -v showing inactive devices"
6174         sleep_maxage
6175
6176         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6177
6178         [[ "$new_status" =~ "D" ]] ||
6179                 error "$ost_name status is '$new_status', missing 'D'"
6180         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6181                 [[ "$new_status" =~ "N" ]] ||
6182                         error "$ost_name status is '$new_status', missing 'N'"
6183         fi
6184         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6185                 [[ "$new_status" =~ "f" ]] ||
6186                         error "$ost_name status is '$new_status', missing 'f'"
6187         fi
6188
6189         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6190         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6191                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6192         [[ -z "$p" ]] && restore_lustre_params < $p || true
6193         sleep_maxage
6194
6195         new_status=$(ost_dev_status $ost_idx)
6196         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6197                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6198         # can't check 'f' as devices may actually be on flash
6199 }
6200 run_test 56c "check 'lfs df' showing device status"
6201
6202 test_56d() {
6203         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6204         local osts=$($LFS df -v $MOUNT | grep -c OST)
6205
6206         $LFS df $MOUNT
6207
6208         (( mdts == MDSCOUNT )) ||
6209                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6210         (( osts == OSTCOUNT )) ||
6211                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6212 }
6213 run_test 56d "'lfs df -v' prints only configured devices"
6214
6215 test_56e() {
6216         err_enoent=2 # No such file or directory
6217         err_eopnotsupp=95 # Operation not supported
6218
6219         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6220         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6221
6222         # Check for handling of path not exists
6223         output=$($LFS df $enoent_mnt 2>&1)
6224         ret=$?
6225
6226         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6227         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6228                 error "expect failure $err_enoent, not $ret"
6229
6230         # Check for handling of non-Lustre FS
6231         output=$($LFS df $notsup_mnt)
6232         ret=$?
6233
6234         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6235         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6236                 error "expect success $err_eopnotsupp, not $ret"
6237
6238         # Check for multiple LustreFS argument
6239         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6240         ret=$?
6241
6242         [[ $output -eq 3 && $ret -eq 0 ]] ||
6243                 error "expect success 3, not $output, rc = $ret"
6244
6245         # Check for correct non-Lustre FS handling among multiple
6246         # LustreFS argument
6247         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6248                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6249         ret=$?
6250
6251         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6252                 error "expect success 2, not $output, rc = $ret"
6253 }
6254 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6255
6256 NUMFILES=3
6257 NUMDIRS=3
6258 setup_56() {
6259         local local_tdir="$1"
6260         local local_numfiles="$2"
6261         local local_numdirs="$3"
6262         local dir_params="$4"
6263         local dir_stripe_params="$5"
6264
6265         if [ ! -d "$local_tdir" ] ; then
6266                 test_mkdir -p $dir_stripe_params $local_tdir
6267                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6268                 for i in $(seq $local_numfiles) ; do
6269                         touch $local_tdir/file$i
6270                 done
6271                 for i in $(seq $local_numdirs) ; do
6272                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6273                         for j in $(seq $local_numfiles) ; do
6274                                 touch $local_tdir/dir$i/file$j
6275                         done
6276                 done
6277         fi
6278 }
6279
6280 setup_56_special() {
6281         local local_tdir=$1
6282         local local_numfiles=$2
6283         local local_numdirs=$3
6284
6285         setup_56 $local_tdir $local_numfiles $local_numdirs
6286
6287         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6288                 for i in $(seq $local_numfiles) ; do
6289                         mknod $local_tdir/loop${i}b b 7 $i
6290                         mknod $local_tdir/null${i}c c 1 3
6291                         ln -s $local_tdir/file1 $local_tdir/link${i}
6292                 done
6293                 for i in $(seq $local_numdirs) ; do
6294                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6295                         mknod $local_tdir/dir$i/null${i}c c 1 3
6296                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6297                 done
6298         fi
6299 }
6300
6301 test_56g() {
6302         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6303         local expected=$(($NUMDIRS + 2))
6304
6305         setup_56 $dir $NUMFILES $NUMDIRS
6306
6307         # test lfs find with -name
6308         for i in $(seq $NUMFILES) ; do
6309                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6310
6311                 [ $nums -eq $expected ] ||
6312                         error "lfs find -name '*$i' $dir wrong: "\
6313                               "found $nums, expected $expected"
6314         done
6315 }
6316 run_test 56g "check lfs find -name"
6317
6318 test_56h() {
6319         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6320         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6321
6322         setup_56 $dir $NUMFILES $NUMDIRS
6323
6324         # test lfs find with ! -name
6325         for i in $(seq $NUMFILES) ; do
6326                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6327
6328                 [ $nums -eq $expected ] ||
6329                         error "lfs find ! -name '*$i' $dir wrong: "\
6330                               "found $nums, expected $expected"
6331         done
6332 }
6333 run_test 56h "check lfs find ! -name"
6334
6335 test_56i() {
6336         local dir=$DIR/$tdir
6337
6338         test_mkdir $dir
6339
6340         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6341         local out=$($cmd)
6342
6343         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6344 }
6345 run_test 56i "check 'lfs find -ost UUID' skips directories"
6346
6347 test_56j() {
6348         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6349
6350         setup_56_special $dir $NUMFILES $NUMDIRS
6351
6352         local expected=$((NUMDIRS + 1))
6353         local cmd="$LFS find -type d $dir"
6354         local nums=$($cmd | wc -l)
6355
6356         [ $nums -eq $expected ] ||
6357                 error "'$cmd' wrong: found $nums, expected $expected"
6358 }
6359 run_test 56j "check lfs find -type d"
6360
6361 test_56k() {
6362         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6363
6364         setup_56_special $dir $NUMFILES $NUMDIRS
6365
6366         local expected=$(((NUMDIRS + 1) * NUMFILES))
6367         local cmd="$LFS find -type f $dir"
6368         local nums=$($cmd | wc -l)
6369
6370         [ $nums -eq $expected ] ||
6371                 error "'$cmd' wrong: found $nums, expected $expected"
6372 }
6373 run_test 56k "check lfs find -type f"
6374
6375 test_56l() {
6376         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6377
6378         setup_56_special $dir $NUMFILES $NUMDIRS
6379
6380         local expected=$((NUMDIRS + NUMFILES))
6381         local cmd="$LFS find -type b $dir"
6382         local nums=$($cmd | wc -l)
6383
6384         [ $nums -eq $expected ] ||
6385                 error "'$cmd' wrong: found $nums, expected $expected"
6386 }
6387 run_test 56l "check lfs find -type b"
6388
6389 test_56m() {
6390         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6391
6392         setup_56_special $dir $NUMFILES $NUMDIRS
6393
6394         local expected=$((NUMDIRS + NUMFILES))
6395         local cmd="$LFS find -type c $dir"
6396         local nums=$($cmd | wc -l)
6397         [ $nums -eq $expected ] ||
6398                 error "'$cmd' wrong: found $nums, expected $expected"
6399 }
6400 run_test 56m "check lfs find -type c"
6401
6402 test_56n() {
6403         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6404         setup_56_special $dir $NUMFILES $NUMDIRS
6405
6406         local expected=$((NUMDIRS + NUMFILES))
6407         local cmd="$LFS find -type l $dir"
6408         local nums=$($cmd | wc -l)
6409
6410         [ $nums -eq $expected ] ||
6411                 error "'$cmd' wrong: found $nums, expected $expected"
6412 }
6413 run_test 56n "check lfs find -type l"
6414
6415 test_56o() {
6416         local dir=$DIR/$tdir
6417
6418         setup_56 $dir $NUMFILES $NUMDIRS
6419         utime $dir/file1 > /dev/null || error "utime (1)"
6420         utime $dir/file2 > /dev/null || error "utime (2)"
6421         utime $dir/dir1 > /dev/null || error "utime (3)"
6422         utime $dir/dir2 > /dev/null || error "utime (4)"
6423         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6424         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6425
6426         local expected=4
6427         local nums=$($LFS find -mtime +0 $dir | wc -l)
6428
6429         [ $nums -eq $expected ] ||
6430                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6431
6432         expected=12
6433         cmd="$LFS find -mtime 0 $dir"
6434         nums=$($cmd | wc -l)
6435         [ $nums -eq $expected ] ||
6436                 error "'$cmd' wrong: found $nums, expected $expected"
6437 }
6438 run_test 56o "check lfs find -mtime for old files"
6439
6440 test_56ob() {
6441         local dir=$DIR/$tdir
6442         local expected=1
6443         local count=0
6444
6445         # just to make sure there is something that won't be found
6446         test_mkdir $dir
6447         touch $dir/$tfile.now
6448
6449         for age in year week day hour min; do
6450                 count=$((count + 1))
6451
6452                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6453                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6454                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6455
6456                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6457                 local nums=$($cmd | wc -l)
6458                 [ $nums -eq $expected ] ||
6459                         error "'$cmd' wrong: found $nums, expected $expected"
6460
6461                 cmd="$LFS find $dir -atime $count${age:0:1}"
6462                 nums=$($cmd | wc -l)
6463                 [ $nums -eq $expected ] ||
6464                         error "'$cmd' wrong: found $nums, expected $expected"
6465         done
6466
6467         sleep 2
6468         cmd="$LFS find $dir -ctime +1s -type f"
6469         nums=$($cmd | wc -l)
6470         (( $nums == $count * 2 + 1)) ||
6471                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6472 }
6473 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6474
6475 test_newerXY_base() {
6476         local x=$1
6477         local y=$2
6478         local dir=$DIR/$tdir
6479         local ref
6480         local negref
6481
6482         if [ $y == "t" ]; then
6483                 if [ $x == "b" ]; then
6484                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6485                 else
6486                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6487                 fi
6488         else
6489                 ref=$DIR/$tfile.newer.$x$y
6490                 touch $ref || error "touch $ref failed"
6491         fi
6492
6493         echo "before = $ref"
6494         sleep 2
6495         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6496         sleep 2
6497         if [ $y == "t" ]; then
6498                 if [ $x == "b" ]; then
6499                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6500                 else
6501                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6502                 fi
6503         else
6504                 negref=$DIR/$tfile.negnewer.$x$y
6505                 touch $negref || error "touch $negref failed"
6506         fi
6507
6508         echo "after = $negref"
6509         local cmd="$LFS find $dir -newer$x$y $ref"
6510         local nums=$(eval $cmd | wc -l)
6511         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6512
6513         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6514                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6515
6516         cmd="$LFS find $dir ! -newer$x$y $negref"
6517         nums=$(eval $cmd | wc -l)
6518         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6519                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6520
6521         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6522         nums=$(eval $cmd | wc -l)
6523         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6524                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6525
6526         rm -rf $DIR/*
6527 }
6528
6529 test_56oc() {
6530         test_newerXY_base "a" "a"
6531         test_newerXY_base "a" "m"
6532         test_newerXY_base "a" "c"
6533         test_newerXY_base "m" "a"
6534         test_newerXY_base "m" "m"
6535         test_newerXY_base "m" "c"
6536         test_newerXY_base "c" "a"
6537         test_newerXY_base "c" "m"
6538         test_newerXY_base "c" "c"
6539
6540         [[ -n "$sles_version" ]] &&
6541                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6542
6543         test_newerXY_base "a" "t"
6544         test_newerXY_base "m" "t"
6545         test_newerXY_base "c" "t"
6546
6547         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6548            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6549                 ! btime_supported && echo "btime unsupported" && return 0
6550
6551         test_newerXY_base "b" "b"
6552         test_newerXY_base "b" "t"
6553 }
6554 run_test 56oc "check lfs find -newerXY work"
6555
6556 btime_supported() {
6557         local dir=$DIR/$tdir
6558         local rc
6559
6560         mkdir -p $dir
6561         touch $dir/$tfile
6562         $LFS find $dir -btime -1d -type f
6563         rc=$?
6564         rm -rf $dir
6565         return $rc
6566 }
6567
6568 test_56od() {
6569         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6570                 ! btime_supported && skip "btime unsupported on MDS"
6571
6572         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6573                 ! btime_supported && skip "btime unsupported on clients"
6574
6575         local dir=$DIR/$tdir
6576         local ref=$DIR/$tfile.ref
6577         local negref=$DIR/$tfile.negref
6578
6579         mkdir $dir || error "mkdir $dir failed"
6580         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6581         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6582         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6583         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6584         touch $ref || error "touch $ref failed"
6585         # sleep 3 seconds at least
6586         sleep 3
6587
6588         local before=$(do_facet mds1 date +%s)
6589         local skew=$(($(date +%s) - before + 1))
6590
6591         if (( skew < 0 && skew > -5 )); then
6592                 sleep $((0 - skew + 1))
6593                 skew=0
6594         fi
6595
6596         # Set the dir stripe params to limit files all on MDT0,
6597         # otherwise we need to calc the max clock skew between
6598         # the client and MDTs.
6599         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6600         sleep 2
6601         touch $negref || error "touch $negref failed"
6602
6603         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6604         local nums=$($cmd | wc -l)
6605         local expected=$(((NUMFILES + 1) * NUMDIRS))
6606
6607         [ $nums -eq $expected ] ||
6608                 error "'$cmd' wrong: found $nums, expected $expected"
6609
6610         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6611         nums=$($cmd | wc -l)
6612         expected=$((NUMFILES + 1))
6613         [ $nums -eq $expected ] ||
6614                 error "'$cmd' wrong: found $nums, expected $expected"
6615
6616         [ $skew -lt 0 ] && return
6617
6618         local after=$(do_facet mds1 date +%s)
6619         local age=$((after - before + 1 + skew))
6620
6621         cmd="$LFS find $dir -btime -${age}s -type f"
6622         nums=$($cmd | wc -l)
6623         expected=$(((NUMFILES + 1) * NUMDIRS))
6624
6625         echo "Clock skew between client and server: $skew, age:$age"
6626         [ $nums -eq $expected ] ||
6627                 error "'$cmd' wrong: found $nums, expected $expected"
6628
6629         expected=$(($NUMDIRS + 1))
6630         cmd="$LFS find $dir -btime -${age}s -type d"
6631         nums=$($cmd | wc -l)
6632         [ $nums -eq $expected ] ||
6633                 error "'$cmd' wrong: found $nums, expected $expected"
6634         rm -f $ref $negref || error "Failed to remove $ref $negref"
6635 }
6636 run_test 56od "check lfs find -btime with units"
6637
6638 test_56p() {
6639         [ $RUNAS_ID -eq $UID ] &&
6640                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6641
6642         local dir=$DIR/$tdir
6643
6644         setup_56 $dir $NUMFILES $NUMDIRS
6645         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6646
6647         local expected=$NUMFILES
6648         local cmd="$LFS find -uid $RUNAS_ID $dir"
6649         local nums=$($cmd | wc -l)
6650
6651         [ $nums -eq $expected ] ||
6652                 error "'$cmd' wrong: found $nums, expected $expected"
6653
6654         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6655         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6656         nums=$($cmd | wc -l)
6657         [ $nums -eq $expected ] ||
6658                 error "'$cmd' wrong: found $nums, expected $expected"
6659 }
6660 run_test 56p "check lfs find -uid and ! -uid"
6661
6662 test_56q() {
6663         [ $RUNAS_ID -eq $UID ] &&
6664                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6665
6666         local dir=$DIR/$tdir
6667
6668         setup_56 $dir $NUMFILES $NUMDIRS
6669         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6670
6671         local expected=$NUMFILES
6672         local cmd="$LFS find -gid $RUNAS_GID $dir"
6673         local nums=$($cmd | wc -l)
6674
6675         [ $nums -eq $expected ] ||
6676                 error "'$cmd' wrong: found $nums, expected $expected"
6677
6678         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6679         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6680         nums=$($cmd | wc -l)
6681         [ $nums -eq $expected ] ||
6682                 error "'$cmd' wrong: found $nums, expected $expected"
6683 }
6684 run_test 56q "check lfs find -gid and ! -gid"
6685
6686 test_56r() {
6687         local dir=$DIR/$tdir
6688
6689         setup_56 $dir $NUMFILES $NUMDIRS
6690
6691         local expected=12
6692         local cmd="$LFS find -size 0 -type f -lazy $dir"
6693         local nums=$($cmd | wc -l)
6694
6695         [ $nums -eq $expected ] ||
6696                 error "'$cmd' wrong: found $nums, expected $expected"
6697         cmd="$LFS find -size 0 -type f $dir"
6698         nums=$($cmd | wc -l)
6699         [ $nums -eq $expected ] ||
6700                 error "'$cmd' wrong: found $nums, expected $expected"
6701
6702         expected=0
6703         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6704         nums=$($cmd | wc -l)
6705         [ $nums -eq $expected ] ||
6706                 error "'$cmd' wrong: found $nums, expected $expected"
6707         cmd="$LFS find ! -size 0 -type f $dir"
6708         nums=$($cmd | wc -l)
6709         [ $nums -eq $expected ] ||
6710                 error "'$cmd' wrong: found $nums, expected $expected"
6711
6712         echo "test" > $dir/$tfile
6713         echo "test2" > $dir/$tfile.2 && sync
6714         expected=1
6715         cmd="$LFS find -size 5 -type f -lazy $dir"
6716         nums=$($cmd | wc -l)
6717         [ $nums -eq $expected ] ||
6718                 error "'$cmd' wrong: found $nums, expected $expected"
6719         cmd="$LFS find -size 5 -type f $dir"
6720         nums=$($cmd | wc -l)
6721         [ $nums -eq $expected ] ||
6722                 error "'$cmd' wrong: found $nums, expected $expected"
6723
6724         expected=1
6725         cmd="$LFS find -size +5 -type f -lazy $dir"
6726         nums=$($cmd | wc -l)
6727         [ $nums -eq $expected ] ||
6728                 error "'$cmd' wrong: found $nums, expected $expected"
6729         cmd="$LFS find -size +5 -type f $dir"
6730         nums=$($cmd | wc -l)
6731         [ $nums -eq $expected ] ||
6732                 error "'$cmd' wrong: found $nums, expected $expected"
6733
6734         expected=2
6735         cmd="$LFS find -size +0 -type f -lazy $dir"
6736         nums=$($cmd | wc -l)
6737         [ $nums -eq $expected ] ||
6738                 error "'$cmd' wrong: found $nums, expected $expected"
6739         cmd="$LFS find -size +0 -type f $dir"
6740         nums=$($cmd | wc -l)
6741         [ $nums -eq $expected ] ||
6742                 error "'$cmd' wrong: found $nums, expected $expected"
6743
6744         expected=2
6745         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6746         nums=$($cmd | wc -l)
6747         [ $nums -eq $expected ] ||
6748                 error "'$cmd' wrong: found $nums, expected $expected"
6749         cmd="$LFS find ! -size -5 -type f $dir"
6750         nums=$($cmd | wc -l)
6751         [ $nums -eq $expected ] ||
6752                 error "'$cmd' wrong: found $nums, expected $expected"
6753
6754         expected=12
6755         cmd="$LFS find -size -5 -type f -lazy $dir"
6756         nums=$($cmd | wc -l)
6757         [ $nums -eq $expected ] ||
6758                 error "'$cmd' wrong: found $nums, expected $expected"
6759         cmd="$LFS find -size -5 -type f $dir"
6760         nums=$($cmd | wc -l)
6761         [ $nums -eq $expected ] ||
6762                 error "'$cmd' wrong: found $nums, expected $expected"
6763 }
6764 run_test 56r "check lfs find -size works"
6765
6766 test_56ra_sub() {
6767         local expected=$1
6768         local glimpses=$2
6769         local cmd="$3"
6770
6771         cancel_lru_locks $OSC
6772
6773         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6774         local nums=$($cmd | wc -l)
6775
6776         [ $nums -eq $expected ] ||
6777                 error "'$cmd' wrong: found $nums, expected $expected"
6778
6779         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6780
6781         if (( rpcs_before + glimpses != rpcs_after )); then
6782                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6783                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6784
6785                 if [[ $glimpses == 0 ]]; then
6786                         error "'$cmd' should not send glimpse RPCs to OST"
6787                 else
6788                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6789                 fi
6790         fi
6791 }
6792
6793 test_56ra() {
6794         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6795                 skip "MDS < 2.12.58 doesn't return LSOM data"
6796         local dir=$DIR/$tdir
6797         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6798
6799         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6800
6801         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6802         $LCTL set_param -n llite.*.statahead_agl=0
6803         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6804
6805         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6806         # open and close all files to ensure LSOM is updated
6807         cancel_lru_locks $OSC
6808         find $dir -type f | xargs cat > /dev/null
6809
6810         #   expect_found  glimpse_rpcs  command_to_run
6811         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6812         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6813         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6814         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6815
6816         echo "test" > $dir/$tfile
6817         echo "test2" > $dir/$tfile.2 && sync
6818         cancel_lru_locks $OSC
6819         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6820
6821         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6822         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6823         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6824         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6825
6826         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6827         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6828         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6829         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6830         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6831         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6832 }
6833 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6834
6835 test_56rb() {
6836         local dir=$DIR/$tdir
6837         local tmp=$TMP/$tfile.log
6838         local mdt_idx;
6839
6840         test_mkdir -p $dir || error "failed to mkdir $dir"
6841         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6842                 error "failed to setstripe $dir/$tfile"
6843         mdt_idx=$($LFS getdirstripe -i $dir)
6844         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6845
6846         stack_trap "rm -f $tmp" EXIT
6847         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6848         ! grep -q obd_uuid $tmp ||
6849                 error "failed to find --size +100K --ost 0 $dir"
6850         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6851         ! grep -q obd_uuid $tmp ||
6852                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6853 }
6854 run_test 56rb "check lfs find --size --ost/--mdt works"
6855
6856 test_56rc() {
6857         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6858         local dir=$DIR/$tdir
6859         local found
6860
6861         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6862         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6863         (( $MDSCOUNT > 2 )) &&
6864                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6865         mkdir $dir/$tdir-{1..10}
6866         touch $dir/$tfile-{1..10}
6867
6868         found=$($LFS find $dir --mdt-count 2 | wc -l)
6869         expect=11
6870         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6871
6872         found=$($LFS find $dir -T +1 | wc -l)
6873         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6874         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6875
6876         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6877         expect=11
6878         (( $found == $expect )) || error "found $found all_char, expect $expect"
6879
6880         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6881         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6882         (( $found == $expect )) || error "found $found all_char, expect $expect"
6883 }
6884 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6885
6886 test_56s() { # LU-611 #LU-9369
6887         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6888
6889         local dir=$DIR/$tdir
6890         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6891
6892         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6893         for i in $(seq $NUMDIRS); do
6894                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6895         done
6896
6897         local expected=$NUMDIRS
6898         local cmd="$LFS find -c $OSTCOUNT $dir"
6899         local nums=$($cmd | wc -l)
6900
6901         [ $nums -eq $expected ] || {
6902                 $LFS getstripe -R $dir
6903                 error "'$cmd' wrong: found $nums, expected $expected"
6904         }
6905
6906         expected=$((NUMDIRS + onestripe))
6907         cmd="$LFS find -stripe-count +0 -type f $dir"
6908         nums=$($cmd | wc -l)
6909         [ $nums -eq $expected ] || {
6910                 $LFS getstripe -R $dir
6911                 error "'$cmd' wrong: found $nums, expected $expected"
6912         }
6913
6914         expected=$onestripe
6915         cmd="$LFS find -stripe-count 1 -type f $dir"
6916         nums=$($cmd | wc -l)
6917         [ $nums -eq $expected ] || {
6918                 $LFS getstripe -R $dir
6919                 error "'$cmd' wrong: found $nums, expected $expected"
6920         }
6921
6922         cmd="$LFS find -stripe-count -2 -type f $dir"
6923         nums=$($cmd | wc -l)
6924         [ $nums -eq $expected ] || {
6925                 $LFS getstripe -R $dir
6926                 error "'$cmd' wrong: found $nums, expected $expected"
6927         }
6928
6929         expected=0
6930         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6931         nums=$($cmd | wc -l)
6932         [ $nums -eq $expected ] || {
6933                 $LFS getstripe -R $dir
6934                 error "'$cmd' wrong: found $nums, expected $expected"
6935         }
6936 }
6937 run_test 56s "check lfs find -stripe-count works"
6938
6939 test_56t() { # LU-611 #LU-9369
6940         local dir=$DIR/$tdir
6941
6942         setup_56 $dir 0 $NUMDIRS
6943         for i in $(seq $NUMDIRS); do
6944                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6945         done
6946
6947         local expected=$NUMDIRS
6948         local cmd="$LFS find -S 8M $dir"
6949         local nums=$($cmd | wc -l)
6950
6951         [ $nums -eq $expected ] || {
6952                 $LFS getstripe -R $dir
6953                 error "'$cmd' wrong: found $nums, expected $expected"
6954         }
6955         rm -rf $dir
6956
6957         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6958
6959         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6960
6961         expected=$(((NUMDIRS + 1) * NUMFILES))
6962         cmd="$LFS find -stripe-size 512k -type f $dir"
6963         nums=$($cmd | wc -l)
6964         [ $nums -eq $expected ] ||
6965                 error "'$cmd' wrong: found $nums, expected $expected"
6966
6967         cmd="$LFS find -stripe-size +320k -type f $dir"
6968         nums=$($cmd | wc -l)
6969         [ $nums -eq $expected ] ||
6970                 error "'$cmd' wrong: found $nums, expected $expected"
6971
6972         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6973         cmd="$LFS find -stripe-size +200k -type f $dir"
6974         nums=$($cmd | wc -l)
6975         [ $nums -eq $expected ] ||
6976                 error "'$cmd' wrong: found $nums, expected $expected"
6977
6978         cmd="$LFS find -stripe-size -640k -type f $dir"
6979         nums=$($cmd | wc -l)
6980         [ $nums -eq $expected ] ||
6981                 error "'$cmd' wrong: found $nums, expected $expected"
6982
6983         expected=4
6984         cmd="$LFS find -stripe-size 256k -type f $dir"
6985         nums=$($cmd | wc -l)
6986         [ $nums -eq $expected ] ||
6987                 error "'$cmd' wrong: found $nums, expected $expected"
6988
6989         cmd="$LFS find -stripe-size -320k -type f $dir"
6990         nums=$($cmd | wc -l)
6991         [ $nums -eq $expected ] ||
6992                 error "'$cmd' wrong: found $nums, expected $expected"
6993
6994         expected=0
6995         cmd="$LFS find -stripe-size 1024k -type f $dir"
6996         nums=$($cmd | wc -l)
6997         [ $nums -eq $expected ] ||
6998                 error "'$cmd' wrong: found $nums, expected $expected"
6999 }
7000 run_test 56t "check lfs find -stripe-size works"
7001
7002 test_56u() { # LU-611
7003         local dir=$DIR/$tdir
7004
7005         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7006
7007         if [[ $OSTCOUNT -gt 1 ]]; then
7008                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7009                 onestripe=4
7010         else
7011                 onestripe=0
7012         fi
7013
7014         local expected=$(((NUMDIRS + 1) * NUMFILES))
7015         local cmd="$LFS find -stripe-index 0 -type f $dir"
7016         local nums=$($cmd | wc -l)
7017
7018         [ $nums -eq $expected ] ||
7019                 error "'$cmd' wrong: found $nums, expected $expected"
7020
7021         expected=$onestripe
7022         cmd="$LFS find -stripe-index 1 -type f $dir"
7023         nums=$($cmd | wc -l)
7024         [ $nums -eq $expected ] ||
7025                 error "'$cmd' wrong: found $nums, expected $expected"
7026
7027         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7028         nums=$($cmd | wc -l)
7029         [ $nums -eq $expected ] ||
7030                 error "'$cmd' wrong: found $nums, expected $expected"
7031
7032         expected=0
7033         # This should produce an error and not return any files
7034         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7035         nums=$($cmd 2>/dev/null | wc -l)
7036         [ $nums -eq $expected ] ||
7037                 error "'$cmd' wrong: found $nums, expected $expected"
7038
7039         if [[ $OSTCOUNT -gt 1 ]]; then
7040                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7041                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7042                 nums=$($cmd | wc -l)
7043                 [ $nums -eq $expected ] ||
7044                         error "'$cmd' wrong: found $nums, expected $expected"
7045         fi
7046 }
7047 run_test 56u "check lfs find -stripe-index works"
7048
7049 test_56v() {
7050         local mdt_idx=0
7051         local dir=$DIR/$tdir
7052
7053         setup_56 $dir $NUMFILES $NUMDIRS
7054
7055         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7056         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7057
7058         for file in $($LFS find -m $UUID $dir); do
7059                 file_midx=$($LFS getstripe -m $file)
7060                 [ $file_midx -eq $mdt_idx ] ||
7061                         error "lfs find -m $UUID != getstripe -m $file_midx"
7062         done
7063 }
7064 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7065
7066 test_56w() {
7067         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7069
7070         local dir=$DIR/$tdir
7071
7072         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7073
7074         local stripe_size=$($LFS getstripe -S -d $dir) ||
7075                 error "$LFS getstripe -S -d $dir failed"
7076         stripe_size=${stripe_size%% *}
7077
7078         local file_size=$((stripe_size * OSTCOUNT))
7079         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7080         local required_space=$((file_num * file_size))
7081         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7082                            head -n1)
7083         [[ $free_space -le $((required_space / 1024)) ]] &&
7084                 skip_env "need $required_space, have $free_space kbytes"
7085
7086         local dd_bs=65536
7087         local dd_count=$((file_size / dd_bs))
7088
7089         # write data into the files
7090         local i
7091         local j
7092         local file
7093
7094         for i in $(seq $NUMFILES); do
7095                 file=$dir/file$i
7096                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7097                         error "write data into $file failed"
7098         done
7099         for i in $(seq $NUMDIRS); do
7100                 for j in $(seq $NUMFILES); do
7101                         file=$dir/dir$i/file$j
7102                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7103                                 error "write data into $file failed"
7104                 done
7105         done
7106
7107         # $LFS_MIGRATE will fail if hard link migration is unsupported
7108         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7109                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7110                         error "creating links to $dir/dir1/file1 failed"
7111         fi
7112
7113         local expected=-1
7114
7115         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7116
7117         # lfs_migrate file
7118         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7119
7120         echo "$cmd"
7121         eval $cmd || error "$cmd failed"
7122
7123         check_stripe_count $dir/file1 $expected
7124
7125         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7126         then
7127                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7128                 # OST 1 if it is on OST 0. This file is small enough to
7129                 # be on only one stripe.
7130                 file=$dir/migr_1_ost
7131                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7132                         error "write data into $file failed"
7133                 local obdidx=$($LFS getstripe -i $file)
7134                 local oldmd5=$(md5sum $file)
7135                 local newobdidx=0
7136
7137                 [[ $obdidx -eq 0 ]] && newobdidx=1
7138                 cmd="$LFS migrate -i $newobdidx $file"
7139                 echo $cmd
7140                 eval $cmd || error "$cmd failed"
7141
7142                 local realobdix=$($LFS getstripe -i $file)
7143                 local newmd5=$(md5sum $file)
7144
7145                 [[ $newobdidx -ne $realobdix ]] &&
7146                         error "new OST is different (was=$obdidx, "\
7147                               "wanted=$newobdidx, got=$realobdix)"
7148                 [[ "$oldmd5" != "$newmd5" ]] &&
7149                         error "md5sum differ: $oldmd5, $newmd5"
7150         fi
7151
7152         # lfs_migrate dir
7153         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7154         echo "$cmd"
7155         eval $cmd || error "$cmd failed"
7156
7157         for j in $(seq $NUMFILES); do
7158                 check_stripe_count $dir/dir1/file$j $expected
7159         done
7160
7161         # lfs_migrate works with lfs find
7162         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7163              $LFS_MIGRATE -y -c $expected"
7164         echo "$cmd"
7165         eval $cmd || error "$cmd failed"
7166
7167         for i in $(seq 2 $NUMFILES); do
7168                 check_stripe_count $dir/file$i $expected
7169         done
7170         for i in $(seq 2 $NUMDIRS); do
7171                 for j in $(seq $NUMFILES); do
7172                 check_stripe_count $dir/dir$i/file$j $expected
7173                 done
7174         done
7175 }
7176 run_test 56w "check lfs_migrate -c stripe_count works"
7177
7178 test_56wb() {
7179         local file1=$DIR/$tdir/file1
7180         local create_pool=false
7181         local initial_pool=$($LFS getstripe -p $DIR)
7182         local pool_list=()
7183         local pool=""
7184
7185         echo -n "Creating test dir..."
7186         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7187         echo "done."
7188
7189         echo -n "Creating test file..."
7190         touch $file1 || error "cannot create file"
7191         echo "done."
7192
7193         echo -n "Detecting existing pools..."
7194         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7195
7196         if [ ${#pool_list[@]} -gt 0 ]; then
7197                 echo "${pool_list[@]}"
7198                 for thispool in "${pool_list[@]}"; do
7199                         if [[ -z "$initial_pool" ||
7200                               "$initial_pool" != "$thispool" ]]; then
7201                                 pool="$thispool"
7202                                 echo "Using existing pool '$pool'"
7203                                 break
7204                         fi
7205                 done
7206         else
7207                 echo "none detected."
7208         fi
7209         if [ -z "$pool" ]; then
7210                 pool=${POOL:-testpool}
7211                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7212                 echo -n "Creating pool '$pool'..."
7213                 create_pool=true
7214                 pool_add $pool &> /dev/null ||
7215                         error "pool_add failed"
7216                 echo "done."
7217
7218                 echo -n "Adding target to pool..."
7219                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7220                         error "pool_add_targets failed"
7221                 echo "done."
7222         fi
7223
7224         echo -n "Setting pool using -p option..."
7225         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7226                 error "migrate failed rc = $?"
7227         echo "done."
7228
7229         echo -n "Verifying test file is in pool after migrating..."
7230         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7231                 error "file was not migrated to pool $pool"
7232         echo "done."
7233
7234         echo -n "Removing test file from pool '$pool'..."
7235         # "lfs migrate $file" won't remove the file from the pool
7236         # until some striping information is changed.
7237         $LFS migrate -c 1 $file1 &> /dev/null ||
7238                 error "cannot remove from pool"
7239         [ "$($LFS getstripe -p $file1)" ] &&
7240                 error "pool still set"
7241         echo "done."
7242
7243         echo -n "Setting pool using --pool option..."
7244         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7245                 error "migrate failed rc = $?"
7246         echo "done."
7247
7248         # Clean up
7249         rm -f $file1
7250         if $create_pool; then
7251                 destroy_test_pools 2> /dev/null ||
7252                         error "destroy test pools failed"
7253         fi
7254 }
7255 run_test 56wb "check lfs_migrate pool support"
7256
7257 test_56wc() {
7258         local file1="$DIR/$tdir/file1"
7259         local parent_ssize
7260         local parent_scount
7261         local cur_ssize
7262         local cur_scount
7263         local orig_ssize
7264
7265         echo -n "Creating test dir..."
7266         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7267         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7268                 error "cannot set stripe by '-S 1M -c 1'"
7269         echo "done"
7270
7271         echo -n "Setting initial stripe for test file..."
7272         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7273                 error "cannot set stripe"
7274         cur_ssize=$($LFS getstripe -S "$file1")
7275         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7276         echo "done."
7277
7278         # File currently set to -S 512K -c 1
7279
7280         # Ensure -c and -S options are rejected when -R is set
7281         echo -n "Verifying incompatible options are detected..."
7282         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7283                 error "incompatible -c and -R options not detected"
7284         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7285                 error "incompatible -S and -R options not detected"
7286         echo "done."
7287
7288         # Ensure unrecognized options are passed through to 'lfs migrate'
7289         echo -n "Verifying -S option is passed through to lfs migrate..."
7290         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7291                 error "migration failed"
7292         cur_ssize=$($LFS getstripe -S "$file1")
7293         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7294         echo "done."
7295
7296         # File currently set to -S 1M -c 1
7297
7298         # Ensure long options are supported
7299         echo -n "Verifying long options supported..."
7300         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7301                 error "long option without argument not supported"
7302         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7303                 error "long option with argument not supported"
7304         cur_ssize=$($LFS getstripe -S "$file1")
7305         [ $cur_ssize -eq 524288 ] ||
7306                 error "migrate --stripe-size $cur_ssize != 524288"
7307         echo "done."
7308
7309         # File currently set to -S 512K -c 1
7310
7311         if [ "$OSTCOUNT" -gt 1 ]; then
7312                 echo -n "Verifying explicit stripe count can be set..."
7313                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7314                         error "migrate failed"
7315                 cur_scount=$($LFS getstripe -c "$file1")
7316                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7317                 echo "done."
7318         fi
7319
7320         # File currently set to -S 512K -c 1 or -S 512K -c 2
7321
7322         # Ensure parent striping is used if -R is set, and no stripe
7323         # count or size is specified
7324         echo -n "Setting stripe for parent directory..."
7325         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7326                 error "cannot set stripe '-S 2M -c 1'"
7327         echo "done."
7328
7329         echo -n "Verifying restripe option uses parent stripe settings..."
7330         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7331         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7332         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7333                 error "migrate failed"
7334         cur_ssize=$($LFS getstripe -S "$file1")
7335         [ $cur_ssize -eq $parent_ssize ] ||
7336                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7337         cur_scount=$($LFS getstripe -c "$file1")
7338         [ $cur_scount -eq $parent_scount ] ||
7339                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7340         echo "done."
7341
7342         # File currently set to -S 1M -c 1
7343
7344         # Ensure striping is preserved if -R is not set, and no stripe
7345         # count or size is specified
7346         echo -n "Verifying striping size preserved when not specified..."
7347         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7348         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7349                 error "cannot set stripe on parent directory"
7350         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7351                 error "migrate failed"
7352         cur_ssize=$($LFS getstripe -S "$file1")
7353         [ $cur_ssize -eq $orig_ssize ] ||
7354                 error "migrate by default $cur_ssize != $orig_ssize"
7355         echo "done."
7356
7357         # Ensure file name properly detected when final option has no argument
7358         echo -n "Verifying file name properly detected..."
7359         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7360                 error "file name interpreted as option argument"
7361         echo "done."
7362
7363         # Clean up
7364         rm -f "$file1"
7365 }
7366 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7367
7368 test_56wd() {
7369         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7370
7371         local file1=$DIR/$tdir/file1
7372
7373         echo -n "Creating test dir..."
7374         test_mkdir $DIR/$tdir || error "cannot create dir"
7375         echo "done."
7376
7377         echo -n "Creating test file..."
7378         touch $file1
7379         echo "done."
7380
7381         # Ensure 'lfs migrate' will fail by using a non-existent option,
7382         # and make sure rsync is not called to recover
7383         echo -n "Make sure --no-rsync option works..."
7384         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7385                 grep -q 'refusing to fall back to rsync' ||
7386                 error "rsync was called with --no-rsync set"
7387         echo "done."
7388
7389         # Ensure rsync is called without trying 'lfs migrate' first
7390         echo -n "Make sure --rsync option works..."
7391         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7392                 grep -q 'falling back to rsync' &&
7393                 error "lfs migrate was called with --rsync set"
7394         echo "done."
7395
7396         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7397         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7398                 grep -q 'at the same time' ||
7399                 error "--rsync and --no-rsync accepted concurrently"
7400         echo "done."
7401
7402         # Clean up
7403         rm -f $file1
7404 }
7405 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7406
7407 test_56we() {
7408         local td=$DIR/$tdir
7409         local tf=$td/$tfile
7410
7411         test_mkdir $td || error "cannot create $td"
7412         touch $tf || error "cannot touch $tf"
7413
7414         echo -n "Make sure --non-direct|-D works..."
7415         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7416                 grep -q "lfs migrate --non-direct" ||
7417                 error "--non-direct option cannot work correctly"
7418         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7419                 grep -q "lfs migrate -D" ||
7420                 error "-D option cannot work correctly"
7421         echo "done."
7422 }
7423 run_test 56we "check lfs_migrate --non-direct|-D support"
7424
7425 test_56x() {
7426         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7427         check_swap_layouts_support
7428
7429         local dir=$DIR/$tdir
7430         local ref1=/etc/passwd
7431         local file1=$dir/file1
7432
7433         test_mkdir $dir || error "creating dir $dir"
7434         $LFS setstripe -c 2 $file1
7435         cp $ref1 $file1
7436         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7437         stripe=$($LFS getstripe -c $file1)
7438         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7439         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7440
7441         # clean up
7442         rm -f $file1
7443 }
7444 run_test 56x "lfs migration support"
7445
7446 test_56xa() {
7447         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7448         check_swap_layouts_support
7449
7450         local dir=$DIR/$tdir/$testnum
7451
7452         test_mkdir -p $dir
7453
7454         local ref1=/etc/passwd
7455         local file1=$dir/file1
7456
7457         $LFS setstripe -c 2 $file1
7458         cp $ref1 $file1
7459         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7460
7461         local stripe=$($LFS getstripe -c $file1)
7462
7463         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7464         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7465
7466         # clean up
7467         rm -f $file1
7468 }
7469 run_test 56xa "lfs migration --block support"
7470
7471 check_migrate_links() {
7472         local dir="$1"
7473         local file1="$dir/file1"
7474         local begin="$2"
7475         local count="$3"
7476         local runas="$4"
7477         local total_count=$(($begin + $count - 1))
7478         local symlink_count=10
7479         local uniq_count=10
7480
7481         if [ ! -f "$file1" ]; then
7482                 echo -n "creating initial file..."
7483                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7484                         error "cannot setstripe initial file"
7485                 echo "done"
7486
7487                 echo -n "creating symlinks..."
7488                 for s in $(seq 1 $symlink_count); do
7489                         ln -s "$file1" "$dir/slink$s" ||
7490                                 error "cannot create symlinks"
7491                 done
7492                 echo "done"
7493
7494                 echo -n "creating nonlinked files..."
7495                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7496                         error "cannot create nonlinked files"
7497                 echo "done"
7498         fi
7499
7500         # create hard links
7501         if [ ! -f "$dir/file$total_count" ]; then
7502                 echo -n "creating hard links $begin:$total_count..."
7503                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7504                         /dev/null || error "cannot create hard links"
7505                 echo "done"
7506         fi
7507
7508         echo -n "checking number of hard links listed in xattrs..."
7509         local fid=$($LFS getstripe -F "$file1")
7510         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7511
7512         echo "${#paths[*]}"
7513         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7514                         skip "hard link list has unexpected size, skipping test"
7515         fi
7516         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7517                         error "link names should exceed xattrs size"
7518         fi
7519
7520         echo -n "migrating files..."
7521         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7522         local rc=$?
7523         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7524         echo "done"
7525
7526         # make sure all links have been properly migrated
7527         echo -n "verifying files..."
7528         fid=$($LFS getstripe -F "$file1") ||
7529                 error "cannot get fid for file $file1"
7530         for i in $(seq 2 $total_count); do
7531                 local fid2=$($LFS getstripe -F $dir/file$i)
7532
7533                 [ "$fid2" == "$fid" ] ||
7534                         error "migrated hard link has mismatched FID"
7535         done
7536
7537         # make sure hard links were properly detected, and migration was
7538         # performed only once for the entire link set; nonlinked files should
7539         # also be migrated
7540         local actual=$(grep -c 'done' <<< "$migrate_out")
7541         local expected=$(($uniq_count + 1))
7542
7543         [ "$actual" -eq  "$expected" ] ||
7544                 error "hard links individually migrated ($actual != $expected)"
7545
7546         # make sure the correct number of hard links are present
7547         local hardlinks=$(stat -c '%h' "$file1")
7548
7549         [ $hardlinks -eq $total_count ] ||
7550                 error "num hard links $hardlinks != $total_count"
7551         echo "done"
7552
7553         return 0
7554 }
7555
7556 test_56xb() {
7557         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7558                 skip "Need MDS version at least 2.10.55"
7559
7560         local dir="$DIR/$tdir"
7561
7562         test_mkdir "$dir" || error "cannot create dir $dir"
7563
7564         echo "testing lfs migrate mode when all links fit within xattrs"
7565         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7566
7567         echo "testing rsync mode when all links fit within xattrs"
7568         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7569
7570         echo "testing lfs migrate mode when all links do not fit within xattrs"
7571         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7572
7573         echo "testing rsync mode when all links do not fit within xattrs"
7574         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7575
7576         chown -R $RUNAS_ID $dir
7577         echo "testing non-root lfs migrate mode when not all links are in xattr"
7578         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7579
7580         # clean up
7581         rm -rf $dir
7582 }
7583 run_test 56xb "lfs migration hard link support"
7584
7585 test_56xc() {
7586         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7587
7588         local dir="$DIR/$tdir"
7589
7590         test_mkdir "$dir" || error "cannot create dir $dir"
7591
7592         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7593         echo -n "Setting initial stripe for 20MB test file..."
7594         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7595                 error "cannot setstripe 20MB file"
7596         echo "done"
7597         echo -n "Sizing 20MB test file..."
7598         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7599         echo "done"
7600         echo -n "Verifying small file autostripe count is 1..."
7601         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7602                 error "cannot migrate 20MB file"
7603         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7604                 error "cannot get stripe for $dir/20mb"
7605         [ $stripe_count -eq 1 ] ||
7606                 error "unexpected stripe count $stripe_count for 20MB file"
7607         rm -f "$dir/20mb"
7608         echo "done"
7609
7610         # Test 2: File is small enough to fit within the available space on
7611         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7612         # have at least an additional 1KB for each desired stripe for test 3
7613         echo -n "Setting stripe for 1GB test file..."
7614         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7615         echo "done"
7616         echo -n "Sizing 1GB test file..."
7617         # File size is 1GB + 3KB
7618         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7619         echo "done"
7620
7621         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7622         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7623         if (( avail > 524288 * OSTCOUNT )); then
7624                 echo -n "Migrating 1GB file..."
7625                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7626                         error "cannot migrate 1GB file"
7627                 echo "done"
7628                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7629                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7630                         error "cannot getstripe for 1GB file"
7631                 [ $stripe_count -eq 2 ] ||
7632                         error "unexpected stripe count $stripe_count != 2"
7633                 echo "done"
7634         fi
7635
7636         # Test 3: File is too large to fit within the available space on
7637         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7638         if [ $OSTCOUNT -ge 3 ]; then
7639                 # The required available space is calculated as
7640                 # file size (1GB + 3KB) / OST count (3).
7641                 local kb_per_ost=349526
7642
7643                 echo -n "Migrating 1GB file with limit..."
7644                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7645                         error "cannot migrate 1GB file with limit"
7646                 echo "done"
7647
7648                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7649                 echo -n "Verifying 1GB autostripe count with limited space..."
7650                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7651                         error "unexpected stripe count $stripe_count (min 3)"
7652                 echo "done"
7653         fi
7654
7655         # clean up
7656         rm -rf $dir
7657 }
7658 run_test 56xc "lfs migration autostripe"
7659
7660 test_56xd() {
7661         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7662
7663         local dir=$DIR/$tdir
7664         local f_mgrt=$dir/$tfile.mgrt
7665         local f_yaml=$dir/$tfile.yaml
7666         local f_copy=$dir/$tfile.copy
7667         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7668         local layout_copy="-c 2 -S 2M -i 1"
7669         local yamlfile=$dir/yamlfile
7670         local layout_before;
7671         local layout_after;
7672
7673         test_mkdir "$dir" || error "cannot create dir $dir"
7674         $LFS setstripe $layout_yaml $f_yaml ||
7675                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7676         $LFS getstripe --yaml $f_yaml > $yamlfile
7677         $LFS setstripe $layout_copy $f_copy ||
7678                 error "cannot setstripe $f_copy with layout $layout_copy"
7679         touch $f_mgrt
7680         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7681
7682         # 1. test option --yaml
7683         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7684                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7685         layout_before=$(get_layout_param $f_yaml)
7686         layout_after=$(get_layout_param $f_mgrt)
7687         [ "$layout_after" == "$layout_before" ] ||
7688                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7689
7690         # 2. test option --copy
7691         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7692                 error "cannot migrate $f_mgrt with --copy $f_copy"
7693         layout_before=$(get_layout_param $f_copy)
7694         layout_after=$(get_layout_param $f_mgrt)
7695         [ "$layout_after" == "$layout_before" ] ||
7696                 error "lfs_migrate --copy: $layout_after != $layout_before"
7697 }
7698 run_test 56xd "check lfs_migrate --yaml and --copy support"
7699
7700 test_56xe() {
7701         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7702
7703         local dir=$DIR/$tdir
7704         local f_comp=$dir/$tfile
7705         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7706         local layout_before=""
7707         local layout_after=""
7708
7709         test_mkdir "$dir" || error "cannot create dir $dir"
7710         $LFS setstripe $layout $f_comp ||
7711                 error "cannot setstripe $f_comp with layout $layout"
7712         layout_before=$(get_layout_param $f_comp)
7713         dd if=/dev/zero of=$f_comp bs=1M count=4
7714
7715         # 1. migrate a comp layout file by lfs_migrate
7716         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7717         layout_after=$(get_layout_param $f_comp)
7718         [ "$layout_before" == "$layout_after" ] ||
7719                 error "lfs_migrate: $layout_before != $layout_after"
7720
7721         # 2. migrate a comp layout file by lfs migrate
7722         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7723         layout_after=$(get_layout_param $f_comp)
7724         [ "$layout_before" == "$layout_after" ] ||
7725                 error "lfs migrate: $layout_before != $layout_after"
7726 }
7727 run_test 56xe "migrate a composite layout file"
7728
7729 test_56xf() {
7730         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7731
7732         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7733                 skip "Need server version at least 2.13.53"
7734
7735         local dir=$DIR/$tdir
7736         local f_comp=$dir/$tfile
7737         local layout="-E 1M -c1 -E -1 -c2"
7738         local fid_before=""
7739         local fid_after=""
7740
7741         test_mkdir "$dir" || error "cannot create dir $dir"
7742         $LFS setstripe $layout $f_comp ||
7743                 error "cannot setstripe $f_comp with layout $layout"
7744         fid_before=$($LFS getstripe --fid $f_comp)
7745         dd if=/dev/zero of=$f_comp bs=1M count=4
7746
7747         # 1. migrate a comp layout file to a comp layout
7748         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7749         fid_after=$($LFS getstripe --fid $f_comp)
7750         [ "$fid_before" == "$fid_after" ] ||
7751                 error "comp-to-comp migrate: $fid_before != $fid_after"
7752
7753         # 2. migrate a comp layout file to a plain layout
7754         $LFS migrate -c2 $f_comp ||
7755                 error "cannot migrate $f_comp by lfs migrate"
7756         fid_after=$($LFS getstripe --fid $f_comp)
7757         [ "$fid_before" == "$fid_after" ] ||
7758                 error "comp-to-plain migrate: $fid_before != $fid_after"
7759
7760         # 3. migrate a plain layout file to a comp layout
7761         $LFS migrate $layout $f_comp ||
7762                 error "cannot migrate $f_comp by lfs migrate"
7763         fid_after=$($LFS getstripe --fid $f_comp)
7764         [ "$fid_before" == "$fid_after" ] ||
7765                 error "plain-to-comp migrate: $fid_before != $fid_after"
7766 }
7767 run_test 56xf "FID is not lost during migration of a composite layout file"
7768
7769 check_file_ost_range() {
7770         local file="$1"
7771         shift
7772         local range="$*"
7773         local -a file_range
7774         local idx
7775
7776         file_range=($($LFS getstripe -y "$file" |
7777                 awk '/l_ost_idx:/ { print $NF }'))
7778
7779         if [[ "${#file_range[@]}" = 0 ]]; then
7780                 echo "No osts found for $file"
7781                 return 1
7782         fi
7783
7784         for idx in "${file_range[@]}"; do
7785                 [[ " $range " =~ " $idx " ]] ||
7786                         return 1
7787         done
7788
7789         return 0
7790 }
7791
7792 sub_test_56xg() {
7793         local stripe_opt="$1"
7794         local pool="$2"
7795         shift 2
7796         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7797
7798         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7799                 error "Fail to migrate $tfile on $pool"
7800         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7801                 error "$tfile is not in pool $pool"
7802         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7803                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7804 }
7805
7806 test_56xg() {
7807         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7808         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7809         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7810                 skip "Need MDS version newer than 2.14.52"
7811
7812         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7813         local -a pool_ranges=("0 0" "1 1" "0 1")
7814
7815         # init pools
7816         for i in "${!pool_names[@]}"; do
7817                 pool_add ${pool_names[$i]} ||
7818                         error "pool_add failed (pool: ${pool_names[$i]})"
7819                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7820                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7821         done
7822
7823         # init the file to migrate
7824         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7825                 error "Unable to create $tfile on OST1"
7826         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7827                 error "Unable to write on $tfile"
7828
7829         echo "1. migrate $tfile on pool ${pool_names[0]}"
7830         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7831
7832         echo "2. migrate $tfile on pool ${pool_names[2]}"
7833         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7834
7835         echo "3. migrate $tfile on pool ${pool_names[1]}"
7836         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7837
7838         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7839         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7840         echo
7841
7842         # Clean pools
7843         destroy_test_pools ||
7844                 error "pool_destroy failed"
7845 }
7846 run_test 56xg "lfs migrate pool support"
7847
7848 test_56y() {
7849         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7850                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7851
7852         local res=""
7853         local dir=$DIR/$tdir
7854         local f1=$dir/file1
7855         local f2=$dir/file2
7856
7857         test_mkdir -p $dir || error "creating dir $dir"
7858         touch $f1 || error "creating std file $f1"
7859         $MULTIOP $f2 H2c || error "creating released file $f2"
7860
7861         # a directory can be raid0, so ask only for files
7862         res=$($LFS find $dir -L raid0 -type f | wc -l)
7863         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7864
7865         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7866         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7867
7868         # only files can be released, so no need to force file search
7869         res=$($LFS find $dir -L released)
7870         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7871
7872         res=$($LFS find $dir -type f \! -L released)
7873         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7874 }
7875 run_test 56y "lfs find -L raid0|released"
7876
7877 test_56z() { # LU-4824
7878         # This checks to make sure 'lfs find' continues after errors
7879         # There are two classes of errors that should be caught:
7880         # - If multiple paths are provided, all should be searched even if one
7881         #   errors out
7882         # - If errors are encountered during the search, it should not terminate
7883         #   early
7884         local dir=$DIR/$tdir
7885         local i
7886
7887         test_mkdir $dir
7888         for i in d{0..9}; do
7889                 test_mkdir $dir/$i
7890                 touch $dir/$i/$tfile
7891         done
7892         $LFS find $DIR/non_existent_dir $dir &&
7893                 error "$LFS find did not return an error"
7894         # Make a directory unsearchable. This should NOT be the last entry in
7895         # directory order.  Arbitrarily pick the 6th entry
7896         chmod 700 $($LFS find $dir -type d | sed '6!d')
7897
7898         $RUNAS $LFS find $DIR/non_existent $dir
7899         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7900
7901         # The user should be able to see 10 directories and 9 files
7902         (( count == 19 )) ||
7903                 error "$LFS find found $count != 19 entries after error"
7904 }
7905 run_test 56z "lfs find should continue after an error"
7906
7907 test_56aa() { # LU-5937
7908         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7909
7910         local dir=$DIR/$tdir
7911
7912         mkdir $dir
7913         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7914
7915         createmany -o $dir/striped_dir/${tfile}- 1024
7916         local dirs=$($LFS find --size +8k $dir/)
7917
7918         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7919 }
7920 run_test 56aa "lfs find --size under striped dir"
7921
7922 test_56ab() { # LU-10705
7923         test_mkdir $DIR/$tdir
7924         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7925         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7926         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7927         # Flush writes to ensure valid blocks.  Need to be more thorough for
7928         # ZFS, since blocks are not allocated/returned to client immediately.
7929         sync_all_data
7930         wait_zfs_commit ost1 2
7931         cancel_lru_locks osc
7932         ls -ls $DIR/$tdir
7933
7934         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7935
7936         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7937
7938         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7939         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7940
7941         rm -f $DIR/$tdir/$tfile.[123]
7942 }
7943 run_test 56ab "lfs find --blocks"
7944
7945 # LU-11188
7946 test_56aca() {
7947         local dir="$DIR/$tdir"
7948         local perms=(001 002 003 004 005 006 007
7949                      010 020 030 040 050 060 070
7950                      100 200 300 400 500 600 700
7951                      111 222 333 444 555 666 777)
7952         local perm_minus=(8 8 4 8 4 4 2
7953                           8 8 4 8 4 4 2
7954                           8 8 4 8 4 4 2
7955                           4 4 2 4 2 2 1)
7956         local perm_slash=(8  8 12  8 12 12 14
7957                           8  8 12  8 12 12 14
7958                           8  8 12  8 12 12 14
7959                          16 16 24 16 24 24 28)
7960
7961         test_mkdir "$dir"
7962         for perm in ${perms[*]}; do
7963                 touch "$dir/$tfile.$perm"
7964                 chmod $perm "$dir/$tfile.$perm"
7965         done
7966
7967         for ((i = 0; i < ${#perms[*]}; i++)); do
7968                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7969                 (( $num == 1 )) ||
7970                         error "lfs find -perm ${perms[i]}:"\
7971                               "$num != 1"
7972
7973                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7974                 (( $num == ${perm_minus[i]} )) ||
7975                         error "lfs find -perm -${perms[i]}:"\
7976                               "$num != ${perm_minus[i]}"
7977
7978                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7979                 (( $num == ${perm_slash[i]} )) ||
7980                         error "lfs find -perm /${perms[i]}:"\
7981                               "$num != ${perm_slash[i]}"
7982         done
7983 }
7984 run_test 56aca "check lfs find -perm with octal representation"
7985
7986 test_56acb() {
7987         local dir=$DIR/$tdir
7988         # p is the permission of write and execute for user, group and other
7989         # without the umask. It is used to test +wx.
7990         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7991         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7992         local symbolic=(+t  a+t u+t g+t o+t
7993                         g+s u+s o+s +s o+sr
7994                         o=r,ug+o,u+w
7995                         u+ g+ o+ a+ ugo+
7996                         u- g- o- a- ugo-
7997                         u= g= o= a= ugo=
7998                         o=r,ug+o,u+w u=r,a+u,u+w
7999                         g=r,ugo=g,u+w u+x,+X +X
8000                         u+x,u+X u+X u+x,g+X o+r,+X
8001                         u+x,go+X +wx +rwx)
8002
8003         test_mkdir $dir
8004         for perm in ${perms[*]}; do
8005                 touch "$dir/$tfile.$perm"
8006                 chmod $perm "$dir/$tfile.$perm"
8007         done
8008
8009         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8010                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8011
8012                 (( $num == 1 )) ||
8013                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8014         done
8015 }
8016 run_test 56acb "check lfs find -perm with symbolic representation"
8017
8018 test_56acc() {
8019         local dir=$DIR/$tdir
8020         local tests="17777 787 789 abcd
8021                 ug=uu ug=a ug=gu uo=ou urw
8022                 u+xg+x a=r,u+x,"
8023
8024         test_mkdir $dir
8025         for err in $tests; do
8026                 if $LFS find $dir -perm $err 2>/dev/null; then
8027                         error "lfs find -perm $err: parsing should have failed"
8028                 fi
8029         done
8030 }
8031 run_test 56acc "check parsing error for lfs find -perm"
8032
8033 test_56ba() {
8034         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8035                 skip "Need MDS version at least 2.10.50"
8036
8037         # Create composite files with one component
8038         local dir=$DIR/$tdir
8039
8040         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8041         # Create composite files with three components
8042         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8043         # Create non-composite files
8044         createmany -o $dir/${tfile}- 10
8045
8046         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8047
8048         [[ $nfiles == 10 ]] ||
8049                 error "lfs find -E 1M found $nfiles != 10 files"
8050
8051         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8052         [[ $nfiles == 25 ]] ||
8053                 error "lfs find ! -E 1M found $nfiles != 25 files"
8054
8055         # All files have a component that starts at 0
8056         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8057         [[ $nfiles == 35 ]] ||
8058                 error "lfs find --component-start 0 - $nfiles != 35 files"
8059
8060         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8061         [[ $nfiles == 15 ]] ||
8062                 error "lfs find --component-start 2M - $nfiles != 15 files"
8063
8064         # All files created here have a componenet that does not starts at 2M
8065         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8066         [[ $nfiles == 35 ]] ||
8067                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8068
8069         # Find files with a specified number of components
8070         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8071         [[ $nfiles == 15 ]] ||
8072                 error "lfs find --component-count 3 - $nfiles != 15 files"
8073
8074         # Remember non-composite files have a component count of zero
8075         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8076         [[ $nfiles == 10 ]] ||
8077                 error "lfs find --component-count 0 - $nfiles != 10 files"
8078
8079         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8080         [[ $nfiles == 20 ]] ||
8081                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8082
8083         # All files have a flag called "init"
8084         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8085         [[ $nfiles == 35 ]] ||
8086                 error "lfs find --component-flags init - $nfiles != 35 files"
8087
8088         # Multi-component files will have a component not initialized
8089         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8090         [[ $nfiles == 15 ]] ||
8091                 error "lfs find !--component-flags init - $nfiles != 15 files"
8092
8093         rm -rf $dir
8094
8095 }
8096 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8097
8098 test_56ca() {
8099         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8100                 skip "Need MDS version at least 2.10.57"
8101
8102         local td=$DIR/$tdir
8103         local tf=$td/$tfile
8104         local dir
8105         local nfiles
8106         local cmd
8107         local i
8108         local j
8109
8110         # create mirrored directories and mirrored files
8111         mkdir $td || error "mkdir $td failed"
8112         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8113         createmany -o $tf- 10 || error "create $tf- failed"
8114
8115         for i in $(seq 2); do
8116                 dir=$td/dir$i
8117                 mkdir $dir || error "mkdir $dir failed"
8118                 $LFS mirror create -N$((3 + i)) $dir ||
8119                         error "create mirrored dir $dir failed"
8120                 createmany -o $dir/$tfile- 10 ||
8121                         error "create $dir/$tfile- failed"
8122         done
8123
8124         # change the states of some mirrored files
8125         echo foo > $tf-6
8126         for i in $(seq 2); do
8127                 dir=$td/dir$i
8128                 for j in $(seq 4 9); do
8129                         echo foo > $dir/$tfile-$j
8130                 done
8131         done
8132
8133         # find mirrored files with specific mirror count
8134         cmd="$LFS find --mirror-count 3 --type f $td"
8135         nfiles=$($cmd | wc -l)
8136         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8137
8138         cmd="$LFS find ! --mirror-count 3 --type f $td"
8139         nfiles=$($cmd | wc -l)
8140         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8141
8142         cmd="$LFS find --mirror-count +2 --type f $td"
8143         nfiles=$($cmd | wc -l)
8144         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8145
8146         cmd="$LFS find --mirror-count -6 --type f $td"
8147         nfiles=$($cmd | wc -l)
8148         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8149
8150         # find mirrored files with specific file state
8151         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8152         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8153
8154         cmd="$LFS find --mirror-state=ro --type f $td"
8155         nfiles=$($cmd | wc -l)
8156         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8157
8158         cmd="$LFS find ! --mirror-state=ro --type f $td"
8159         nfiles=$($cmd | wc -l)
8160         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8161
8162         cmd="$LFS find --mirror-state=wp --type f $td"
8163         nfiles=$($cmd | wc -l)
8164         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8165
8166         cmd="$LFS find ! --mirror-state=sp --type f $td"
8167         nfiles=$($cmd | wc -l)
8168         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8169 }
8170 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8171
8172 test_56da() { # LU-14179
8173         local path=$DIR/$tdir
8174
8175         test_mkdir $path
8176         cd $path
8177
8178         local longdir=$(str_repeat 'a' 255)
8179
8180         for i in {1..15}; do
8181                 path=$path/$longdir
8182                 test_mkdir $longdir
8183                 cd $longdir
8184         done
8185
8186         local len=${#path}
8187         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8188
8189         test_mkdir $lastdir
8190         cd $lastdir
8191         # PATH_MAX-1
8192         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8193
8194         # NAME_MAX
8195         touch $(str_repeat 'f' 255)
8196
8197         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8198                 error "lfs find reported an error"
8199
8200         rm -rf $DIR/$tdir
8201 }
8202 run_test 56da "test lfs find with long paths"
8203
8204 test_56ea() { #LU-10378
8205         local path=$DIR/$tdir
8206         local pool=$TESTNAME
8207
8208         # Create ost pool
8209         pool_add $pool || error "pool_add $pool failed"
8210         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8211                 error "adding targets to $pool failed"
8212
8213         # Set default pool on directory before creating file
8214         mkdir $path || error "mkdir $path failed"
8215         $LFS setstripe -p $pool $path ||
8216                 error "set OST pool on $pool failed"
8217         touch $path/$tfile || error "touch $path/$tfile failed"
8218
8219         # Compare basic file attributes from -printf and stat
8220         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8221         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8222
8223         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8224                 error "Attrs from lfs find and stat don't match"
8225
8226         # Compare Lustre attributes from lfs find and lfs getstripe
8227         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8228         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8229         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8230         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8231         local fpool=$($LFS getstripe --pool $path/$tfile)
8232         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8233
8234         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8235                 error "Attrs from lfs find and lfs getstripe don't match"
8236
8237         # Verify behavior for unknown escape/format sequences
8238         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8239
8240         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8241                 error "Escape/format codes don't match"
8242 }
8243 run_test 56ea "test lfs find -printf option"
8244
8245 test_57a() {
8246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8247         # note test will not do anything if MDS is not local
8248         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8249                 skip_env "ldiskfs only test"
8250         fi
8251         remote_mds_nodsh && skip "remote MDS with nodsh"
8252
8253         local MNTDEV="osd*.*MDT*.mntdev"
8254         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8255         [ -z "$DEV" ] && error "can't access $MNTDEV"
8256         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8257                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8258                         error "can't access $DEV"
8259                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8260                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8261                 rm $TMP/t57a.dump
8262         done
8263 }
8264 run_test 57a "verify MDS filesystem created with large inodes =="
8265
8266 test_57b() {
8267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8268         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8269                 skip_env "ldiskfs only test"
8270         fi
8271         remote_mds_nodsh && skip "remote MDS with nodsh"
8272
8273         local dir=$DIR/$tdir
8274         local filecount=100
8275         local file1=$dir/f1
8276         local fileN=$dir/f$filecount
8277
8278         rm -rf $dir || error "removing $dir"
8279         test_mkdir -c1 $dir
8280         local mdtidx=$($LFS getstripe -m $dir)
8281         local mdtname=MDT$(printf %04x $mdtidx)
8282         local facet=mds$((mdtidx + 1))
8283
8284         echo "mcreating $filecount files"
8285         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8286
8287         # verify that files do not have EAs yet
8288         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8289                 error "$file1 has an EA"
8290         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8291                 error "$fileN has an EA"
8292
8293         sync
8294         sleep 1
8295         df $dir  #make sure we get new statfs data
8296         local mdsfree=$(do_facet $facet \
8297                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8298         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8299         local file
8300
8301         echo "opening files to create objects/EAs"
8302         for file in $(seq -f $dir/f%g 1 $filecount); do
8303                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8304                         error "opening $file"
8305         done
8306
8307         # verify that files have EAs now
8308         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8309         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8310
8311         sleep 1  #make sure we get new statfs data
8312         df $dir
8313         local mdsfree2=$(do_facet $facet \
8314                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8315         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8316
8317         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8318                 if [ "$mdsfree" != "$mdsfree2" ]; then
8319                         error "MDC before $mdcfree != after $mdcfree2"
8320                 else
8321                         echo "MDC before $mdcfree != after $mdcfree2"
8322                         echo "unable to confirm if MDS has large inodes"
8323                 fi
8324         fi
8325         rm -rf $dir
8326 }
8327 run_test 57b "default LOV EAs are stored inside large inodes ==="
8328
8329 test_58() {
8330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8331         [ -z "$(which wiretest 2>/dev/null)" ] &&
8332                         skip_env "could not find wiretest"
8333
8334         wiretest
8335 }
8336 run_test 58 "verify cross-platform wire constants =============="
8337
8338 test_59() {
8339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8340
8341         echo "touch 130 files"
8342         createmany -o $DIR/f59- 130
8343         echo "rm 130 files"
8344         unlinkmany $DIR/f59- 130
8345         sync
8346         # wait for commitment of removal
8347         wait_delete_completed
8348 }
8349 run_test 59 "verify cancellation of llog records async ========="
8350
8351 TEST60_HEAD="test_60 run $RANDOM"
8352 test_60a() {
8353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8354         remote_mgs_nodsh && skip "remote MGS with nodsh"
8355         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8356                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8357                         skip_env "missing subtest run-llog.sh"
8358
8359         log "$TEST60_HEAD - from kernel mode"
8360         do_facet mgs "$LCTL dk > /dev/null"
8361         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8362         do_facet mgs $LCTL dk > $TMP/$tfile
8363
8364         # LU-6388: test llog_reader
8365         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8366         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8367         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8368                         skip_env "missing llog_reader"
8369         local fstype=$(facet_fstype mgs)
8370         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8371                 skip_env "Only for ldiskfs or zfs type mgs"
8372
8373         local mntpt=$(facet_mntpt mgs)
8374         local mgsdev=$(mgsdevname 1)
8375         local fid_list
8376         local fid
8377         local rec_list
8378         local rec
8379         local rec_type
8380         local obj_file
8381         local path
8382         local seq
8383         local oid
8384         local pass=true
8385
8386         #get fid and record list
8387         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8388                 tail -n 4))
8389         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8390                 tail -n 4))
8391         #remount mgs as ldiskfs or zfs type
8392         stop mgs || error "stop mgs failed"
8393         mount_fstype mgs || error "remount mgs failed"
8394         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8395                 fid=${fid_list[i]}
8396                 rec=${rec_list[i]}
8397                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8398                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8399                 oid=$((16#$oid))
8400
8401                 case $fstype in
8402                         ldiskfs )
8403                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8404                         zfs )
8405                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8406                 esac
8407                 echo "obj_file is $obj_file"
8408                 do_facet mgs $llog_reader $obj_file
8409
8410                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8411                         awk '{ print $3 }' | sed -e "s/^type=//g")
8412                 if [ $rec_type != $rec ]; then
8413                         echo "FAILED test_60a wrong record type $rec_type," \
8414                               "should be $rec"
8415                         pass=false
8416                         break
8417                 fi
8418
8419                 #check obj path if record type is LLOG_LOGID_MAGIC
8420                 if [ "$rec" == "1064553b" ]; then
8421                         path=$(do_facet mgs $llog_reader $obj_file |
8422                                 grep "path=" | awk '{ print $NF }' |
8423                                 sed -e "s/^path=//g")
8424                         if [ $obj_file != $mntpt/$path ]; then
8425                                 echo "FAILED test_60a wrong obj path" \
8426                                       "$montpt/$path, should be $obj_file"
8427                                 pass=false
8428                                 break
8429                         fi
8430                 fi
8431         done
8432         rm -f $TMP/$tfile
8433         #restart mgs before "error", otherwise it will block the next test
8434         stop mgs || error "stop mgs failed"
8435         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8436         $pass || error "test failed, see FAILED test_60a messages for specifics"
8437 }
8438 run_test 60a "llog_test run from kernel module and test llog_reader"
8439
8440 test_60b() { # bug 6411
8441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8442
8443         dmesg > $DIR/$tfile
8444         LLOG_COUNT=$(do_facet mgs dmesg |
8445                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8446                           /llog_[a-z]*.c:[0-9]/ {
8447                                 if (marker)
8448                                         from_marker++
8449                                 from_begin++
8450                           }
8451                           END {
8452                                 if (marker)
8453                                         print from_marker
8454                                 else
8455                                         print from_begin
8456                           }")
8457
8458         [[ $LLOG_COUNT -gt 120 ]] &&
8459                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8460 }
8461 run_test 60b "limit repeated messages from CERROR/CWARN"
8462
8463 test_60c() {
8464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8465
8466         echo "create 5000 files"
8467         createmany -o $DIR/f60c- 5000
8468 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8469         lctl set_param fail_loc=0x80000137
8470         unlinkmany $DIR/f60c- 5000
8471         lctl set_param fail_loc=0
8472 }
8473 run_test 60c "unlink file when mds full"
8474
8475 test_60d() {
8476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8477
8478         SAVEPRINTK=$(lctl get_param -n printk)
8479         # verify "lctl mark" is even working"
8480         MESSAGE="test message ID $RANDOM $$"
8481         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8482         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8483
8484         lctl set_param printk=0 || error "set lnet.printk failed"
8485         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8486         MESSAGE="new test message ID $RANDOM $$"
8487         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8488         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8489         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8490
8491         lctl set_param -n printk="$SAVEPRINTK"
8492 }
8493 run_test 60d "test printk console message masking"
8494
8495 test_60e() {
8496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8497         remote_mds_nodsh && skip "remote MDS with nodsh"
8498
8499         touch $DIR/$tfile
8500 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8501         do_facet mds1 lctl set_param fail_loc=0x15b
8502         rm $DIR/$tfile
8503 }
8504 run_test 60e "no space while new llog is being created"
8505
8506 test_60f() {
8507         local old_path=$($LCTL get_param -n debug_path)
8508
8509         stack_trap "$LCTL set_param debug_path=$old_path"
8510         stack_trap "rm -f $TMP/$tfile*"
8511         rm -f $TMP/$tfile* 2> /dev/null
8512         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8513         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8514         test_mkdir $DIR/$tdir
8515         # retry in case the open is cached and not released
8516         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8517                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8518                 sleep 0.1
8519         done
8520         ls $TMP/$tfile*
8521         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8522 }
8523 run_test 60f "change debug_path works"
8524
8525 test_60g() {
8526         local pid
8527         local i
8528
8529         test_mkdir -c $MDSCOUNT $DIR/$tdir
8530
8531         (
8532                 local index=0
8533                 while true; do
8534                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8535                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8536                                 2>/dev/null
8537                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8538                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8539                         index=$((index + 1))
8540                 done
8541         ) &
8542
8543         pid=$!
8544
8545         for i in {0..100}; do
8546                 # define OBD_FAIL_OSD_TXN_START    0x19a
8547                 local index=$((i % MDSCOUNT + 1))
8548
8549                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8550                         > /dev/null
8551                 sleep 0.01
8552         done
8553
8554         kill -9 $pid
8555
8556         for i in $(seq $MDSCOUNT); do
8557                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8558         done
8559
8560         mkdir $DIR/$tdir/new || error "mkdir failed"
8561         rmdir $DIR/$tdir/new || error "rmdir failed"
8562
8563         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8564                 -t namespace
8565         for i in $(seq $MDSCOUNT); do
8566                 wait_update_facet mds$i "$LCTL get_param -n \
8567                         mdd.$(facet_svc mds$i).lfsck_namespace |
8568                         awk '/^status/ { print \\\$2 }'" "completed"
8569         done
8570
8571         ls -R $DIR/$tdir
8572         rm -rf $DIR/$tdir || error "rmdir failed"
8573 }
8574 run_test 60g "transaction abort won't cause MDT hung"
8575
8576 test_60h() {
8577         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8578                 skip "Need MDS version at least 2.12.52"
8579         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8580
8581         local f
8582
8583         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8584         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8585         for fail_loc in 0x80000188 0x80000189; do
8586                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8587                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8588                         error "mkdir $dir-$fail_loc failed"
8589                 for i in {0..10}; do
8590                         # create may fail on missing stripe
8591                         echo $i > $DIR/$tdir-$fail_loc/$i
8592                 done
8593                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8594                         error "getdirstripe $tdir-$fail_loc failed"
8595                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8596                         error "migrate $tdir-$fail_loc failed"
8597                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8598                         error "getdirstripe $tdir-$fail_loc failed"
8599                 pushd $DIR/$tdir-$fail_loc
8600                 for f in *; do
8601                         echo $f | cmp $f - || error "$f data mismatch"
8602                 done
8603                 popd
8604                 rm -rf $DIR/$tdir-$fail_loc
8605         done
8606 }
8607 run_test 60h "striped directory with missing stripes can be accessed"
8608
8609 function t60i_load() {
8610         mkdir $DIR/$tdir
8611         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8612         $LCTL set_param fail_loc=0x131c fail_val=1
8613         for ((i=0; i<5000; i++)); do
8614                 touch $DIR/$tdir/f$i
8615         done
8616 }
8617
8618 test_60i() {
8619         changelog_register || error "changelog_register failed"
8620         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8621         changelog_users $SINGLEMDS | grep -q $cl_user ||
8622                 error "User $cl_user not found in changelog_users"
8623         changelog_chmask "ALL"
8624         t60i_load &
8625         local PID=$!
8626         for((i=0; i<100; i++)); do
8627                 changelog_dump >/dev/null ||
8628                         error "can't read changelog"
8629         done
8630         kill $PID
8631         wait $PID
8632         changelog_deregister || error "changelog_deregister failed"
8633         $LCTL set_param fail_loc=0
8634 }
8635 run_test 60i "llog: new record vs reader race"
8636
8637 test_61a() {
8638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8639
8640         f="$DIR/f61"
8641         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8642         cancel_lru_locks osc
8643         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8644         sync
8645 }
8646 run_test 61a "mmap() writes don't make sync hang ================"
8647
8648 test_61b() {
8649         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8650 }
8651 run_test 61b "mmap() of unstriped file is successful"
8652
8653 # bug 2330 - insufficient obd_match error checking causes LBUG
8654 test_62() {
8655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8656
8657         f="$DIR/f62"
8658         echo foo > $f
8659         cancel_lru_locks osc
8660         lctl set_param fail_loc=0x405
8661         cat $f && error "cat succeeded, expect -EIO"
8662         lctl set_param fail_loc=0
8663 }
8664 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8665 # match every page all of the time.
8666 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8667
8668 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8669 # Though this test is irrelevant anymore, it helped to reveal some
8670 # other grant bugs (LU-4482), let's keep it.
8671 test_63a() {   # was test_63
8672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8673
8674         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8675
8676         for i in `seq 10` ; do
8677                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8678                 sleep 5
8679                 kill $!
8680                 sleep 1
8681         done
8682
8683         rm -f $DIR/f63 || true
8684 }
8685 run_test 63a "Verify oig_wait interruption does not crash ======="
8686
8687 # bug 2248 - async write errors didn't return to application on sync
8688 # bug 3677 - async write errors left page locked
8689 test_63b() {
8690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8691
8692         debugsave
8693         lctl set_param debug=-1
8694
8695         # ensure we have a grant to do async writes
8696         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8697         rm $DIR/$tfile
8698
8699         sync    # sync lest earlier test intercept the fail_loc
8700
8701         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8702         lctl set_param fail_loc=0x80000406
8703         $MULTIOP $DIR/$tfile Owy && \
8704                 error "sync didn't return ENOMEM"
8705         sync; sleep 2; sync     # do a real sync this time to flush page
8706         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8707                 error "locked page left in cache after async error" || true
8708         debugrestore
8709 }
8710 run_test 63b "async write errors should be returned to fsync ==="
8711
8712 test_64a () {
8713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8714
8715         lfs df $DIR
8716         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8717 }
8718 run_test 64a "verify filter grant calculations (in kernel) ====="
8719
8720 test_64b () {
8721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8722
8723         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8724 }
8725 run_test 64b "check out-of-space detection on client"
8726
8727 test_64c() {
8728         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8729 }
8730 run_test 64c "verify grant shrink"
8731
8732 import_param() {
8733         local tgt=$1
8734         local param=$2
8735
8736         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8737 }
8738
8739 # this does exactly what osc_request.c:osc_announce_cached() does in
8740 # order to calculate max amount of grants to ask from server
8741 want_grant() {
8742         local tgt=$1
8743
8744         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8745         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8746
8747         ((rpc_in_flight++));
8748         nrpages=$((nrpages * rpc_in_flight))
8749
8750         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8751
8752         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8753
8754         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8755         local undirty=$((nrpages * PAGE_SIZE))
8756
8757         local max_extent_pages
8758         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8759         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8760         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8761         local grant_extent_tax
8762         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8763
8764         undirty=$((undirty + nrextents * grant_extent_tax))
8765
8766         echo $undirty
8767 }
8768
8769 # this is size of unit for grant allocation. It should be equal to
8770 # what tgt_grant.c:tgt_grant_chunk() calculates
8771 grant_chunk() {
8772         local tgt=$1
8773         local max_brw_size
8774         local grant_extent_tax
8775
8776         max_brw_size=$(import_param $tgt max_brw_size)
8777
8778         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8779
8780         echo $(((max_brw_size + grant_extent_tax) * 2))
8781 }
8782
8783 test_64d() {
8784         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8785                 skip "OST < 2.10.55 doesn't limit grants enough"
8786
8787         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8788
8789         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8790                 skip "no grant_param connect flag"
8791
8792         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8793
8794         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8795         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8796
8797
8798         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8799         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8800
8801         $LFS setstripe $DIR/$tfile -i 0 -c 1
8802         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8803         ddpid=$!
8804
8805         while kill -0 $ddpid; do
8806                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8807
8808                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8809                         kill $ddpid
8810                         error "cur_grant $cur_grant > $max_cur_granted"
8811                 fi
8812
8813                 sleep 1
8814         done
8815 }
8816 run_test 64d "check grant limit exceed"
8817
8818 check_grants() {
8819         local tgt=$1
8820         local expected=$2
8821         local msg=$3
8822         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8823
8824         ((cur_grants == expected)) ||
8825                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8826 }
8827
8828 round_up_p2() {
8829         echo $((($1 + $2 - 1) & ~($2 - 1)))
8830 }
8831
8832 test_64e() {
8833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8834         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8835                 skip "Need OSS version at least 2.11.56"
8836
8837         # Remount client to reset grant
8838         remount_client $MOUNT || error "failed to remount client"
8839         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8840
8841         local init_grants=$(import_param $osc_tgt initial_grant)
8842
8843         check_grants $osc_tgt $init_grants "init grants"
8844
8845         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8846         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8847         local gbs=$(import_param $osc_tgt grant_block_size)
8848
8849         # write random number of bytes from max_brw_size / 4 to max_brw_size
8850         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8851         # align for direct io
8852         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8853         # round to grant consumption unit
8854         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8855
8856         local grants=$((wb_round_up + extent_tax))
8857
8858         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8859
8860         # define OBD_FAIL_TGT_NO_GRANT 0x725
8861         # make the server not grant more back
8862         do_facet ost1 $LCTL set_param fail_loc=0x725
8863         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8864
8865         do_facet ost1 $LCTL set_param fail_loc=0
8866
8867         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8868
8869         rm -f $DIR/$tfile || error "rm failed"
8870
8871         # Remount client to reset grant
8872         remount_client $MOUNT || error "failed to remount client"
8873         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8874
8875         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8876
8877         # define OBD_FAIL_TGT_NO_GRANT 0x725
8878         # make the server not grant more back
8879         do_facet ost1 $LCTL set_param fail_loc=0x725
8880         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8881         do_facet ost1 $LCTL set_param fail_loc=0
8882
8883         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8884 }
8885 run_test 64e "check grant consumption (no grant allocation)"
8886
8887 test_64f() {
8888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8889
8890         # Remount client to reset grant
8891         remount_client $MOUNT || error "failed to remount client"
8892         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8893
8894         local init_grants=$(import_param $osc_tgt initial_grant)
8895         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8896         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8897         local gbs=$(import_param $osc_tgt grant_block_size)
8898         local chunk=$(grant_chunk $osc_tgt)
8899
8900         # write random number of bytes from max_brw_size / 4 to max_brw_size
8901         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8902         # align for direct io
8903         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8904         # round to grant consumption unit
8905         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8906
8907         local grants=$((wb_round_up + extent_tax))
8908
8909         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8910         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8911                 error "error writing to $DIR/$tfile"
8912
8913         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8914                 "direct io with grant allocation"
8915
8916         rm -f $DIR/$tfile || error "rm failed"
8917
8918         # Remount client to reset grant
8919         remount_client $MOUNT || error "failed to remount client"
8920         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8921
8922         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8923
8924         local cmd="oO_WRONLY:w${write_bytes}_yc"
8925
8926         $MULTIOP $DIR/$tfile $cmd &
8927         MULTIPID=$!
8928         sleep 1
8929
8930         check_grants $osc_tgt $((init_grants - grants)) \
8931                 "buffered io, not write rpc"
8932
8933         kill -USR1 $MULTIPID
8934         wait
8935
8936         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8937                 "buffered io, one RPC"
8938 }
8939 run_test 64f "check grant consumption (with grant allocation)"
8940
8941 test_64g() {
8942         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
8943                 skip "Need MDS version at least 2.14.56"
8944
8945         local mdts=$(comma_list $(mdts_nodes))
8946
8947         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8948                         tr '\n' ' ')
8949         stack_trap "$LCTL set_param $old"
8950
8951         # generate dirty pages and increase dirty granted on MDT
8952         stack_trap "rm -f $DIR/$tfile-*"
8953         for (( i = 0; i < 10; i++)); do
8954                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8955                         error "can't set stripe"
8956                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8957                         error "can't dd"
8958                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8959                         $LFS getstripe $DIR/$tfile-$i
8960                         error "not DoM file"
8961                 }
8962         done
8963
8964         # flush dirty pages
8965         sync
8966
8967         # wait until grant shrink reset grant dirty on MDTs
8968         for ((i = 0; i < 120; i++)); do
8969                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8970                         awk '{sum=sum+$1} END {print sum}')
8971                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8972                 echo "$grant_dirty grants, $vm_dirty pages"
8973                 (( grant_dirty + vm_dirty == 0 )) && break
8974                 (( i == 3 )) && sync &&
8975                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8976                 sleep 1
8977         done
8978
8979         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8980                 awk '{sum=sum+$1} END {print sum}')
8981         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8982 }
8983 run_test 64g "grant shrink on MDT"
8984
8985 test_64h() {
8986         local instance=$($LFS getname -i $DIR)
8987         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8988         local num_exps=$(do_facet ost1 \
8989             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8990         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8991         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8992         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8993
8994         # 10MiB is for file to be written, max_brw_size * 16 *
8995         # num_exps is space reserve so that tgt_grant_shrink() decided
8996         # to not shrink
8997         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8998         (( avail * 1024 < expect )) &&
8999                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9000
9001         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9002         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9003         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9004         $LCTL set_param osc.*OST0000*.grant_shrink=1
9005         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9006
9007         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9008         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9009
9010         # drop cache so that coming read would do rpc
9011         cancel_lru_locks osc
9012
9013         # shrink interval is set to 10, pause for 7 seconds so that
9014         # grant thread did not wake up yet but coming read entered
9015         # shrink mode for rpc (osc_should_shrink_grant())
9016         sleep 7
9017
9018         declare -a cur_grant_bytes
9019         declare -a tot_granted
9020         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9021         tot_granted[0]=$(do_facet ost1 \
9022             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9023
9024         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9025
9026         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9027         tot_granted[1]=$(do_facet ost1 \
9028             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9029
9030         # grant change should be equal on both sides
9031         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9032                 tot_granted[0] - tot_granted[1])) ||
9033                 error "grant change mismatch, "                                \
9034                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9035                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9036 }
9037 run_test 64h "grant shrink on read"
9038
9039 test_64i() {
9040         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
9041                 skip "need OST at least 2.14.55 to avoid grant shrink on replay"
9042
9043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9044         remote_ost_nodsh && skip "remote OSTs with nodsh"
9045
9046         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9047
9048         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9049
9050         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9051         local instance=$($LFS getname -i $DIR)
9052
9053         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9054         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9055
9056         # shrink grants and simulate rpc loss
9057         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9058         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9059         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9060
9061         fail ost1
9062
9063         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9064
9065         local testid=$(echo $TESTNAME | tr '_' ' ')
9066
9067         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9068                 grep "GRANT, real grant" &&
9069                 error "client has more grants then it owns" || true
9070 }
9071 run_test 64i "shrink on reconnect"
9072
9073 # bug 1414 - set/get directories' stripe info
9074 test_65a() {
9075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9076
9077         test_mkdir $DIR/$tdir
9078         touch $DIR/$tdir/f1
9079         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9080 }
9081 run_test 65a "directory with no stripe info"
9082
9083 test_65b() {
9084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9085
9086         test_mkdir $DIR/$tdir
9087         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9088
9089         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9090                                                 error "setstripe"
9091         touch $DIR/$tdir/f2
9092         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9093 }
9094 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9095
9096 test_65c() {
9097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9098         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9099
9100         test_mkdir $DIR/$tdir
9101         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9102
9103         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9104                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9105         touch $DIR/$tdir/f3
9106         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9107 }
9108 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9109
9110 test_65d() {
9111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9112
9113         test_mkdir $DIR/$tdir
9114         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9115         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9116
9117         if [[ $STRIPECOUNT -le 0 ]]; then
9118                 sc=1
9119         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9120                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9121                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9122         else
9123                 sc=$(($STRIPECOUNT - 1))
9124         fi
9125         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9126         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9127         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9128                 error "lverify failed"
9129 }
9130 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9131
9132 test_65e() {
9133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9134
9135         test_mkdir $DIR/$tdir
9136
9137         $LFS setstripe $DIR/$tdir || error "setstripe"
9138         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9139                                         error "no stripe info failed"
9140         touch $DIR/$tdir/f6
9141         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9142 }
9143 run_test 65e "directory setstripe defaults"
9144
9145 test_65f() {
9146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9147
9148         test_mkdir $DIR/${tdir}f
9149         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9150                 error "setstripe succeeded" || true
9151 }
9152 run_test 65f "dir setstripe permission (should return error) ==="
9153
9154 test_65g() {
9155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9156
9157         test_mkdir $DIR/$tdir
9158         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9159
9160         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9161                 error "setstripe -S failed"
9162         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9163         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9164                 error "delete default stripe failed"
9165 }
9166 run_test 65g "directory setstripe -d"
9167
9168 test_65h() {
9169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9170
9171         test_mkdir $DIR/$tdir
9172         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9173
9174         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9175                 error "setstripe -S failed"
9176         test_mkdir $DIR/$tdir/dd1
9177         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9178                 error "stripe info inherit failed"
9179 }
9180 run_test 65h "directory stripe info inherit ===================="
9181
9182 test_65i() {
9183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9184
9185         save_layout_restore_at_exit $MOUNT
9186
9187         # bug6367: set non-default striping on root directory
9188         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9189
9190         # bug12836: getstripe on -1 default directory striping
9191         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9192
9193         # bug12836: getstripe -v on -1 default directory striping
9194         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9195
9196         # bug12836: new find on -1 default directory striping
9197         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9198 }
9199 run_test 65i "various tests to set root directory striping"
9200
9201 test_65j() { # bug6367
9202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9203
9204         sync; sleep 1
9205
9206         # if we aren't already remounting for each test, do so for this test
9207         if [ "$I_MOUNTED" = "yes" ]; then
9208                 cleanup || error "failed to unmount"
9209                 setup
9210         fi
9211
9212         save_layout_restore_at_exit $MOUNT
9213
9214         $LFS setstripe -d $MOUNT || error "setstripe failed"
9215 }
9216 run_test 65j "set default striping on root directory (bug 6367)="
9217
9218 cleanup_65k() {
9219         rm -rf $DIR/$tdir
9220         wait_delete_completed
9221         do_facet $SINGLEMDS "lctl set_param -n \
9222                 osp.$ost*MDT0000.max_create_count=$max_count"
9223         do_facet $SINGLEMDS "lctl set_param -n \
9224                 osp.$ost*MDT0000.create_count=$count"
9225         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9226         echo $INACTIVE_OSC "is Activate"
9227
9228         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9229 }
9230
9231 test_65k() { # bug11679
9232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9233         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9234         remote_mds_nodsh && skip "remote MDS with nodsh"
9235
9236         local disable_precreate=true
9237         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9238                 disable_precreate=false
9239
9240         echo "Check OST status: "
9241         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9242                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9243
9244         for OSC in $MDS_OSCS; do
9245                 echo $OSC "is active"
9246                 do_facet $SINGLEMDS lctl --device %$OSC activate
9247         done
9248
9249         for INACTIVE_OSC in $MDS_OSCS; do
9250                 local ost=$(osc_to_ost $INACTIVE_OSC)
9251                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9252                                lov.*md*.target_obd |
9253                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9254
9255                 mkdir -p $DIR/$tdir
9256                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9257                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9258
9259                 echo "Deactivate: " $INACTIVE_OSC
9260                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9261
9262                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9263                               osp.$ost*MDT0000.create_count")
9264                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9265                                   osp.$ost*MDT0000.max_create_count")
9266                 $disable_precreate &&
9267                         do_facet $SINGLEMDS "lctl set_param -n \
9268                                 osp.$ost*MDT0000.max_create_count=0"
9269
9270                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9271                         [ -f $DIR/$tdir/$idx ] && continue
9272                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9273                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9274                                 { cleanup_65k;
9275                                   error "setstripe $idx should succeed"; }
9276                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9277                 done
9278                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9279                 rmdir $DIR/$tdir
9280
9281                 do_facet $SINGLEMDS "lctl set_param -n \
9282                         osp.$ost*MDT0000.max_create_count=$max_count"
9283                 do_facet $SINGLEMDS "lctl set_param -n \
9284                         osp.$ost*MDT0000.create_count=$count"
9285                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9286                 echo $INACTIVE_OSC "is Activate"
9287
9288                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9289         done
9290 }
9291 run_test 65k "validate manual striping works properly with deactivated OSCs"
9292
9293 test_65l() { # bug 12836
9294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9295
9296         test_mkdir -p $DIR/$tdir/test_dir
9297         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9298         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9299 }
9300 run_test 65l "lfs find on -1 stripe dir ========================"
9301
9302 test_65m() {
9303         local layout=$(save_layout $MOUNT)
9304         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9305                 restore_layout $MOUNT $layout
9306                 error "setstripe should fail by non-root users"
9307         }
9308         true
9309 }
9310 run_test 65m "normal user can't set filesystem default stripe"
9311
9312 test_65n() {
9313         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9314         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9315                 skip "Need MDS version at least 2.12.50"
9316         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9317
9318         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9319         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9320         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9321
9322         save_layout_restore_at_exit $MOUNT
9323
9324         # new subdirectory under root directory should not inherit
9325         # the default layout from root
9326         local dir1=$MOUNT/$tdir-1
9327         mkdir $dir1 || error "mkdir $dir1 failed"
9328         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9329                 error "$dir1 shouldn't have LOV EA"
9330
9331         # delete the default layout on root directory
9332         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9333
9334         local dir2=$MOUNT/$tdir-2
9335         mkdir $dir2 || error "mkdir $dir2 failed"
9336         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9337                 error "$dir2 shouldn't have LOV EA"
9338
9339         # set a new striping pattern on root directory
9340         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9341         local new_def_stripe_size=$((def_stripe_size * 2))
9342         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9343                 error "set stripe size on $MOUNT failed"
9344
9345         # new file created in $dir2 should inherit the new stripe size from
9346         # the filesystem default
9347         local file2=$dir2/$tfile-2
9348         touch $file2 || error "touch $file2 failed"
9349
9350         local file2_stripe_size=$($LFS getstripe -S $file2)
9351         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9352         {
9353                 echo "file2_stripe_size: '$file2_stripe_size'"
9354                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9355                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9356         }
9357
9358         local dir3=$MOUNT/$tdir-3
9359         mkdir $dir3 || error "mkdir $dir3 failed"
9360         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9361         # the root layout, which is the actual default layout that will be used
9362         # when new files are created in $dir3.
9363         local dir3_layout=$(get_layout_param $dir3)
9364         local root_dir_layout=$(get_layout_param $MOUNT)
9365         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9366         {
9367                 echo "dir3_layout: '$dir3_layout'"
9368                 echo "root_dir_layout: '$root_dir_layout'"
9369                 error "$dir3 should show the default layout from $MOUNT"
9370         }
9371
9372         # set OST pool on root directory
9373         local pool=$TESTNAME
9374         pool_add $pool || error "add $pool failed"
9375         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9376                 error "add targets to $pool failed"
9377
9378         $LFS setstripe -p $pool $MOUNT ||
9379                 error "set OST pool on $MOUNT failed"
9380
9381         # new file created in $dir3 should inherit the pool from
9382         # the filesystem default
9383         local file3=$dir3/$tfile-3
9384         touch $file3 || error "touch $file3 failed"
9385
9386         local file3_pool=$($LFS getstripe -p $file3)
9387         [[ "$file3_pool" = "$pool" ]] ||
9388                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9389
9390         local dir4=$MOUNT/$tdir-4
9391         mkdir $dir4 || error "mkdir $dir4 failed"
9392         local dir4_layout=$(get_layout_param $dir4)
9393         root_dir_layout=$(get_layout_param $MOUNT)
9394         echo "$LFS getstripe -d $dir4"
9395         $LFS getstripe -d $dir4
9396         echo "$LFS getstripe -d $MOUNT"
9397         $LFS getstripe -d $MOUNT
9398         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9399         {
9400                 echo "dir4_layout: '$dir4_layout'"
9401                 echo "root_dir_layout: '$root_dir_layout'"
9402                 error "$dir4 should show the default layout from $MOUNT"
9403         }
9404
9405         # new file created in $dir4 should inherit the pool from
9406         # the filesystem default
9407         local file4=$dir4/$tfile-4
9408         touch $file4 || error "touch $file4 failed"
9409
9410         local file4_pool=$($LFS getstripe -p $file4)
9411         [[ "$file4_pool" = "$pool" ]] ||
9412                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9413
9414         # new subdirectory under non-root directory should inherit
9415         # the default layout from its parent directory
9416         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9417                 error "set directory layout on $dir4 failed"
9418
9419         local dir5=$dir4/$tdir-5
9420         mkdir $dir5 || error "mkdir $dir5 failed"
9421
9422         dir4_layout=$(get_layout_param $dir4)
9423         local dir5_layout=$(get_layout_param $dir5)
9424         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9425         {
9426                 echo "dir4_layout: '$dir4_layout'"
9427                 echo "dir5_layout: '$dir5_layout'"
9428                 error "$dir5 should inherit the default layout from $dir4"
9429         }
9430
9431         # though subdir under ROOT doesn't inherit default layout, but
9432         # its sub dir/file should be created with default layout.
9433         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9434         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9435                 skip "Need MDS version at least 2.12.59"
9436
9437         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9438         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9439         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9440
9441         if [ $default_lmv_hash == "none" ]; then
9442                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9443         else
9444                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9445                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9446         fi
9447
9448         $LFS setdirstripe -D -c 2 $MOUNT ||
9449                 error "setdirstripe -D -c 2 failed"
9450         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9451         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9452         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9453
9454         # $dir4 layout includes pool
9455         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9456         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9457                 error "pool lost on setstripe"
9458         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9459         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9460                 error "pool lost on compound layout setstripe"
9461 }
9462 run_test 65n "don't inherit default layout from root for new subdirectories"
9463
9464 # bug 2543 - update blocks count on client
9465 test_66() {
9466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9467
9468         COUNT=${COUNT:-8}
9469         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9470         sync; sync_all_data; sync; sync_all_data
9471         cancel_lru_locks osc
9472         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9473         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9474 }
9475 run_test 66 "update inode blocks count on client ==============="
9476
9477 meminfo() {
9478         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9479 }
9480
9481 swap_used() {
9482         swapon -s | awk '($1 == "'$1'") { print $4 }'
9483 }
9484
9485 # bug5265, obdfilter oa2dentry return -ENOENT
9486 # #define OBD_FAIL_SRV_ENOENT 0x217
9487 test_69() {
9488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9489         remote_ost_nodsh && skip "remote OST with nodsh"
9490
9491         f="$DIR/$tfile"
9492         $LFS setstripe -c 1 -i 0 $f
9493
9494         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9495
9496         do_facet ost1 lctl set_param fail_loc=0x217
9497         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9498         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9499
9500         do_facet ost1 lctl set_param fail_loc=0
9501         $DIRECTIO write $f 0 2 || error "write error"
9502
9503         cancel_lru_locks osc
9504         $DIRECTIO read $f 0 1 || error "read error"
9505
9506         do_facet ost1 lctl set_param fail_loc=0x217
9507         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9508
9509         do_facet ost1 lctl set_param fail_loc=0
9510         rm -f $f
9511 }
9512 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9513
9514 test_71() {
9515         test_mkdir $DIR/$tdir
9516         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9517         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9518 }
9519 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9520
9521 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9523         [ "$RUNAS_ID" = "$UID" ] &&
9524                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9525         # Check that testing environment is properly set up. Skip if not
9526         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9527                 skip_env "User $RUNAS_ID does not exist - skipping"
9528
9529         touch $DIR/$tfile
9530         chmod 777 $DIR/$tfile
9531         chmod ug+s $DIR/$tfile
9532         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9533                 error "$RUNAS dd $DIR/$tfile failed"
9534         # See if we are still setuid/sgid
9535         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9536                 error "S/gid is not dropped on write"
9537         # Now test that MDS is updated too
9538         cancel_lru_locks mdc
9539         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9540                 error "S/gid is not dropped on MDS"
9541         rm -f $DIR/$tfile
9542 }
9543 run_test 72a "Test that remove suid works properly (bug5695) ===="
9544
9545 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9546         local perm
9547
9548         [ "$RUNAS_ID" = "$UID" ] &&
9549                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9550         [ "$RUNAS_ID" -eq 0 ] &&
9551                 skip_env "RUNAS_ID = 0 -- skipping"
9552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9553         # Check that testing environment is properly set up. Skip if not
9554         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9555                 skip_env "User $RUNAS_ID does not exist - skipping"
9556
9557         touch $DIR/${tfile}-f{g,u}
9558         test_mkdir $DIR/${tfile}-dg
9559         test_mkdir $DIR/${tfile}-du
9560         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9561         chmod g+s $DIR/${tfile}-{f,d}g
9562         chmod u+s $DIR/${tfile}-{f,d}u
9563         for perm in 777 2777 4777; do
9564                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9565                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9566                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9567                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9568         done
9569         true
9570 }
9571 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9572
9573 # bug 3462 - multiple simultaneous MDC requests
9574 test_73() {
9575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9576
9577         test_mkdir $DIR/d73-1
9578         test_mkdir $DIR/d73-2
9579         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9580         pid1=$!
9581
9582         lctl set_param fail_loc=0x80000129
9583         $MULTIOP $DIR/d73-1/f73-2 Oc &
9584         sleep 1
9585         lctl set_param fail_loc=0
9586
9587         $MULTIOP $DIR/d73-2/f73-3 Oc &
9588         pid3=$!
9589
9590         kill -USR1 $pid1
9591         wait $pid1 || return 1
9592
9593         sleep 25
9594
9595         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9596         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9597         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9598
9599         rm -rf $DIR/d73-*
9600 }
9601 run_test 73 "multiple MDC requests (should not deadlock)"
9602
9603 test_74a() { # bug 6149, 6184
9604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9605
9606         touch $DIR/f74a
9607         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9608         #
9609         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9610         # will spin in a tight reconnection loop
9611         $LCTL set_param fail_loc=0x8000030e
9612         # get any lock that won't be difficult - lookup works.
9613         ls $DIR/f74a
9614         $LCTL set_param fail_loc=0
9615         rm -f $DIR/f74a
9616         true
9617 }
9618 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9619
9620 test_74b() { # bug 13310
9621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9622
9623         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9624         #
9625         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9626         # will spin in a tight reconnection loop
9627         $LCTL set_param fail_loc=0x8000030e
9628         # get a "difficult" lock
9629         touch $DIR/f74b
9630         $LCTL set_param fail_loc=0
9631         rm -f $DIR/f74b
9632         true
9633 }
9634 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9635
9636 test_74c() {
9637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9638
9639         #define OBD_FAIL_LDLM_NEW_LOCK
9640         $LCTL set_param fail_loc=0x319
9641         touch $DIR/$tfile && error "touch successful"
9642         $LCTL set_param fail_loc=0
9643         true
9644 }
9645 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9646
9647 slab_lic=/sys/kernel/slab/lustre_inode_cache
9648 num_objects() {
9649         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9650         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9651                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9652 }
9653
9654 test_76a() { # Now for b=20433, added originally in b=1443
9655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9656
9657         cancel_lru_locks osc
9658         # there may be some slab objects cached per core
9659         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9660         local before=$(num_objects)
9661         local count=$((512 * cpus))
9662         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9663         local margin=$((count / 10))
9664         if [[ -f $slab_lic/aliases ]]; then
9665                 local aliases=$(cat $slab_lic/aliases)
9666                 (( aliases > 0 )) && margin=$((margin * aliases))
9667         fi
9668
9669         echo "before slab objects: $before"
9670         for i in $(seq $count); do
9671                 touch $DIR/$tfile
9672                 rm -f $DIR/$tfile
9673         done
9674         cancel_lru_locks osc
9675         local after=$(num_objects)
9676         echo "created: $count, after slab objects: $after"
9677         # shared slab counts are not very accurate, allow significant margin
9678         # the main goal is that the cache growth is not permanently > $count
9679         while (( after > before + margin )); do
9680                 sleep 1
9681                 after=$(num_objects)
9682                 wait=$((wait + 1))
9683                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9684                 if (( wait > 60 )); then
9685                         error "inode slab grew from $before+$margin to $after"
9686                 fi
9687         done
9688 }
9689 run_test 76a "confirm clients recycle inodes properly ===="
9690
9691 test_76b() {
9692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9693         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9694
9695         local count=512
9696         local before=$(num_objects)
9697
9698         for i in $(seq $count); do
9699                 mkdir $DIR/$tdir
9700                 rmdir $DIR/$tdir
9701         done
9702
9703         local after=$(num_objects)
9704         local wait=0
9705
9706         while (( after > before )); do
9707                 sleep 1
9708                 after=$(num_objects)
9709                 wait=$((wait + 1))
9710                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9711                 if (( wait > 60 )); then
9712                         error "inode slab grew from $before to $after"
9713                 fi
9714         done
9715
9716         echo "slab objects before: $before, after: $after"
9717 }
9718 run_test 76b "confirm clients recycle directory inodes properly ===="
9719
9720 export ORIG_CSUM=""
9721 set_checksums()
9722 {
9723         # Note: in sptlrpc modes which enable its own bulk checksum, the
9724         # original crc32_le bulk checksum will be automatically disabled,
9725         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9726         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9727         # In this case set_checksums() will not be no-op, because sptlrpc
9728         # bulk checksum will be enabled all through the test.
9729
9730         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9731         lctl set_param -n osc.*.checksums $1
9732         return 0
9733 }
9734
9735 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9736                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9737 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9738                              tr -d [] | head -n1)}
9739 set_checksum_type()
9740 {
9741         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9742         rc=$?
9743         log "set checksum type to $1, rc = $rc"
9744         return $rc
9745 }
9746
9747 get_osc_checksum_type()
9748 {
9749         # arugment 1: OST name, like OST0000
9750         ost=$1
9751         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9752                         sed 's/.*\[\(.*\)\].*/\1/g')
9753         rc=$?
9754         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9755         echo $checksum_type
9756 }
9757
9758 F77_TMP=$TMP/f77-temp
9759 F77SZ=8
9760 setup_f77() {
9761         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9762                 error "error writing to $F77_TMP"
9763 }
9764
9765 test_77a() { # bug 10889
9766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9767         $GSS && skip_env "could not run with gss"
9768
9769         [ ! -f $F77_TMP ] && setup_f77
9770         set_checksums 1
9771         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9772         set_checksums 0
9773         rm -f $DIR/$tfile
9774 }
9775 run_test 77a "normal checksum read/write operation"
9776
9777 test_77b() { # bug 10889
9778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9779         $GSS && skip_env "could not run with gss"
9780
9781         [ ! -f $F77_TMP ] && setup_f77
9782         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9783         $LCTL set_param fail_loc=0x80000409
9784         set_checksums 1
9785
9786         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9787                 error "dd error: $?"
9788         $LCTL set_param fail_loc=0
9789
9790         for algo in $CKSUM_TYPES; do
9791                 cancel_lru_locks osc
9792                 set_checksum_type $algo
9793                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9794                 $LCTL set_param fail_loc=0x80000408
9795                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9796                 $LCTL set_param fail_loc=0
9797         done
9798         set_checksums 0
9799         set_checksum_type $ORIG_CSUM_TYPE
9800         rm -f $DIR/$tfile
9801 }
9802 run_test 77b "checksum error on client write, read"
9803
9804 cleanup_77c() {
9805         trap 0
9806         set_checksums 0
9807         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9808         $check_ost &&
9809                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9810         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9811         $check_ost && [ -n "$ost_file_prefix" ] &&
9812                 do_facet ost1 rm -f ${ost_file_prefix}\*
9813 }
9814
9815 test_77c() {
9816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9817         $GSS && skip_env "could not run with gss"
9818         remote_ost_nodsh && skip "remote OST with nodsh"
9819
9820         local bad1
9821         local osc_file_prefix
9822         local osc_file
9823         local check_ost=false
9824         local ost_file_prefix
9825         local ost_file
9826         local orig_cksum
9827         local dump_cksum
9828         local fid
9829
9830         # ensure corruption will occur on first OSS/OST
9831         $LFS setstripe -i 0 $DIR/$tfile
9832
9833         [ ! -f $F77_TMP ] && setup_f77
9834         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9835                 error "dd write error: $?"
9836         fid=$($LFS path2fid $DIR/$tfile)
9837
9838         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9839         then
9840                 check_ost=true
9841                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9842                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9843         else
9844                 echo "OSS do not support bulk pages dump upon error"
9845         fi
9846
9847         osc_file_prefix=$($LCTL get_param -n debug_path)
9848         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9849
9850         trap cleanup_77c EXIT
9851
9852         set_checksums 1
9853         # enable bulk pages dump upon error on Client
9854         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9855         # enable bulk pages dump upon error on OSS
9856         $check_ost &&
9857                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9858
9859         # flush Client cache to allow next read to reach OSS
9860         cancel_lru_locks osc
9861
9862         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9863         $LCTL set_param fail_loc=0x80000408
9864         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9865         $LCTL set_param fail_loc=0
9866
9867         rm -f $DIR/$tfile
9868
9869         # check cksum dump on Client
9870         osc_file=$(ls ${osc_file_prefix}*)
9871         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9872         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9873         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9874         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9875         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9876                      cksum)
9877         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9878         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9879                 error "dump content does not match on Client"
9880
9881         $check_ost || skip "No need to check cksum dump on OSS"
9882
9883         # check cksum dump on OSS
9884         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9885         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9886         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9887         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9888         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9889                 error "dump content does not match on OSS"
9890
9891         cleanup_77c
9892 }
9893 run_test 77c "checksum error on client read with debug"
9894
9895 test_77d() { # bug 10889
9896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9897         $GSS && skip_env "could not run with gss"
9898
9899         stack_trap "rm -f $DIR/$tfile"
9900         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9901         $LCTL set_param fail_loc=0x80000409
9902         set_checksums 1
9903         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9904                 error "direct write: rc=$?"
9905         $LCTL set_param fail_loc=0
9906         set_checksums 0
9907
9908         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9909         $LCTL set_param fail_loc=0x80000408
9910         set_checksums 1
9911         cancel_lru_locks osc
9912         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9913                 error "direct read: rc=$?"
9914         $LCTL set_param fail_loc=0
9915         set_checksums 0
9916 }
9917 run_test 77d "checksum error on OST direct write, read"
9918
9919 test_77f() { # bug 10889
9920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9921         $GSS && skip_env "could not run with gss"
9922
9923         set_checksums 1
9924         stack_trap "rm -f $DIR/$tfile"
9925         for algo in $CKSUM_TYPES; do
9926                 cancel_lru_locks osc
9927                 set_checksum_type $algo
9928                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9929                 $LCTL set_param fail_loc=0x409
9930                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9931                         error "direct write succeeded"
9932                 $LCTL set_param fail_loc=0
9933         done
9934         set_checksum_type $ORIG_CSUM_TYPE
9935         set_checksums 0
9936 }
9937 run_test 77f "repeat checksum error on write (expect error)"
9938
9939 test_77g() { # bug 10889
9940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9941         $GSS && skip_env "could not run with gss"
9942         remote_ost_nodsh && skip "remote OST with nodsh"
9943
9944         [ ! -f $F77_TMP ] && setup_f77
9945
9946         local file=$DIR/$tfile
9947         stack_trap "rm -f $file" EXIT
9948
9949         $LFS setstripe -c 1 -i 0 $file
9950         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9951         do_facet ost1 lctl set_param fail_loc=0x8000021a
9952         set_checksums 1
9953         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9954                 error "write error: rc=$?"
9955         do_facet ost1 lctl set_param fail_loc=0
9956         set_checksums 0
9957
9958         cancel_lru_locks osc
9959         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9960         do_facet ost1 lctl set_param fail_loc=0x8000021b
9961         set_checksums 1
9962         cmp $F77_TMP $file || error "file compare failed"
9963         do_facet ost1 lctl set_param fail_loc=0
9964         set_checksums 0
9965 }
9966 run_test 77g "checksum error on OST write, read"
9967
9968 test_77k() { # LU-10906
9969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9970         $GSS && skip_env "could not run with gss"
9971
9972         local cksum_param="osc.$FSNAME*.checksums"
9973         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9974         local checksum
9975         local i
9976
9977         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9978         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9979         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9980
9981         for i in 0 1; do
9982                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9983                         error "failed to set checksum=$i on MGS"
9984                 wait_update $HOSTNAME "$get_checksum" $i
9985                 #remount
9986                 echo "remount client, checksum should be $i"
9987                 remount_client $MOUNT || error "failed to remount client"
9988                 checksum=$(eval $get_checksum)
9989                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9990         done
9991         # remove persistent param to avoid races with checksum mountopt below
9992         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9993                 error "failed to delete checksum on MGS"
9994
9995         for opt in "checksum" "nochecksum"; do
9996                 #remount with mount option
9997                 echo "remount client with option $opt, checksum should be $i"
9998                 umount_client $MOUNT || error "failed to umount client"
9999                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10000                         error "failed to mount client with option '$opt'"
10001                 checksum=$(eval $get_checksum)
10002                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10003                 i=$((i - 1))
10004         done
10005
10006         remount_client $MOUNT || error "failed to remount client"
10007 }
10008 run_test 77k "enable/disable checksum correctly"
10009
10010 test_77l() {
10011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10012         $GSS && skip_env "could not run with gss"
10013
10014         set_checksums 1
10015         stack_trap "set_checksums $ORIG_CSUM" EXIT
10016         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10017
10018         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10019
10020         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10021         for algo in $CKSUM_TYPES; do
10022                 set_checksum_type $algo || error "fail to set checksum type $algo"
10023                 osc_algo=$(get_osc_checksum_type OST0000)
10024                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10025
10026                 # no locks, no reqs to let the connection idle
10027                 cancel_lru_locks osc
10028                 lru_resize_disable osc
10029                 wait_osc_import_state client ost1 IDLE
10030
10031                 # ensure ost1 is connected
10032                 stat $DIR/$tfile >/dev/null || error "can't stat"
10033                 wait_osc_import_state client ost1 FULL
10034
10035                 osc_algo=$(get_osc_checksum_type OST0000)
10036                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10037         done
10038         return 0
10039 }
10040 run_test 77l "preferred checksum type is remembered after reconnected"
10041
10042 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10043 rm -f $F77_TMP
10044 unset F77_TMP
10045
10046 test_77m() {
10047         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10048                 skip "Need at least version 2.14.52"
10049         local param=checksum_speed
10050
10051         $LCTL get_param $param || error "reading $param failed"
10052
10053         csum_speeds=$($LCTL get_param -n $param)
10054
10055         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10056                 error "known checksum types are missing"
10057 }
10058 run_test 77m "Verify checksum_speed is correctly read"
10059
10060 check_filefrag_77n() {
10061         local nr_ext=0
10062         local starts=()
10063         local ends=()
10064
10065         while read extidx a b start end rest; do
10066                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10067                         nr_ext=$(( $nr_ext + 1 ))
10068                         starts+=( ${start%..} )
10069                         ends+=( ${end%:} )
10070                 fi
10071         done < <( filefrag -sv $1 )
10072
10073         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10074         return 1
10075 }
10076
10077 test_77n() {
10078         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10079
10080         touch $DIR/$tfile
10081         $TRUNCATE $DIR/$tfile 0
10082         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10083         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10084         check_filefrag_77n $DIR/$tfile ||
10085                 skip "$tfile blocks not contiguous around hole"
10086
10087         set_checksums 1
10088         stack_trap "set_checksums $ORIG_CSUM" EXIT
10089         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10090         stack_trap "rm -f $DIR/$tfile"
10091
10092         for algo in $CKSUM_TYPES; do
10093                 if [[ "$algo" =~ ^t10 ]]; then
10094                         set_checksum_type $algo ||
10095                                 error "fail to set checksum type $algo"
10096                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10097                                 error "fail to read $tfile with $algo"
10098                 fi
10099         done
10100         rm -f $DIR/$tfile
10101         return 0
10102 }
10103 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10104
10105 test_77o() {
10106         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10107                 skip "Need MDS version at least 2.14.55"
10108         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10109                 skip "Need OST version at least 2.14.55"
10110         local ofd=obdfilter
10111         local mdt=mdt
10112
10113         # print OST checksum_type
10114         echo "$ofd.$FSNAME-*.checksum_type:"
10115         do_nodes $(comma_list $(osts_nodes)) \
10116                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10117
10118         # print MDT checksum_type
10119         echo "$mdt.$FSNAME-*.checksum_type:"
10120         do_nodes $(comma_list $(mdts_nodes)) \
10121                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10122
10123         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10124                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10125
10126         (( $o_count == $OSTCOUNT )) ||
10127                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10128
10129         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10130                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10131
10132         (( $m_count == $MDSCOUNT )) ||
10133                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10134 }
10135 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10136
10137 cleanup_test_78() {
10138         trap 0
10139         rm -f $DIR/$tfile
10140 }
10141
10142 test_78() { # bug 10901
10143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10144         remote_ost || skip_env "local OST"
10145
10146         NSEQ=5
10147         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10148         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10149         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10150         echo "MemTotal: $MEMTOTAL"
10151
10152         # reserve 256MB of memory for the kernel and other running processes,
10153         # and then take 1/2 of the remaining memory for the read/write buffers.
10154         if [ $MEMTOTAL -gt 512 ] ;then
10155                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10156         else
10157                 # for those poor memory-starved high-end clusters...
10158                 MEMTOTAL=$((MEMTOTAL / 2))
10159         fi
10160         echo "Mem to use for directio: $MEMTOTAL"
10161
10162         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10163         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10164         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10165         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10166                 head -n1)
10167         echo "Smallest OST: $SMALLESTOST"
10168         [[ $SMALLESTOST -lt 10240 ]] &&
10169                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10170
10171         trap cleanup_test_78 EXIT
10172
10173         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10174                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10175
10176         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10177         echo "File size: $F78SIZE"
10178         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10179         for i in $(seq 1 $NSEQ); do
10180                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10181                 echo directIO rdwr round $i of $NSEQ
10182                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10183         done
10184
10185         cleanup_test_78
10186 }
10187 run_test 78 "handle large O_DIRECT writes correctly ============"
10188
10189 test_79() { # bug 12743
10190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10191
10192         wait_delete_completed
10193
10194         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10195         BKFREE=$(calc_osc_kbytes kbytesfree)
10196         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10197
10198         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10199         DFTOTAL=`echo $STRING | cut -d, -f1`
10200         DFUSED=`echo $STRING  | cut -d, -f2`
10201         DFAVAIL=`echo $STRING | cut -d, -f3`
10202         DFFREE=$(($DFTOTAL - $DFUSED))
10203
10204         ALLOWANCE=$((64 * $OSTCOUNT))
10205
10206         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10207            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10208                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10209         fi
10210         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10211            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10212                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10213         fi
10214         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10215            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10216                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10217         fi
10218 }
10219 run_test 79 "df report consistency check ======================="
10220
10221 test_80() { # bug 10718
10222         remote_ost_nodsh && skip "remote OST with nodsh"
10223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10224
10225         # relax strong synchronous semantics for slow backends like ZFS
10226         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10227                 local soc="obdfilter.*.sync_lock_cancel"
10228                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10229
10230                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10231                 if [ -z "$save" ]; then
10232                         soc="obdfilter.*.sync_on_lock_cancel"
10233                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10234                 fi
10235
10236                 if [ "$save" != "never" ]; then
10237                         local hosts=$(comma_list $(osts_nodes))
10238
10239                         do_nodes $hosts $LCTL set_param $soc=never
10240                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10241                 fi
10242         fi
10243
10244         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10245         sync; sleep 1; sync
10246         local before=$(date +%s)
10247         cancel_lru_locks osc
10248         local after=$(date +%s)
10249         local diff=$((after - before))
10250         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10251
10252         rm -f $DIR/$tfile
10253 }
10254 run_test 80 "Page eviction is equally fast at high offsets too"
10255
10256 test_81a() { # LU-456
10257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10258         remote_ost_nodsh && skip "remote OST with nodsh"
10259
10260         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10261         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10262         do_facet ost1 lctl set_param fail_loc=0x80000228
10263
10264         # write should trigger a retry and success
10265         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10266         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10267         RC=$?
10268         if [ $RC -ne 0 ] ; then
10269                 error "write should success, but failed for $RC"
10270         fi
10271 }
10272 run_test 81a "OST should retry write when get -ENOSPC ==============="
10273
10274 test_81b() { # LU-456
10275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10276         remote_ost_nodsh && skip "remote OST with nodsh"
10277
10278         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10279         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10280         do_facet ost1 lctl set_param fail_loc=0x228
10281
10282         # write should retry several times and return -ENOSPC finally
10283         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10284         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10285         RC=$?
10286         ENOSPC=28
10287         if [ $RC -ne $ENOSPC ] ; then
10288                 error "dd should fail for -ENOSPC, but succeed."
10289         fi
10290 }
10291 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10292
10293 test_99() {
10294         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10295
10296         test_mkdir $DIR/$tdir.cvsroot
10297         chown $RUNAS_ID $DIR/$tdir.cvsroot
10298
10299         cd $TMP
10300         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10301
10302         cd /etc/init.d
10303         # some versions of cvs import exit(1) when asked to import links or
10304         # files they can't read.  ignore those files.
10305         local toignore=$(find . -type l -printf '-I %f\n' -o \
10306                          ! -perm /4 -printf '-I %f\n')
10307         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10308                 $tdir.reposname vtag rtag
10309
10310         cd $DIR
10311         test_mkdir $DIR/$tdir.reposname
10312         chown $RUNAS_ID $DIR/$tdir.reposname
10313         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10314
10315         cd $DIR/$tdir.reposname
10316         $RUNAS touch foo99
10317         $RUNAS cvs add -m 'addmsg' foo99
10318         $RUNAS cvs update
10319         $RUNAS cvs commit -m 'nomsg' foo99
10320         rm -fr $DIR/$tdir.cvsroot
10321 }
10322 run_test 99 "cvs strange file/directory operations"
10323
10324 test_100() {
10325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10326         [[ "$NETTYPE" =~ tcp ]] ||
10327                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10328         remote_ost_nodsh && skip "remote OST with nodsh"
10329         remote_mds_nodsh && skip "remote MDS with nodsh"
10330         remote_servers ||
10331                 skip "useless for local single node setup"
10332
10333         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10334                 [ "$PROT" != "tcp" ] && continue
10335                 RPORT=$(echo $REMOTE | cut -d: -f2)
10336                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10337
10338                 rc=0
10339                 LPORT=`echo $LOCAL | cut -d: -f2`
10340                 if [ $LPORT -ge 1024 ]; then
10341                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10342                         netstat -tna
10343                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10344                 fi
10345         done
10346         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10347 }
10348 run_test 100 "check local port using privileged port ==========="
10349
10350 function get_named_value()
10351 {
10352     local tag=$1
10353
10354     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10355 }
10356
10357 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10358                    awk '/^max_cached_mb/ { print $2 }')
10359
10360 cleanup_101a() {
10361         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10362         trap 0
10363 }
10364
10365 test_101a() {
10366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10367
10368         local s
10369         local discard
10370         local nreads=10000
10371         local cache_limit=32
10372
10373         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10374         trap cleanup_101a EXIT
10375         $LCTL set_param -n llite.*.read_ahead_stats=0
10376         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10377
10378         #
10379         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10380         #
10381         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10382         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10383
10384         discard=0
10385         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10386                    get_named_value 'read.but.discarded'); do
10387                         discard=$(($discard + $s))
10388         done
10389         cleanup_101a
10390
10391         $LCTL get_param osc.*-osc*.rpc_stats
10392         $LCTL get_param llite.*.read_ahead_stats
10393
10394         # Discard is generally zero, but sometimes a few random reads line up
10395         # and trigger larger readahead, which is wasted & leads to discards.
10396         if [[ $(($discard)) -gt $nreads ]]; then
10397                 error "too many ($discard) discarded pages"
10398         fi
10399         rm -f $DIR/$tfile || true
10400 }
10401 run_test 101a "check read-ahead for random reads"
10402
10403 setup_test101bc() {
10404         test_mkdir $DIR/$tdir
10405         local ssize=$1
10406         local FILE_LENGTH=$2
10407         STRIPE_OFFSET=0
10408
10409         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10410
10411         local list=$(comma_list $(osts_nodes))
10412         set_osd_param $list '' read_cache_enable 0
10413         set_osd_param $list '' writethrough_cache_enable 0
10414
10415         trap cleanup_test101bc EXIT
10416         # prepare the read-ahead file
10417         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10418
10419         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10420                                 count=$FILE_SIZE_MB 2> /dev/null
10421
10422 }
10423
10424 cleanup_test101bc() {
10425         trap 0
10426         rm -rf $DIR/$tdir
10427         rm -f $DIR/$tfile
10428
10429         local list=$(comma_list $(osts_nodes))
10430         set_osd_param $list '' read_cache_enable 1
10431         set_osd_param $list '' writethrough_cache_enable 1
10432 }
10433
10434 calc_total() {
10435         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10436 }
10437
10438 ra_check_101() {
10439         local read_size=$1
10440         local stripe_size=$2
10441         local stride_length=$((stripe_size / read_size))
10442         local stride_width=$((stride_length * OSTCOUNT))
10443         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10444                                 (stride_width - stride_length) ))
10445         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10446                   get_named_value 'read.but.discarded' | calc_total)
10447
10448         if [[ $discard -gt $discard_limit ]]; then
10449                 $LCTL get_param llite.*.read_ahead_stats
10450                 error "($discard) discarded pages with size (${read_size})"
10451         else
10452                 echo "Read-ahead success for size ${read_size}"
10453         fi
10454 }
10455
10456 test_101b() {
10457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10458         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10459
10460         local STRIPE_SIZE=1048576
10461         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10462
10463         if [ $SLOW == "yes" ]; then
10464                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10465         else
10466                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10467         fi
10468
10469         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10470
10471         # prepare the read-ahead file
10472         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10473         cancel_lru_locks osc
10474         for BIDX in 2 4 8 16 32 64 128 256
10475         do
10476                 local BSIZE=$((BIDX*4096))
10477                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10478                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10479                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10480                 $LCTL set_param -n llite.*.read_ahead_stats=0
10481                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10482                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10483                 cancel_lru_locks osc
10484                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10485         done
10486         cleanup_test101bc
10487         true
10488 }
10489 run_test 101b "check stride-io mode read-ahead ================="
10490
10491 test_101c() {
10492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10493
10494         local STRIPE_SIZE=1048576
10495         local FILE_LENGTH=$((STRIPE_SIZE*100))
10496         local nreads=10000
10497         local rsize=65536
10498         local osc_rpc_stats
10499
10500         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10501
10502         cancel_lru_locks osc
10503         $LCTL set_param osc.*.rpc_stats=0
10504         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10505         $LCTL get_param osc.*.rpc_stats
10506         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10507                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10508                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10509                 local size
10510
10511                 if [ $lines -le 20 ]; then
10512                         echo "continue debug"
10513                         continue
10514                 fi
10515                 for size in 1 2 4 8; do
10516                         local rpc=$(echo "$stats" |
10517                                     awk '($1 == "'$size':") {print $2; exit; }')
10518                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10519                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10520                 done
10521                 echo "$osc_rpc_stats check passed!"
10522         done
10523         cleanup_test101bc
10524         true
10525 }
10526 run_test 101c "check stripe_size aligned read-ahead"
10527
10528 test_101d() {
10529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10530
10531         local file=$DIR/$tfile
10532         local sz_MB=${FILESIZE_101d:-80}
10533         local ra_MB=${READAHEAD_MB:-40}
10534
10535         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10536         [ $free_MB -lt $sz_MB ] &&
10537                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10538
10539         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10540         $LFS setstripe -c -1 $file || error "setstripe failed"
10541
10542         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10543         echo Cancel LRU locks on lustre client to flush the client cache
10544         cancel_lru_locks osc
10545
10546         echo Disable read-ahead
10547         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10548         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10549         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10550         $LCTL get_param -n llite.*.max_read_ahead_mb
10551
10552         echo "Reading the test file $file with read-ahead disabled"
10553         local sz_KB=$((sz_MB * 1024 / 4))
10554         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10555         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10556         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10557                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10558
10559         echo "Cancel LRU locks on lustre client to flush the client cache"
10560         cancel_lru_locks osc
10561         echo Enable read-ahead with ${ra_MB}MB
10562         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10563
10564         echo "Reading the test file $file with read-ahead enabled"
10565         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10566                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10567
10568         echo "read-ahead disabled time read $raOFF"
10569         echo "read-ahead enabled time read $raON"
10570
10571         rm -f $file
10572         wait_delete_completed
10573
10574         # use awk for this check instead of bash because it handles decimals
10575         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10576                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10577 }
10578 run_test 101d "file read with and without read-ahead enabled"
10579
10580 test_101e() {
10581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10582
10583         local file=$DIR/$tfile
10584         local size_KB=500  #KB
10585         local count=100
10586         local bsize=1024
10587
10588         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10589         local need_KB=$((count * size_KB))
10590         [[ $free_KB -le $need_KB ]] &&
10591                 skip_env "Need free space $need_KB, have $free_KB"
10592
10593         echo "Creating $count ${size_KB}K test files"
10594         for ((i = 0; i < $count; i++)); do
10595                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10596         done
10597
10598         echo "Cancel LRU locks on lustre client to flush the client cache"
10599         cancel_lru_locks $OSC
10600
10601         echo "Reset readahead stats"
10602         $LCTL set_param -n llite.*.read_ahead_stats=0
10603
10604         for ((i = 0; i < $count; i++)); do
10605                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10606         done
10607
10608         $LCTL get_param llite.*.max_cached_mb
10609         $LCTL get_param llite.*.read_ahead_stats
10610         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10611                      get_named_value 'misses' | calc_total)
10612
10613         for ((i = 0; i < $count; i++)); do
10614                 rm -rf $file.$i 2>/dev/null
10615         done
10616
10617         #10000 means 20% reads are missing in readahead
10618         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10619 }
10620 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10621
10622 test_101f() {
10623         which iozone || skip_env "no iozone installed"
10624
10625         local old_debug=$($LCTL get_param debug)
10626         old_debug=${old_debug#*=}
10627         $LCTL set_param debug="reada mmap"
10628
10629         # create a test file
10630         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10631
10632         echo Cancel LRU locks on lustre client to flush the client cache
10633         cancel_lru_locks osc
10634
10635         echo Reset readahead stats
10636         $LCTL set_param -n llite.*.read_ahead_stats=0
10637
10638         echo mmap read the file with small block size
10639         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10640                 > /dev/null 2>&1
10641
10642         echo checking missing pages
10643         $LCTL get_param llite.*.read_ahead_stats
10644         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10645                         get_named_value 'misses' | calc_total)
10646
10647         $LCTL set_param debug="$old_debug"
10648         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10649         rm -f $DIR/$tfile
10650 }
10651 run_test 101f "check mmap read performance"
10652
10653 test_101g_brw_size_test() {
10654         local mb=$1
10655         local pages=$((mb * 1048576 / PAGE_SIZE))
10656         local file=$DIR/$tfile
10657
10658         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10659                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10660         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10661                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10662                         return 2
10663         done
10664
10665         stack_trap "rm -f $file" EXIT
10666         $LCTL set_param -n osc.*.rpc_stats=0
10667
10668         # 10 RPCs should be enough for the test
10669         local count=10
10670         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10671                 { error "dd write ${mb} MB blocks failed"; return 3; }
10672         cancel_lru_locks osc
10673         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10674                 { error "dd write ${mb} MB blocks failed"; return 4; }
10675
10676         # calculate number of full-sized read and write RPCs
10677         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10678                 sed -n '/pages per rpc/,/^$/p' |
10679                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10680                 END { print reads,writes }'))
10681         # allow one extra full-sized read RPC for async readahead
10682         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10683                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10684         [[ ${rpcs[1]} == $count ]] ||
10685                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10686 }
10687
10688 test_101g() {
10689         remote_ost_nodsh && skip "remote OST with nodsh"
10690
10691         local rpcs
10692         local osts=$(get_facets OST)
10693         local list=$(comma_list $(osts_nodes))
10694         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10695         local brw_size="obdfilter.*.brw_size"
10696
10697         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10698
10699         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10700
10701         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10702                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10703                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10704            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10705                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10706                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10707
10708                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10709                         suffix="M"
10710
10711                 if [[ $orig_mb -lt 16 ]]; then
10712                         save_lustre_params $osts "$brw_size" > $p
10713                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10714                                 error "set 16MB RPC size failed"
10715
10716                         echo "remount client to enable new RPC size"
10717                         remount_client $MOUNT || error "remount_client failed"
10718                 fi
10719
10720                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10721                 # should be able to set brw_size=12, but no rpc_stats for that
10722                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10723         fi
10724
10725         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10726
10727         if [[ $orig_mb -lt 16 ]]; then
10728                 restore_lustre_params < $p
10729                 remount_client $MOUNT || error "remount_client restore failed"
10730         fi
10731
10732         rm -f $p $DIR/$tfile
10733 }
10734 run_test 101g "Big bulk(4/16 MiB) readahead"
10735
10736 test_101h() {
10737         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10738
10739         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10740                 error "dd 70M file failed"
10741         echo Cancel LRU locks on lustre client to flush the client cache
10742         cancel_lru_locks osc
10743
10744         echo "Reset readahead stats"
10745         $LCTL set_param -n llite.*.read_ahead_stats 0
10746
10747         echo "Read 10M of data but cross 64M bundary"
10748         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10749         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10750                      get_named_value 'misses' | calc_total)
10751         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10752         rm -f $p $DIR/$tfile
10753 }
10754 run_test 101h "Readahead should cover current read window"
10755
10756 test_101i() {
10757         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10758                 error "dd 10M file failed"
10759
10760         local max_per_file_mb=$($LCTL get_param -n \
10761                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10762         cancel_lru_locks osc
10763         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10764         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10765                 error "set max_read_ahead_per_file_mb to 1 failed"
10766
10767         echo "Reset readahead stats"
10768         $LCTL set_param llite.*.read_ahead_stats=0
10769
10770         dd if=$DIR/$tfile of=/dev/null bs=2M
10771
10772         $LCTL get_param llite.*.read_ahead_stats
10773         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10774                      awk '/misses/ { print $2 }')
10775         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10776         rm -f $DIR/$tfile
10777 }
10778 run_test 101i "allow current readahead to exceed reservation"
10779
10780 test_101j() {
10781         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10782                 error "setstripe $DIR/$tfile failed"
10783         local file_size=$((1048576 * 16))
10784         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10785         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10786
10787         echo Disable read-ahead
10788         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10789
10790         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10791         for blk in $PAGE_SIZE 1048576 $file_size; do
10792                 cancel_lru_locks osc
10793                 echo "Reset readahead stats"
10794                 $LCTL set_param -n llite.*.read_ahead_stats=0
10795                 local count=$(($file_size / $blk))
10796                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10797                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10798                              get_named_value 'failed.to.fast.read' | calc_total)
10799                 $LCTL get_param -n llite.*.read_ahead_stats
10800                 [ $miss -eq $count ] || error "expected $count got $miss"
10801         done
10802
10803         rm -f $p $DIR/$tfile
10804 }
10805 run_test 101j "A complete read block should be submitted when no RA"
10806
10807 setup_test102() {
10808         test_mkdir $DIR/$tdir
10809         chown $RUNAS_ID $DIR/$tdir
10810         STRIPE_SIZE=65536
10811         STRIPE_OFFSET=1
10812         STRIPE_COUNT=$OSTCOUNT
10813         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10814
10815         trap cleanup_test102 EXIT
10816         cd $DIR
10817         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10818         cd $DIR/$tdir
10819         for num in 1 2 3 4; do
10820                 for count in $(seq 1 $STRIPE_COUNT); do
10821                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10822                                 local size=`expr $STRIPE_SIZE \* $num`
10823                                 local file=file"$num-$idx-$count"
10824                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10825                         done
10826                 done
10827         done
10828
10829         cd $DIR
10830         $1 tar cf $TMP/f102.tar $tdir --xattrs
10831 }
10832
10833 cleanup_test102() {
10834         trap 0
10835         rm -f $TMP/f102.tar
10836         rm -rf $DIR/d0.sanity/d102
10837 }
10838
10839 test_102a() {
10840         [ "$UID" != 0 ] && skip "must run as root"
10841         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10842                 skip_env "must have user_xattr"
10843
10844         [ -z "$(which setfattr 2>/dev/null)" ] &&
10845                 skip_env "could not find setfattr"
10846
10847         local testfile=$DIR/$tfile
10848
10849         touch $testfile
10850         echo "set/get xattr..."
10851         setfattr -n trusted.name1 -v value1 $testfile ||
10852                 error "setfattr -n trusted.name1=value1 $testfile failed"
10853         getfattr -n trusted.name1 $testfile 2> /dev/null |
10854           grep "trusted.name1=.value1" ||
10855                 error "$testfile missing trusted.name1=value1"
10856
10857         setfattr -n user.author1 -v author1 $testfile ||
10858                 error "setfattr -n user.author1=author1 $testfile failed"
10859         getfattr -n user.author1 $testfile 2> /dev/null |
10860           grep "user.author1=.author1" ||
10861                 error "$testfile missing trusted.author1=author1"
10862
10863         echo "listxattr..."
10864         setfattr -n trusted.name2 -v value2 $testfile ||
10865                 error "$testfile unable to set trusted.name2"
10866         setfattr -n trusted.name3 -v value3 $testfile ||
10867                 error "$testfile unable to set trusted.name3"
10868         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10869             grep "trusted.name" | wc -l) -eq 3 ] ||
10870                 error "$testfile missing 3 trusted.name xattrs"
10871
10872         setfattr -n user.author2 -v author2 $testfile ||
10873                 error "$testfile unable to set user.author2"
10874         setfattr -n user.author3 -v author3 $testfile ||
10875                 error "$testfile unable to set user.author3"
10876         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10877             grep "user.author" | wc -l) -eq 3 ] ||
10878                 error "$testfile missing 3 user.author xattrs"
10879
10880         echo "remove xattr..."
10881         setfattr -x trusted.name1 $testfile ||
10882                 error "$testfile error deleting trusted.name1"
10883         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10884                 error "$testfile did not delete trusted.name1 xattr"
10885
10886         setfattr -x user.author1 $testfile ||
10887                 error "$testfile error deleting user.author1"
10888         echo "set lustre special xattr ..."
10889         $LFS setstripe -c1 $testfile
10890         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10891                 awk -F "=" '/trusted.lov/ { print $2 }' )
10892         setfattr -n "trusted.lov" -v $lovea $testfile ||
10893                 error "$testfile doesn't ignore setting trusted.lov again"
10894         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10895                 error "$testfile allow setting invalid trusted.lov"
10896         rm -f $testfile
10897 }
10898 run_test 102a "user xattr test =================================="
10899
10900 check_102b_layout() {
10901         local layout="$*"
10902         local testfile=$DIR/$tfile
10903
10904         echo "test layout '$layout'"
10905         $LFS setstripe $layout $testfile || error "setstripe failed"
10906         $LFS getstripe -y $testfile
10907
10908         echo "get/set/list trusted.lov xattr ..." # b=10930
10909         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10910         [[ "$value" =~ "trusted.lov" ]] ||
10911                 error "can't get trusted.lov from $testfile"
10912         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10913                 error "getstripe failed"
10914
10915         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10916
10917         value=$(cut -d= -f2 <<<$value)
10918         # LU-13168: truncated xattr should fail if short lov_user_md header
10919         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10920                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10921         for len in $lens; do
10922                 echo "setfattr $len $testfile.2"
10923                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10924                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10925         done
10926         local stripe_size=$($LFS getstripe -S $testfile.2)
10927         local stripe_count=$($LFS getstripe -c $testfile.2)
10928         [[ $stripe_size -eq 65536 ]] ||
10929                 error "stripe size $stripe_size != 65536"
10930         [[ $stripe_count -eq $stripe_count_orig ]] ||
10931                 error "stripe count $stripe_count != $stripe_count_orig"
10932         rm $testfile $testfile.2
10933 }
10934
10935 test_102b() {
10936         [ -z "$(which setfattr 2>/dev/null)" ] &&
10937                 skip_env "could not find setfattr"
10938         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10939
10940         # check plain layout
10941         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10942
10943         # and also check composite layout
10944         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10945
10946 }
10947 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10948
10949 test_102c() {
10950         [ -z "$(which setfattr 2>/dev/null)" ] &&
10951                 skip_env "could not find setfattr"
10952         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10953
10954         # b10930: get/set/list lustre.lov xattr
10955         echo "get/set/list lustre.lov xattr ..."
10956         test_mkdir $DIR/$tdir
10957         chown $RUNAS_ID $DIR/$tdir
10958         local testfile=$DIR/$tdir/$tfile
10959         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10960                 error "setstripe failed"
10961         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10962                 error "getstripe failed"
10963         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10964         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10965
10966         local testfile2=${testfile}2
10967         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10968                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10969
10970         $RUNAS $MCREATE $testfile2
10971         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10972         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10973         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10974         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10975         [ $stripe_count -eq $STRIPECOUNT ] ||
10976                 error "stripe count $stripe_count != $STRIPECOUNT"
10977 }
10978 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10979
10980 compare_stripe_info1() {
10981         local stripe_index_all_zero=true
10982
10983         for num in 1 2 3 4; do
10984                 for count in $(seq 1 $STRIPE_COUNT); do
10985                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10986                                 local size=$((STRIPE_SIZE * num))
10987                                 local file=file"$num-$offset-$count"
10988                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10989                                 [[ $stripe_size -ne $size ]] &&
10990                                     error "$file: size $stripe_size != $size"
10991                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10992                                 # allow fewer stripes to be created, ORI-601
10993                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10994                                     error "$file: count $stripe_count != $count"
10995                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10996                                 [[ $stripe_index -ne 0 ]] &&
10997                                         stripe_index_all_zero=false
10998                         done
10999                 done
11000         done
11001         $stripe_index_all_zero &&
11002                 error "all files are being extracted starting from OST index 0"
11003         return 0
11004 }
11005
11006 have_xattrs_include() {
11007         tar --help | grep -q xattrs-include &&
11008                 echo --xattrs-include="lustre.*"
11009 }
11010
11011 test_102d() {
11012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11013         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11014
11015         XINC=$(have_xattrs_include)
11016         setup_test102
11017         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11018         cd $DIR/$tdir/$tdir
11019         compare_stripe_info1
11020 }
11021 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11022
11023 test_102f() {
11024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11025         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11026
11027         XINC=$(have_xattrs_include)
11028         setup_test102
11029         test_mkdir $DIR/$tdir.restore
11030         cd $DIR
11031         tar cf - --xattrs $tdir | tar xf - \
11032                 -C $DIR/$tdir.restore --xattrs $XINC
11033         cd $DIR/$tdir.restore/$tdir
11034         compare_stripe_info1
11035 }
11036 run_test 102f "tar copy files, not keep osts"
11037
11038 grow_xattr() {
11039         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11040                 skip "must have user_xattr"
11041         [ -z "$(which setfattr 2>/dev/null)" ] &&
11042                 skip_env "could not find setfattr"
11043         [ -z "$(which getfattr 2>/dev/null)" ] &&
11044                 skip_env "could not find getfattr"
11045
11046         local xsize=${1:-1024}  # in bytes
11047         local file=$DIR/$tfile
11048         local value="$(generate_string $xsize)"
11049         local xbig=trusted.big
11050         local toobig=$2
11051
11052         touch $file
11053         log "save $xbig on $file"
11054         if [ -z "$toobig" ]
11055         then
11056                 setfattr -n $xbig -v $value $file ||
11057                         error "saving $xbig on $file failed"
11058         else
11059                 setfattr -n $xbig -v $value $file &&
11060                         error "saving $xbig on $file succeeded"
11061                 return 0
11062         fi
11063
11064         local orig=$(get_xattr_value $xbig $file)
11065         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11066
11067         local xsml=trusted.sml
11068         log "save $xsml on $file"
11069         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11070
11071         local new=$(get_xattr_value $xbig $file)
11072         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11073
11074         log "grow $xsml on $file"
11075         setfattr -n $xsml -v "$value" $file ||
11076                 error "growing $xsml on $file failed"
11077
11078         new=$(get_xattr_value $xbig $file)
11079         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11080         log "$xbig still valid after growing $xsml"
11081
11082         rm -f $file
11083 }
11084
11085 test_102h() { # bug 15777
11086         grow_xattr 1024
11087 }
11088 run_test 102h "grow xattr from inside inode to external block"
11089
11090 test_102ha() {
11091         large_xattr_enabled || skip_env "ea_inode feature disabled"
11092
11093         echo "setting xattr of max xattr size: $(max_xattr_size)"
11094         grow_xattr $(max_xattr_size)
11095
11096         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11097         echo "This should fail:"
11098         grow_xattr $(($(max_xattr_size) + 10)) 1
11099 }
11100 run_test 102ha "grow xattr from inside inode to external inode"
11101
11102 test_102i() { # bug 17038
11103         [ -z "$(which getfattr 2>/dev/null)" ] &&
11104                 skip "could not find getfattr"
11105
11106         touch $DIR/$tfile
11107         ln -s $DIR/$tfile $DIR/${tfile}link
11108         getfattr -n trusted.lov $DIR/$tfile ||
11109                 error "lgetxattr on $DIR/$tfile failed"
11110         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11111                 grep -i "no such attr" ||
11112                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11113         rm -f $DIR/$tfile $DIR/${tfile}link
11114 }
11115 run_test 102i "lgetxattr test on symbolic link ============"
11116
11117 test_102j() {
11118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11119         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11120
11121         XINC=$(have_xattrs_include)
11122         setup_test102 "$RUNAS"
11123         chown $RUNAS_ID $DIR/$tdir
11124         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11125         cd $DIR/$tdir/$tdir
11126         compare_stripe_info1 "$RUNAS"
11127 }
11128 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11129
11130 test_102k() {
11131         [ -z "$(which setfattr 2>/dev/null)" ] &&
11132                 skip "could not find setfattr"
11133
11134         touch $DIR/$tfile
11135         # b22187 just check that does not crash for regular file.
11136         setfattr -n trusted.lov $DIR/$tfile
11137         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11138         local test_kdir=$DIR/$tdir
11139         test_mkdir $test_kdir
11140         local default_size=$($LFS getstripe -S $test_kdir)
11141         local default_count=$($LFS getstripe -c $test_kdir)
11142         local default_offset=$($LFS getstripe -i $test_kdir)
11143         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11144                 error 'dir setstripe failed'
11145         setfattr -n trusted.lov $test_kdir
11146         local stripe_size=$($LFS getstripe -S $test_kdir)
11147         local stripe_count=$($LFS getstripe -c $test_kdir)
11148         local stripe_offset=$($LFS getstripe -i $test_kdir)
11149         [ $stripe_size -eq $default_size ] ||
11150                 error "stripe size $stripe_size != $default_size"
11151         [ $stripe_count -eq $default_count ] ||
11152                 error "stripe count $stripe_count != $default_count"
11153         [ $stripe_offset -eq $default_offset ] ||
11154                 error "stripe offset $stripe_offset != $default_offset"
11155         rm -rf $DIR/$tfile $test_kdir
11156 }
11157 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11158
11159 test_102l() {
11160         [ -z "$(which getfattr 2>/dev/null)" ] &&
11161                 skip "could not find getfattr"
11162
11163         # LU-532 trusted. xattr is invisible to non-root
11164         local testfile=$DIR/$tfile
11165
11166         touch $testfile
11167
11168         echo "listxattr as user..."
11169         chown $RUNAS_ID $testfile
11170         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11171             grep -q "trusted" &&
11172                 error "$testfile trusted xattrs are user visible"
11173
11174         return 0;
11175 }
11176 run_test 102l "listxattr size test =================================="
11177
11178 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11179         local path=$DIR/$tfile
11180         touch $path
11181
11182         listxattr_size_check $path || error "listattr_size_check $path failed"
11183 }
11184 run_test 102m "Ensure listxattr fails on small bufffer ========"
11185
11186 cleanup_test102
11187
11188 getxattr() { # getxattr path name
11189         # Return the base64 encoding of the value of xattr name on path.
11190         local path=$1
11191         local name=$2
11192
11193         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11194         # file: $path
11195         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11196         #
11197         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11198
11199         getfattr --absolute-names --encoding=base64 --name=$name $path |
11200                 awk -F= -v name=$name '$1 == name {
11201                         print substr($0, index($0, "=") + 1);
11202         }'
11203 }
11204
11205 test_102n() { # LU-4101 mdt: protect internal xattrs
11206         [ -z "$(which setfattr 2>/dev/null)" ] &&
11207                 skip "could not find setfattr"
11208         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11209         then
11210                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11211         fi
11212
11213         local file0=$DIR/$tfile.0
11214         local file1=$DIR/$tfile.1
11215         local xattr0=$TMP/$tfile.0
11216         local xattr1=$TMP/$tfile.1
11217         local namelist="lov lma lmv link fid version som hsm"
11218         local name
11219         local value
11220
11221         rm -rf $file0 $file1 $xattr0 $xattr1
11222         touch $file0 $file1
11223
11224         # Get 'before' xattrs of $file1.
11225         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11226
11227         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11228                 namelist+=" lfsck_namespace"
11229         for name in $namelist; do
11230                 # Try to copy xattr from $file0 to $file1.
11231                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11232
11233                 setfattr --name=trusted.$name --value="$value" $file1 ||
11234                         error "setxattr 'trusted.$name' failed"
11235
11236                 # Try to set a garbage xattr.
11237                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11238
11239                 if [[ x$name == "xlov" ]]; then
11240                         setfattr --name=trusted.lov --value="$value" $file1 &&
11241                         error "setxattr invalid 'trusted.lov' success"
11242                 else
11243                         setfattr --name=trusted.$name --value="$value" $file1 ||
11244                                 error "setxattr invalid 'trusted.$name' failed"
11245                 fi
11246
11247                 # Try to remove the xattr from $file1. We don't care if this
11248                 # appears to succeed or fail, we just don't want there to be
11249                 # any changes or crashes.
11250                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11251         done
11252
11253         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11254         then
11255                 name="lfsck_ns"
11256                 # Try to copy xattr from $file0 to $file1.
11257                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11258
11259                 setfattr --name=trusted.$name --value="$value" $file1 ||
11260                         error "setxattr 'trusted.$name' failed"
11261
11262                 # Try to set a garbage xattr.
11263                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11264
11265                 setfattr --name=trusted.$name --value="$value" $file1 ||
11266                         error "setxattr 'trusted.$name' failed"
11267
11268                 # Try to remove the xattr from $file1. We don't care if this
11269                 # appears to succeed or fail, we just don't want there to be
11270                 # any changes or crashes.
11271                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11272         fi
11273
11274         # Get 'after' xattrs of file1.
11275         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11276
11277         if ! diff $xattr0 $xattr1; then
11278                 error "before and after xattrs of '$file1' differ"
11279         fi
11280
11281         rm -rf $file0 $file1 $xattr0 $xattr1
11282
11283         return 0
11284 }
11285 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11286
11287 test_102p() { # LU-4703 setxattr did not check ownership
11288         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11289                 skip "MDS needs to be at least 2.5.56"
11290
11291         local testfile=$DIR/$tfile
11292
11293         touch $testfile
11294
11295         echo "setfacl as user..."
11296         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11297         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11298
11299         echo "setfattr as user..."
11300         setfacl -m "u:$RUNAS_ID:---" $testfile
11301         $RUNAS setfattr -x system.posix_acl_access $testfile
11302         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11303 }
11304 run_test 102p "check setxattr(2) correctly fails without permission"
11305
11306 test_102q() {
11307         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11308                 skip "MDS needs to be at least 2.6.92"
11309
11310         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11311 }
11312 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11313
11314 test_102r() {
11315         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11316                 skip "MDS needs to be at least 2.6.93"
11317
11318         touch $DIR/$tfile || error "touch"
11319         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11320         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11321         rm $DIR/$tfile || error "rm"
11322
11323         #normal directory
11324         mkdir -p $DIR/$tdir || error "mkdir"
11325         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11326         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11327         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11328                 error "$testfile error deleting user.author1"
11329         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11330                 grep "user.$(basename $tdir)" &&
11331                 error "$tdir did not delete user.$(basename $tdir)"
11332         rmdir $DIR/$tdir || error "rmdir"
11333
11334         #striped directory
11335         test_mkdir $DIR/$tdir
11336         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11337         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11338         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11339                 error "$testfile error deleting user.author1"
11340         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11341                 grep "user.$(basename $tdir)" &&
11342                 error "$tdir did not delete user.$(basename $tdir)"
11343         rmdir $DIR/$tdir || error "rm striped dir"
11344 }
11345 run_test 102r "set EAs with empty values"
11346
11347 test_102s() {
11348         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11349                 skip "MDS needs to be at least 2.11.52"
11350
11351         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11352
11353         save_lustre_params client "llite.*.xattr_cache" > $save
11354
11355         for cache in 0 1; do
11356                 lctl set_param llite.*.xattr_cache=$cache
11357
11358                 rm -f $DIR/$tfile
11359                 touch $DIR/$tfile || error "touch"
11360                 for prefix in lustre security system trusted user; do
11361                         # Note getxattr() may fail with 'Operation not
11362                         # supported' or 'No such attribute' depending
11363                         # on prefix and cache.
11364                         getfattr -n $prefix.n102s $DIR/$tfile &&
11365                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11366                 done
11367         done
11368
11369         restore_lustre_params < $save
11370 }
11371 run_test 102s "getting nonexistent xattrs should fail"
11372
11373 test_102t() {
11374         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11375                 skip "MDS needs to be at least 2.11.52"
11376
11377         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11378
11379         save_lustre_params client "llite.*.xattr_cache" > $save
11380
11381         for cache in 0 1; do
11382                 lctl set_param llite.*.xattr_cache=$cache
11383
11384                 for buf_size in 0 256; do
11385                         rm -f $DIR/$tfile
11386                         touch $DIR/$tfile || error "touch"
11387                         setfattr -n user.multiop $DIR/$tfile
11388                         $MULTIOP $DIR/$tfile oa$buf_size ||
11389                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11390                 done
11391         done
11392
11393         restore_lustre_params < $save
11394 }
11395 run_test 102t "zero length xattr values handled correctly"
11396
11397 run_acl_subtest()
11398 {
11399     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11400     return $?
11401 }
11402
11403 test_103a() {
11404         [ "$UID" != 0 ] && skip "must run as root"
11405         $GSS && skip_env "could not run under gss"
11406         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11407                 skip_env "must have acl enabled"
11408         [ -z "$(which setfacl 2>/dev/null)" ] &&
11409                 skip_env "could not find setfacl"
11410         remote_mds_nodsh && skip "remote MDS with nodsh"
11411
11412         gpasswd -a daemon bin                           # LU-5641
11413         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11414
11415         declare -a identity_old
11416
11417         for num in $(seq $MDSCOUNT); do
11418                 switch_identity $num true || identity_old[$num]=$?
11419         done
11420
11421         SAVE_UMASK=$(umask)
11422         umask 0022
11423         mkdir -p $DIR/$tdir
11424         cd $DIR/$tdir
11425
11426         echo "performing cp ..."
11427         run_acl_subtest cp || error "run_acl_subtest cp failed"
11428         echo "performing getfacl-noacl..."
11429         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11430         echo "performing misc..."
11431         run_acl_subtest misc || error  "misc test failed"
11432         echo "performing permissions..."
11433         run_acl_subtest permissions || error "permissions failed"
11434         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11435         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11436                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11437                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11438         then
11439                 echo "performing permissions xattr..."
11440                 run_acl_subtest permissions_xattr ||
11441                         error "permissions_xattr failed"
11442         fi
11443         echo "performing setfacl..."
11444         run_acl_subtest setfacl || error  "setfacl test failed"
11445
11446         # inheritance test got from HP
11447         echo "performing inheritance..."
11448         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11449         chmod +x make-tree || error "chmod +x failed"
11450         run_acl_subtest inheritance || error "inheritance test failed"
11451         rm -f make-tree
11452
11453         echo "LU-974 ignore umask when acl is enabled..."
11454         run_acl_subtest 974 || error "LU-974 umask test failed"
11455         if [ $MDSCOUNT -ge 2 ]; then
11456                 run_acl_subtest 974_remote ||
11457                         error "LU-974 umask test failed under remote dir"
11458         fi
11459
11460         echo "LU-2561 newly created file is same size as directory..."
11461         if [ "$mds1_FSTYPE" != "zfs" ]; then
11462                 run_acl_subtest 2561 || error "LU-2561 test failed"
11463         else
11464                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11465         fi
11466
11467         run_acl_subtest 4924 || error "LU-4924 test failed"
11468
11469         cd $SAVE_PWD
11470         umask $SAVE_UMASK
11471
11472         for num in $(seq $MDSCOUNT); do
11473                 if [ "${identity_old[$num]}" = 1 ]; then
11474                         switch_identity $num false || identity_old[$num]=$?
11475                 fi
11476         done
11477 }
11478 run_test 103a "acl test"
11479
11480 test_103b() {
11481         declare -a pids
11482         local U
11483
11484         for U in {0..511}; do
11485                 {
11486                 local O=$(printf "%04o" $U)
11487
11488                 umask $(printf "%04o" $((511 ^ $O)))
11489                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11490                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11491
11492                 (( $S == ($O & 0666) )) ||
11493                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11494
11495                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11496                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11497                 (( $S == ($O & 0666) )) ||
11498                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11499
11500                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11501                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11502                 (( $S == ($O & 0666) )) ||
11503                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11504                 rm -f $DIR/$tfile.[smp]$0
11505                 } &
11506                 local pid=$!
11507
11508                 # limit the concurrently running threads to 64. LU-11878
11509                 local idx=$((U % 64))
11510                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11511                 pids[idx]=$pid
11512         done
11513         wait
11514 }
11515 run_test 103b "umask lfs setstripe"
11516
11517 test_103c() {
11518         mkdir -p $DIR/$tdir
11519         cp -rp $DIR/$tdir $DIR/$tdir.bak
11520
11521         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11522                 error "$DIR/$tdir shouldn't contain default ACL"
11523         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11524                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11525         true
11526 }
11527 run_test 103c "'cp -rp' won't set empty acl"
11528
11529 test_103e() {
11530         local numacl
11531         local fileacl
11532         local saved_debug=$($LCTL get_param -n debug)
11533
11534         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11535                 skip "MDS needs to be at least 2.14.52"
11536
11537         large_xattr_enabled || skip_env "ea_inode feature disabled"
11538
11539         mkdir -p $DIR/$tdir
11540         # add big LOV EA to cause reply buffer overflow earlier
11541         $LFS setstripe -C 1000 $DIR/$tdir
11542         lctl set_param mdc.*-mdc*.stats=clear
11543
11544         $LCTL set_param debug=0
11545         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11546         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11547
11548         # add a large number of default ACLs (expect 8000+ for 2.13+)
11549         for U in {2..7000}; do
11550                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11551                         error "Able to add just $U default ACLs"
11552         done
11553         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11554         echo "$numacl default ACLs created"
11555
11556         stat $DIR/$tdir || error "Cannot stat directory"
11557         # check file creation
11558         touch $DIR/$tdir/$tfile ||
11559                 error "failed to create $tfile with $numacl default ACLs"
11560         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11561         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11562         echo "$fileacl ACLs were inherited"
11563         (( $fileacl == $numacl )) ||
11564                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11565         # check that new ACLs creation adds new ACLs to inherited ACLs
11566         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11567                 error "Cannot set new ACL"
11568         numacl=$((numacl + 1))
11569         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11570         (( $fileacl == $numacl )) ||
11571                 error "failed to add new ACL: $fileacl != $numacl as expected"
11572         # adds more ACLs to a file to reach their maximum at 8000+
11573         numacl=0
11574         for U in {20000..25000}; do
11575                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11576                 numacl=$((numacl + 1))
11577         done
11578         echo "Added $numacl more ACLs to the file"
11579         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11580         echo "Total $fileacl ACLs in file"
11581         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11582         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11583         rmdir $DIR/$tdir || error "Cannot remove directory"
11584 }
11585 run_test 103e "inheritance of big amount of default ACLs"
11586
11587 test_103f() {
11588         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11589                 skip "MDS needs to be at least 2.14.51"
11590
11591         large_xattr_enabled || skip_env "ea_inode feature disabled"
11592
11593         # enable changelog to consume more internal MDD buffers
11594         changelog_register
11595
11596         mkdir -p $DIR/$tdir
11597         # add big LOV EA
11598         $LFS setstripe -C 1000 $DIR/$tdir
11599         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11600         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11601         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11602         rmdir $DIR/$tdir || error "Cannot remove directory"
11603 }
11604 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11605
11606 test_104a() {
11607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11608
11609         touch $DIR/$tfile
11610         lfs df || error "lfs df failed"
11611         lfs df -ih || error "lfs df -ih failed"
11612         lfs df -h $DIR || error "lfs df -h $DIR failed"
11613         lfs df -i $DIR || error "lfs df -i $DIR failed"
11614         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11615         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11616
11617         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11618         lctl --device %$OSC deactivate
11619         lfs df || error "lfs df with deactivated OSC failed"
11620         lctl --device %$OSC activate
11621         # wait the osc back to normal
11622         wait_osc_import_ready client ost
11623
11624         lfs df || error "lfs df with reactivated OSC failed"
11625         rm -f $DIR/$tfile
11626 }
11627 run_test 104a "lfs df [-ih] [path] test ========================="
11628
11629 test_104b() {
11630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11631         [ $RUNAS_ID -eq $UID ] &&
11632                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11633
11634         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11635                         grep "Permission denied" | wc -l)))
11636         if [ $denied_cnt -ne 0 ]; then
11637                 error "lfs check servers test failed"
11638         fi
11639 }
11640 run_test 104b "$RUNAS lfs check servers test ===================="
11641
11642 #
11643 # Verify $1 is within range of $2.
11644 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11645 # $1 is <= 2% of $2. Else Fail.
11646 #
11647 value_in_range() {
11648         # Strip all units (M, G, T)
11649         actual=$(echo $1 | tr -d A-Z)
11650         expect=$(echo $2 | tr -d A-Z)
11651
11652         expect_lo=$(($expect * 98 / 100)) # 2% below
11653         expect_hi=$(($expect * 102 / 100)) # 2% above
11654
11655         # permit 2% drift above and below
11656         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11657 }
11658
11659 test_104c() {
11660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11661         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11662
11663         local ost_param="osd-zfs.$FSNAME-OST0000."
11664         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11665         local ofacets=$(get_facets OST)
11666         local mfacets=$(get_facets MDS)
11667         local saved_ost_blocks=
11668         local saved_mdt_blocks=
11669
11670         echo "Before recordsize change"
11671         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11672         df=($(df -h | grep "/mnt/lustre"$))
11673
11674         # For checking.
11675         echo "lfs output : ${lfs_df[*]}"
11676         echo "df  output : ${df[*]}"
11677
11678         for facet in ${ofacets//,/ }; do
11679                 if [ -z $saved_ost_blocks ]; then
11680                         saved_ost_blocks=$(do_facet $facet \
11681                                 lctl get_param -n $ost_param.blocksize)
11682                         echo "OST Blocksize: $saved_ost_blocks"
11683                 fi
11684                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11685                 do_facet $facet zfs set recordsize=32768 $ost
11686         done
11687
11688         # BS too small. Sufficient for functional testing.
11689         for facet in ${mfacets//,/ }; do
11690                 if [ -z $saved_mdt_blocks ]; then
11691                         saved_mdt_blocks=$(do_facet $facet \
11692                                 lctl get_param -n $mdt_param.blocksize)
11693                         echo "MDT Blocksize: $saved_mdt_blocks"
11694                 fi
11695                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11696                 do_facet $facet zfs set recordsize=32768 $mdt
11697         done
11698
11699         # Give new values chance to reflect change
11700         sleep 2
11701
11702         echo "After recordsize change"
11703         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11704         df_after=($(df -h | grep "/mnt/lustre"$))
11705
11706         # For checking.
11707         echo "lfs output : ${lfs_df_after[*]}"
11708         echo "df  output : ${df_after[*]}"
11709
11710         # Verify lfs df
11711         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11712                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11713         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11714                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11715         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11716                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11717
11718         # Verify df
11719         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11720                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11721         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11722                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11723         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11724                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11725
11726         # Restore MDT recordize back to original
11727         for facet in ${mfacets//,/ }; do
11728                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11729                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11730         done
11731
11732         # Restore OST recordize back to original
11733         for facet in ${ofacets//,/ }; do
11734                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11735                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11736         done
11737
11738         return 0
11739 }
11740 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11741
11742 test_105a() {
11743         # doesn't work on 2.4 kernels
11744         touch $DIR/$tfile
11745         if $(flock_is_enabled); then
11746                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11747         else
11748                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11749         fi
11750         rm -f $DIR/$tfile
11751 }
11752 run_test 105a "flock when mounted without -o flock test ========"
11753
11754 test_105b() {
11755         touch $DIR/$tfile
11756         if $(flock_is_enabled); then
11757                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11758         else
11759                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11760         fi
11761         rm -f $DIR/$tfile
11762 }
11763 run_test 105b "fcntl when mounted without -o flock test ========"
11764
11765 test_105c() {
11766         touch $DIR/$tfile
11767         if $(flock_is_enabled); then
11768                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11769         else
11770                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11771         fi
11772         rm -f $DIR/$tfile
11773 }
11774 run_test 105c "lockf when mounted without -o flock test"
11775
11776 test_105d() { # bug 15924
11777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11778
11779         test_mkdir $DIR/$tdir
11780         flock_is_enabled || skip_env "mount w/o flock enabled"
11781         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11782         $LCTL set_param fail_loc=0x80000315
11783         flocks_test 2 $DIR/$tdir
11784 }
11785 run_test 105d "flock race (should not freeze) ========"
11786
11787 test_105e() { # bug 22660 && 22040
11788         flock_is_enabled || skip_env "mount w/o flock enabled"
11789
11790         touch $DIR/$tfile
11791         flocks_test 3 $DIR/$tfile
11792 }
11793 run_test 105e "Two conflicting flocks from same process"
11794
11795 test_106() { #bug 10921
11796         test_mkdir $DIR/$tdir
11797         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11798         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11799 }
11800 run_test 106 "attempt exec of dir followed by chown of that dir"
11801
11802 test_107() {
11803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11804
11805         CDIR=`pwd`
11806         local file=core
11807
11808         cd $DIR
11809         rm -f $file
11810
11811         local save_pattern=$(sysctl -n kernel.core_pattern)
11812         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11813         sysctl -w kernel.core_pattern=$file
11814         sysctl -w kernel.core_uses_pid=0
11815
11816         ulimit -c unlimited
11817         sleep 60 &
11818         SLEEPPID=$!
11819
11820         sleep 1
11821
11822         kill -s 11 $SLEEPPID
11823         wait $SLEEPPID
11824         if [ -e $file ]; then
11825                 size=`stat -c%s $file`
11826                 [ $size -eq 0 ] && error "Fail to create core file $file"
11827         else
11828                 error "Fail to create core file $file"
11829         fi
11830         rm -f $file
11831         sysctl -w kernel.core_pattern=$save_pattern
11832         sysctl -w kernel.core_uses_pid=$save_uses_pid
11833         cd $CDIR
11834 }
11835 run_test 107 "Coredump on SIG"
11836
11837 test_110() {
11838         test_mkdir $DIR/$tdir
11839         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11840         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11841                 error "mkdir with 256 char should fail, but did not"
11842         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11843                 error "create with 255 char failed"
11844         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11845                 error "create with 256 char should fail, but did not"
11846
11847         ls -l $DIR/$tdir
11848         rm -rf $DIR/$tdir
11849 }
11850 run_test 110 "filename length checking"
11851
11852 #
11853 # Purpose: To verify dynamic thread (OSS) creation.
11854 #
11855 test_115() {
11856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11857         remote_ost_nodsh && skip "remote OST with nodsh"
11858
11859         # Lustre does not stop service threads once they are started.
11860         # Reset number of running threads to default.
11861         stopall
11862         setupall
11863
11864         local OSTIO_pre
11865         local save_params="$TMP/sanity-$TESTNAME.parameters"
11866
11867         # Get ll_ost_io count before I/O
11868         OSTIO_pre=$(do_facet ost1 \
11869                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11870         # Exit if lustre is not running (ll_ost_io not running).
11871         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11872
11873         echo "Starting with $OSTIO_pre threads"
11874         local thread_max=$((OSTIO_pre * 2))
11875         local rpc_in_flight=$((thread_max * 2))
11876         # this is limited to OSC_MAX_RIF_MAX (256)
11877         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
11878         thread_max=$((rpc_in_flight / 2))
11879         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
11880                 return
11881
11882         # Number of I/O Process proposed to be started.
11883         local nfiles
11884         local facets=$(get_facets OST)
11885
11886         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11887         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11888
11889         # Set in_flight to $rpc_in_flight
11890         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11891                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11892         nfiles=${rpc_in_flight}
11893         # Set ost thread_max to $thread_max
11894         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11895
11896         # 5 Minutes should be sufficient for max number of OSS
11897         # threads(thread_max) to be created.
11898         local timeout=300
11899
11900         # Start I/O.
11901         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11902         test_mkdir $DIR/$tdir
11903         for i in $(seq $nfiles); do
11904                 local file=$DIR/$tdir/${tfile}-$i
11905                 $LFS setstripe -c -1 -i 0 $file
11906                 ($WTL $file $timeout)&
11907         done
11908
11909         # I/O Started - Wait for thread_started to reach thread_max or report
11910         # error if thread_started is more than thread_max.
11911         echo "Waiting for thread_started to reach thread_max"
11912         local thread_started=0
11913         local end_time=$((SECONDS + timeout))
11914
11915         while [ $SECONDS -le $end_time ] ; do
11916                 echo -n "."
11917                 # Get ost i/o thread_started count.
11918                 thread_started=$(do_facet ost1 \
11919                         "$LCTL get_param \
11920                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11921                 # Break out if thread_started is equal/greater than thread_max
11922                 if [[ $thread_started -ge $thread_max ]]; then
11923                         echo ll_ost_io thread_started $thread_started, \
11924                                 equal/greater than thread_max $thread_max
11925                         break
11926                 fi
11927                 sleep 1
11928         done
11929
11930         # Cleanup - We have the numbers, Kill i/o jobs if running.
11931         jobcount=($(jobs -p))
11932         for i in $(seq 0 $((${#jobcount[@]}-1)))
11933         do
11934                 kill -9 ${jobcount[$i]}
11935                 if [ $? -ne 0 ] ; then
11936                         echo Warning: \
11937                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11938                 fi
11939         done
11940
11941         # Cleanup files left by WTL binary.
11942         for i in $(seq $nfiles); do
11943                 local file=$DIR/$tdir/${tfile}-$i
11944                 rm -rf $file
11945                 if [ $? -ne 0 ] ; then
11946                         echo "Warning: Failed to delete file $file"
11947                 fi
11948         done
11949
11950         restore_lustre_params <$save_params
11951         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11952
11953         # Error out if no new thread has started or Thread started is greater
11954         # than thread max.
11955         if [[ $thread_started -le $OSTIO_pre ||
11956                         $thread_started -gt $thread_max ]]; then
11957                 error "ll_ost_io: thread_started $thread_started" \
11958                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11959                       "No new thread started or thread started greater " \
11960                       "than thread_max."
11961         fi
11962 }
11963 run_test 115 "verify dynamic thread creation===================="
11964
11965 free_min_max () {
11966         wait_delete_completed
11967         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11968         echo "OST kbytes available: ${AVAIL[*]}"
11969         MAXV=${AVAIL[0]}
11970         MAXI=0
11971         MINV=${AVAIL[0]}
11972         MINI=0
11973         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11974                 #echo OST $i: ${AVAIL[i]}kb
11975                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11976                         MAXV=${AVAIL[i]}
11977                         MAXI=$i
11978                 fi
11979                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11980                         MINV=${AVAIL[i]}
11981                         MINI=$i
11982                 fi
11983         done
11984         echo "Min free space: OST $MINI: $MINV"
11985         echo "Max free space: OST $MAXI: $MAXV"
11986 }
11987
11988 test_116a() { # was previously test_116()
11989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11990         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11991         remote_mds_nodsh && skip "remote MDS with nodsh"
11992
11993         echo -n "Free space priority "
11994         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11995                 head -n1
11996         declare -a AVAIL
11997         free_min_max
11998
11999         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12000         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12001         stack_trap simple_cleanup_common
12002
12003         # Check if we need to generate uneven OSTs
12004         test_mkdir -p $DIR/$tdir/OST${MINI}
12005         local FILL=$((MINV / 4))
12006         local DIFF=$((MAXV - MINV))
12007         local DIFF2=$((DIFF * 100 / MINV))
12008
12009         local threshold=$(do_facet $SINGLEMDS \
12010                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12011         threshold=${threshold%%%}
12012         echo -n "Check for uneven OSTs: "
12013         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12014
12015         if [[ $DIFF2 -gt $threshold ]]; then
12016                 echo "ok"
12017                 echo "Don't need to fill OST$MINI"
12018         else
12019                 # generate uneven OSTs. Write 2% over the QOS threshold value
12020                 echo "no"
12021                 DIFF=$((threshold - DIFF2 + 2))
12022                 DIFF2=$((MINV * DIFF / 100))
12023                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12024                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12025                         error "setstripe failed"
12026                 DIFF=$((DIFF2 / 2048))
12027                 i=0
12028                 while [ $i -lt $DIFF ]; do
12029                         i=$((i + 1))
12030                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12031                                 bs=2M count=1 2>/dev/null
12032                         echo -n .
12033                 done
12034                 echo .
12035                 sync
12036                 sleep_maxage
12037                 free_min_max
12038         fi
12039
12040         DIFF=$((MAXV - MINV))
12041         DIFF2=$((DIFF * 100 / MINV))
12042         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12043         if [ $DIFF2 -gt $threshold ]; then
12044                 echo "ok"
12045         else
12046                 skip "QOS imbalance criteria not met"
12047         fi
12048
12049         MINI1=$MINI
12050         MINV1=$MINV
12051         MAXI1=$MAXI
12052         MAXV1=$MAXV
12053
12054         # now fill using QOS
12055         $LFS setstripe -c 1 $DIR/$tdir
12056         FILL=$((FILL / 200))
12057         if [ $FILL -gt 600 ]; then
12058                 FILL=600
12059         fi
12060         echo "writing $FILL files to QOS-assigned OSTs"
12061         i=0
12062         while [ $i -lt $FILL ]; do
12063                 i=$((i + 1))
12064                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12065                         count=1 2>/dev/null
12066                 echo -n .
12067         done
12068         echo "wrote $i 200k files"
12069         sync
12070         sleep_maxage
12071
12072         echo "Note: free space may not be updated, so measurements might be off"
12073         free_min_max
12074         DIFF2=$((MAXV - MINV))
12075         echo "free space delta: orig $DIFF final $DIFF2"
12076         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12077         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12078         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12079         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12080         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12081         if [[ $DIFF -gt 0 ]]; then
12082                 FILL=$((DIFF2 * 100 / DIFF - 100))
12083                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12084         fi
12085
12086         # Figure out which files were written where
12087         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12088                awk '/'$MINI1': / {print $2; exit}')
12089         echo $UUID
12090         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12091         echo "$MINC files created on smaller OST $MINI1"
12092         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12093                awk '/'$MAXI1': / {print $2; exit}')
12094         echo $UUID
12095         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12096         echo "$MAXC files created on larger OST $MAXI1"
12097         if [[ $MINC -gt 0 ]]; then
12098                 FILL=$((MAXC * 100 / MINC - 100))
12099                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12100         fi
12101         [[ $MAXC -gt $MINC ]] ||
12102                 error_ignore LU-9 "stripe QOS didn't balance free space"
12103 }
12104 run_test 116a "stripe QOS: free space balance ==================="
12105
12106 test_116b() { # LU-2093
12107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12108         remote_mds_nodsh && skip "remote MDS with nodsh"
12109
12110 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12111         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12112                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12113         [ -z "$old_rr" ] && skip "no QOS"
12114         do_facet $SINGLEMDS lctl set_param \
12115                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12116         mkdir -p $DIR/$tdir
12117         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12118         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12119         do_facet $SINGLEMDS lctl set_param fail_loc=0
12120         rm -rf $DIR/$tdir
12121         do_facet $SINGLEMDS lctl set_param \
12122                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12123 }
12124 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12125
12126 test_117() # bug 10891
12127 {
12128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12129
12130         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12131         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12132         lctl set_param fail_loc=0x21e
12133         > $DIR/$tfile || error "truncate failed"
12134         lctl set_param fail_loc=0
12135         echo "Truncate succeeded."
12136         rm -f $DIR/$tfile
12137 }
12138 run_test 117 "verify osd extend =========="
12139
12140 NO_SLOW_RESENDCOUNT=4
12141 export OLD_RESENDCOUNT=""
12142 set_resend_count () {
12143         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12144         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12145         lctl set_param -n $PROC_RESENDCOUNT $1
12146         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12147 }
12148
12149 # for reduce test_118* time (b=14842)
12150 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12151
12152 # Reset async IO behavior after error case
12153 reset_async() {
12154         FILE=$DIR/reset_async
12155
12156         # Ensure all OSCs are cleared
12157         $LFS setstripe -c -1 $FILE
12158         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12159         sync
12160         rm $FILE
12161 }
12162
12163 test_118a() #bug 11710
12164 {
12165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12166
12167         reset_async
12168
12169         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12170         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12171         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12172
12173         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12174                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12175                 return 1;
12176         fi
12177         rm -f $DIR/$tfile
12178 }
12179 run_test 118a "verify O_SYNC works =========="
12180
12181 test_118b()
12182 {
12183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12184         remote_ost_nodsh && skip "remote OST with nodsh"
12185
12186         reset_async
12187
12188         #define OBD_FAIL_SRV_ENOENT 0x217
12189         set_nodes_failloc "$(osts_nodes)" 0x217
12190         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12191         RC=$?
12192         set_nodes_failloc "$(osts_nodes)" 0
12193         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12194         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12195                     grep -c writeback)
12196
12197         if [[ $RC -eq 0 ]]; then
12198                 error "Must return error due to dropped pages, rc=$RC"
12199                 return 1;
12200         fi
12201
12202         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12203                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12204                 return 1;
12205         fi
12206
12207         echo "Dirty pages not leaked on ENOENT"
12208
12209         # Due to the above error the OSC will issue all RPCs syncronously
12210         # until a subsequent RPC completes successfully without error.
12211         $MULTIOP $DIR/$tfile Ow4096yc
12212         rm -f $DIR/$tfile
12213
12214         return 0
12215 }
12216 run_test 118b "Reclaim dirty pages on fatal error =========="
12217
12218 test_118c()
12219 {
12220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12221
12222         # for 118c, restore the original resend count, LU-1940
12223         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12224                                 set_resend_count $OLD_RESENDCOUNT
12225         remote_ost_nodsh && skip "remote OST with nodsh"
12226
12227         reset_async
12228
12229         #define OBD_FAIL_OST_EROFS               0x216
12230         set_nodes_failloc "$(osts_nodes)" 0x216
12231
12232         # multiop should block due to fsync until pages are written
12233         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12234         MULTIPID=$!
12235         sleep 1
12236
12237         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12238                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12239         fi
12240
12241         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12242                     grep -c writeback)
12243         if [[ $WRITEBACK -eq 0 ]]; then
12244                 error "No page in writeback, writeback=$WRITEBACK"
12245         fi
12246
12247         set_nodes_failloc "$(osts_nodes)" 0
12248         wait $MULTIPID
12249         RC=$?
12250         if [[ $RC -ne 0 ]]; then
12251                 error "Multiop fsync failed, rc=$RC"
12252         fi
12253
12254         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12255         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12256                     grep -c writeback)
12257         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12258                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12259         fi
12260
12261         rm -f $DIR/$tfile
12262         echo "Dirty pages flushed via fsync on EROFS"
12263         return 0
12264 }
12265 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12266
12267 # continue to use small resend count to reduce test_118* time (b=14842)
12268 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12269
12270 test_118d()
12271 {
12272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12273         remote_ost_nodsh && skip "remote OST with nodsh"
12274
12275         reset_async
12276
12277         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12278         set_nodes_failloc "$(osts_nodes)" 0x214
12279         # multiop should block due to fsync until pages are written
12280         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12281         MULTIPID=$!
12282         sleep 1
12283
12284         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12285                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12286         fi
12287
12288         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12289                     grep -c writeback)
12290         if [[ $WRITEBACK -eq 0 ]]; then
12291                 error "No page in writeback, writeback=$WRITEBACK"
12292         fi
12293
12294         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12295         set_nodes_failloc "$(osts_nodes)" 0
12296
12297         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12298         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12299                     grep -c writeback)
12300         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12301                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12302         fi
12303
12304         rm -f $DIR/$tfile
12305         echo "Dirty pages gaurenteed flushed via fsync"
12306         return 0
12307 }
12308 run_test 118d "Fsync validation inject a delay of the bulk =========="
12309
12310 test_118f() {
12311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12312
12313         reset_async
12314
12315         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12316         lctl set_param fail_loc=0x8000040a
12317
12318         # Should simulate EINVAL error which is fatal
12319         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12320         RC=$?
12321         if [[ $RC -eq 0 ]]; then
12322                 error "Must return error due to dropped pages, rc=$RC"
12323         fi
12324
12325         lctl set_param fail_loc=0x0
12326
12327         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12328         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12329         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12330                     grep -c writeback)
12331         if [[ $LOCKED -ne 0 ]]; then
12332                 error "Locked pages remain in cache, locked=$LOCKED"
12333         fi
12334
12335         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12336                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12337         fi
12338
12339         rm -f $DIR/$tfile
12340         echo "No pages locked after fsync"
12341
12342         reset_async
12343         return 0
12344 }
12345 run_test 118f "Simulate unrecoverable OSC side error =========="
12346
12347 test_118g() {
12348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12349
12350         reset_async
12351
12352         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12353         lctl set_param fail_loc=0x406
12354
12355         # simulate local -ENOMEM
12356         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12357         RC=$?
12358
12359         lctl set_param fail_loc=0
12360         if [[ $RC -eq 0 ]]; then
12361                 error "Must return error due to dropped pages, rc=$RC"
12362         fi
12363
12364         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12365         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12366         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12367                         grep -c writeback)
12368         if [[ $LOCKED -ne 0 ]]; then
12369                 error "Locked pages remain in cache, locked=$LOCKED"
12370         fi
12371
12372         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12373                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12374         fi
12375
12376         rm -f $DIR/$tfile
12377         echo "No pages locked after fsync"
12378
12379         reset_async
12380         return 0
12381 }
12382 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12383
12384 test_118h() {
12385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12386         remote_ost_nodsh && skip "remote OST with nodsh"
12387
12388         reset_async
12389
12390         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12391         set_nodes_failloc "$(osts_nodes)" 0x20e
12392         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12393         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12394         RC=$?
12395
12396         set_nodes_failloc "$(osts_nodes)" 0
12397         if [[ $RC -eq 0 ]]; then
12398                 error "Must return error due to dropped pages, rc=$RC"
12399         fi
12400
12401         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12402         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12403         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12404                     grep -c writeback)
12405         if [[ $LOCKED -ne 0 ]]; then
12406                 error "Locked pages remain in cache, locked=$LOCKED"
12407         fi
12408
12409         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12410                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12411         fi
12412
12413         rm -f $DIR/$tfile
12414         echo "No pages locked after fsync"
12415
12416         return 0
12417 }
12418 run_test 118h "Verify timeout in handling recoverables errors  =========="
12419
12420 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12421
12422 test_118i() {
12423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12424         remote_ost_nodsh && skip "remote OST with nodsh"
12425
12426         reset_async
12427
12428         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12429         set_nodes_failloc "$(osts_nodes)" 0x20e
12430
12431         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12432         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12433         PID=$!
12434         sleep 5
12435         set_nodes_failloc "$(osts_nodes)" 0
12436
12437         wait $PID
12438         RC=$?
12439         if [[ $RC -ne 0 ]]; then
12440                 error "got error, but should be not, rc=$RC"
12441         fi
12442
12443         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12444         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12445         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12446         if [[ $LOCKED -ne 0 ]]; then
12447                 error "Locked pages remain in cache, locked=$LOCKED"
12448         fi
12449
12450         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12451                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12452         fi
12453
12454         rm -f $DIR/$tfile
12455         echo "No pages locked after fsync"
12456
12457         return 0
12458 }
12459 run_test 118i "Fix error before timeout in recoverable error  =========="
12460
12461 [ "$SLOW" = "no" ] && set_resend_count 4
12462
12463 test_118j() {
12464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12465         remote_ost_nodsh && skip "remote OST with nodsh"
12466
12467         reset_async
12468
12469         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12470         set_nodes_failloc "$(osts_nodes)" 0x220
12471
12472         # return -EIO from OST
12473         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12474         RC=$?
12475         set_nodes_failloc "$(osts_nodes)" 0x0
12476         if [[ $RC -eq 0 ]]; then
12477                 error "Must return error due to dropped pages, rc=$RC"
12478         fi
12479
12480         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12481         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12482         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12483         if [[ $LOCKED -ne 0 ]]; then
12484                 error "Locked pages remain in cache, locked=$LOCKED"
12485         fi
12486
12487         # in recoverable error on OST we want resend and stay until it finished
12488         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12489                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12490         fi
12491
12492         rm -f $DIR/$tfile
12493         echo "No pages locked after fsync"
12494
12495         return 0
12496 }
12497 run_test 118j "Simulate unrecoverable OST side error =========="
12498
12499 test_118k()
12500 {
12501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12502         remote_ost_nodsh && skip "remote OSTs with nodsh"
12503
12504         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12505         set_nodes_failloc "$(osts_nodes)" 0x20e
12506         test_mkdir $DIR/$tdir
12507
12508         for ((i=0;i<10;i++)); do
12509                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12510                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12511                 SLEEPPID=$!
12512                 sleep 0.500s
12513                 kill $SLEEPPID
12514                 wait $SLEEPPID
12515         done
12516
12517         set_nodes_failloc "$(osts_nodes)" 0
12518         rm -rf $DIR/$tdir
12519 }
12520 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12521
12522 test_118l() # LU-646
12523 {
12524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12525
12526         test_mkdir $DIR/$tdir
12527         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12528         rm -rf $DIR/$tdir
12529 }
12530 run_test 118l "fsync dir"
12531
12532 test_118m() # LU-3066
12533 {
12534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12535
12536         test_mkdir $DIR/$tdir
12537         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12538         rm -rf $DIR/$tdir
12539 }
12540 run_test 118m "fdatasync dir ========="
12541
12542 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12543
12544 test_118n()
12545 {
12546         local begin
12547         local end
12548
12549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12550         remote_ost_nodsh && skip "remote OSTs with nodsh"
12551
12552         # Sleep to avoid a cached response.
12553         #define OBD_STATFS_CACHE_SECONDS 1
12554         sleep 2
12555
12556         # Inject a 10 second delay in the OST_STATFS handler.
12557         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12558         set_nodes_failloc "$(osts_nodes)" 0x242
12559
12560         begin=$SECONDS
12561         stat --file-system $MOUNT > /dev/null
12562         end=$SECONDS
12563
12564         set_nodes_failloc "$(osts_nodes)" 0
12565
12566         if ((end - begin > 20)); then
12567             error "statfs took $((end - begin)) seconds, expected 10"
12568         fi
12569 }
12570 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12571
12572 test_119a() # bug 11737
12573 {
12574         BSIZE=$((512 * 1024))
12575         directio write $DIR/$tfile 0 1 $BSIZE
12576         # We ask to read two blocks, which is more than a file size.
12577         # directio will indicate an error when requested and actual
12578         # sizes aren't equeal (a normal situation in this case) and
12579         # print actual read amount.
12580         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12581         if [ "$NOB" != "$BSIZE" ]; then
12582                 error "read $NOB bytes instead of $BSIZE"
12583         fi
12584         rm -f $DIR/$tfile
12585 }
12586 run_test 119a "Short directIO read must return actual read amount"
12587
12588 test_119b() # bug 11737
12589 {
12590         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12591
12592         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12593         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12594         sync
12595         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12596                 error "direct read failed"
12597         rm -f $DIR/$tfile
12598 }
12599 run_test 119b "Sparse directIO read must return actual read amount"
12600
12601 test_119c() # bug 13099
12602 {
12603         BSIZE=1048576
12604         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12605         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12606         rm -f $DIR/$tfile
12607 }
12608 run_test 119c "Testing for direct read hitting hole"
12609
12610 test_119d() # bug 15950
12611 {
12612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12613
12614         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12615         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12616         BSIZE=1048576
12617         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12618         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12619         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12620         lctl set_param fail_loc=0x40d
12621         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12622         pid_dio=$!
12623         sleep 1
12624         cat $DIR/$tfile > /dev/null &
12625         lctl set_param fail_loc=0
12626         pid_reads=$!
12627         wait $pid_dio
12628         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12629         sleep 2
12630         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12631         error "the read rpcs have not completed in 2s"
12632         rm -f $DIR/$tfile
12633         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12634 }
12635 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12636
12637 test_120a() {
12638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12639         remote_mds_nodsh && skip "remote MDS with nodsh"
12640         test_mkdir -i0 -c1 $DIR/$tdir
12641         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12642                 skip_env "no early lock cancel on server"
12643
12644         lru_resize_disable mdc
12645         lru_resize_disable osc
12646         cancel_lru_locks mdc
12647         # asynchronous object destroy at MDT could cause bl ast to client
12648         cancel_lru_locks osc
12649
12650         stat $DIR/$tdir > /dev/null
12651         can1=$(do_facet mds1 \
12652                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12653                awk '/ldlm_cancel/ {print $2}')
12654         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12655                awk '/ldlm_bl_callback/ {print $2}')
12656         test_mkdir -i0 -c1 $DIR/$tdir/d1
12657         can2=$(do_facet mds1 \
12658                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12659                awk '/ldlm_cancel/ {print $2}')
12660         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12661                awk '/ldlm_bl_callback/ {print $2}')
12662         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12663         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12664         lru_resize_enable mdc
12665         lru_resize_enable osc
12666 }
12667 run_test 120a "Early Lock Cancel: mkdir test"
12668
12669 test_120b() {
12670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12671         remote_mds_nodsh && skip "remote MDS with nodsh"
12672         test_mkdir $DIR/$tdir
12673         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12674                 skip_env "no early lock cancel on server"
12675
12676         lru_resize_disable mdc
12677         lru_resize_disable osc
12678         cancel_lru_locks mdc
12679         stat $DIR/$tdir > /dev/null
12680         can1=$(do_facet $SINGLEMDS \
12681                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12682                awk '/ldlm_cancel/ {print $2}')
12683         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12684                awk '/ldlm_bl_callback/ {print $2}')
12685         touch $DIR/$tdir/f1
12686         can2=$(do_facet $SINGLEMDS \
12687                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12688                awk '/ldlm_cancel/ {print $2}')
12689         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12690                awk '/ldlm_bl_callback/ {print $2}')
12691         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12692         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12693         lru_resize_enable mdc
12694         lru_resize_enable osc
12695 }
12696 run_test 120b "Early Lock Cancel: create test"
12697
12698 test_120c() {
12699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12700         remote_mds_nodsh && skip "remote MDS with nodsh"
12701         test_mkdir -i0 -c1 $DIR/$tdir
12702         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12703                 skip "no early lock cancel on server"
12704
12705         lru_resize_disable mdc
12706         lru_resize_disable osc
12707         test_mkdir -i0 -c1 $DIR/$tdir/d1
12708         test_mkdir -i0 -c1 $DIR/$tdir/d2
12709         touch $DIR/$tdir/d1/f1
12710         cancel_lru_locks mdc
12711         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12712         can1=$(do_facet mds1 \
12713                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12714                awk '/ldlm_cancel/ {print $2}')
12715         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12716                awk '/ldlm_bl_callback/ {print $2}')
12717         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12718         can2=$(do_facet mds1 \
12719                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12720                awk '/ldlm_cancel/ {print $2}')
12721         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12722                awk '/ldlm_bl_callback/ {print $2}')
12723         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12724         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12725         lru_resize_enable mdc
12726         lru_resize_enable osc
12727 }
12728 run_test 120c "Early Lock Cancel: link test"
12729
12730 test_120d() {
12731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12732         remote_mds_nodsh && skip "remote MDS with nodsh"
12733         test_mkdir -i0 -c1 $DIR/$tdir
12734         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12735                 skip_env "no early lock cancel on server"
12736
12737         lru_resize_disable mdc
12738         lru_resize_disable osc
12739         touch $DIR/$tdir
12740         cancel_lru_locks mdc
12741         stat $DIR/$tdir > /dev/null
12742         can1=$(do_facet mds1 \
12743                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12744                awk '/ldlm_cancel/ {print $2}')
12745         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12746                awk '/ldlm_bl_callback/ {print $2}')
12747         chmod a+x $DIR/$tdir
12748         can2=$(do_facet mds1 \
12749                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12750                awk '/ldlm_cancel/ {print $2}')
12751         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12752                awk '/ldlm_bl_callback/ {print $2}')
12753         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12754         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12755         lru_resize_enable mdc
12756         lru_resize_enable osc
12757 }
12758 run_test 120d "Early Lock Cancel: setattr test"
12759
12760 test_120e() {
12761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12762         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12763                 skip_env "no early lock cancel on server"
12764         remote_mds_nodsh && skip "remote MDS with nodsh"
12765
12766         local dlmtrace_set=false
12767
12768         test_mkdir -i0 -c1 $DIR/$tdir
12769         lru_resize_disable mdc
12770         lru_resize_disable osc
12771         ! $LCTL get_param debug | grep -q dlmtrace &&
12772                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12773         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12774         cancel_lru_locks mdc
12775         cancel_lru_locks osc
12776         dd if=$DIR/$tdir/f1 of=/dev/null
12777         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12778         # XXX client can not do early lock cancel of OST lock
12779         # during unlink (LU-4206), so cancel osc lock now.
12780         sleep 2
12781         cancel_lru_locks osc
12782         can1=$(do_facet mds1 \
12783                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12784                awk '/ldlm_cancel/ {print $2}')
12785         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12786                awk '/ldlm_bl_callback/ {print $2}')
12787         unlink $DIR/$tdir/f1
12788         sleep 5
12789         can2=$(do_facet mds1 \
12790                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12791                awk '/ldlm_cancel/ {print $2}')
12792         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12793                awk '/ldlm_bl_callback/ {print $2}')
12794         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12795                 $LCTL dk $TMP/cancel.debug.txt
12796         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12797                 $LCTL dk $TMP/blocking.debug.txt
12798         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12799         lru_resize_enable mdc
12800         lru_resize_enable osc
12801 }
12802 run_test 120e "Early Lock Cancel: unlink test"
12803
12804 test_120f() {
12805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12806         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12807                 skip_env "no early lock cancel on server"
12808         remote_mds_nodsh && skip "remote MDS with nodsh"
12809
12810         test_mkdir -i0 -c1 $DIR/$tdir
12811         lru_resize_disable mdc
12812         lru_resize_disable osc
12813         test_mkdir -i0 -c1 $DIR/$tdir/d1
12814         test_mkdir -i0 -c1 $DIR/$tdir/d2
12815         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12816         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12817         cancel_lru_locks mdc
12818         cancel_lru_locks osc
12819         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12820         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12821         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12822         # XXX client can not do early lock cancel of OST lock
12823         # during rename (LU-4206), so cancel osc lock now.
12824         sleep 2
12825         cancel_lru_locks osc
12826         can1=$(do_facet mds1 \
12827                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12828                awk '/ldlm_cancel/ {print $2}')
12829         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12830                awk '/ldlm_bl_callback/ {print $2}')
12831         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12832         sleep 5
12833         can2=$(do_facet mds1 \
12834                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12835                awk '/ldlm_cancel/ {print $2}')
12836         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12837                awk '/ldlm_bl_callback/ {print $2}')
12838         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12839         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12840         lru_resize_enable mdc
12841         lru_resize_enable osc
12842 }
12843 run_test 120f "Early Lock Cancel: rename test"
12844
12845 test_120g() {
12846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12847         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12848                 skip_env "no early lock cancel on server"
12849         remote_mds_nodsh && skip "remote MDS with nodsh"
12850
12851         lru_resize_disable mdc
12852         lru_resize_disable osc
12853         count=10000
12854         echo create $count files
12855         test_mkdir $DIR/$tdir
12856         cancel_lru_locks mdc
12857         cancel_lru_locks osc
12858         t0=$(date +%s)
12859
12860         can0=$(do_facet $SINGLEMDS \
12861                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12862                awk '/ldlm_cancel/ {print $2}')
12863         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12864                awk '/ldlm_bl_callback/ {print $2}')
12865         createmany -o $DIR/$tdir/f $count
12866         sync
12867         can1=$(do_facet $SINGLEMDS \
12868                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12869                awk '/ldlm_cancel/ {print $2}')
12870         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12871                awk '/ldlm_bl_callback/ {print $2}')
12872         t1=$(date +%s)
12873         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12874         echo rm $count files
12875         rm -r $DIR/$tdir
12876         sync
12877         can2=$(do_facet $SINGLEMDS \
12878                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12879                awk '/ldlm_cancel/ {print $2}')
12880         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12881                awk '/ldlm_bl_callback/ {print $2}')
12882         t2=$(date +%s)
12883         echo total: $count removes in $((t2-t1))
12884         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12885         sleep 2
12886         # wait for commitment of removal
12887         lru_resize_enable mdc
12888         lru_resize_enable osc
12889 }
12890 run_test 120g "Early Lock Cancel: performance test"
12891
12892 test_121() { #bug #10589
12893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12894
12895         rm -rf $DIR/$tfile
12896         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12897 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12898         lctl set_param fail_loc=0x310
12899         cancel_lru_locks osc > /dev/null
12900         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12901         lctl set_param fail_loc=0
12902         [[ $reads -eq $writes ]] ||
12903                 error "read $reads blocks, must be $writes blocks"
12904 }
12905 run_test 121 "read cancel race ========="
12906
12907 test_123a_base() { # was test 123, statahead(bug 11401)
12908         local lsx="$1"
12909
12910         SLOWOK=0
12911         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12912                 log "testing UP system. Performance may be lower than expected."
12913                 SLOWOK=1
12914         fi
12915
12916         rm -rf $DIR/$tdir
12917         test_mkdir $DIR/$tdir
12918         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12919         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12920         MULT=10
12921         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12922                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12923
12924                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12925                 lctl set_param -n llite.*.statahead_max 0
12926                 lctl get_param llite.*.statahead_max
12927                 cancel_lru_locks mdc
12928                 cancel_lru_locks osc
12929                 stime=$(date +%s)
12930                 time $lsx $DIR/$tdir | wc -l
12931                 etime=$(date +%s)
12932                 delta=$((etime - stime))
12933                 log "$lsx $i files without statahead: $delta sec"
12934                 lctl set_param llite.*.statahead_max=$max
12935
12936                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12937                         grep "statahead wrong:" | awk '{print $3}')
12938                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12939                 cancel_lru_locks mdc
12940                 cancel_lru_locks osc
12941                 stime=$(date +%s)
12942                 time $lsx $DIR/$tdir | wc -l
12943                 etime=$(date +%s)
12944                 delta_sa=$((etime - stime))
12945                 log "$lsx $i files with statahead: $delta_sa sec"
12946                 lctl get_param -n llite.*.statahead_stats
12947                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12948                         grep "statahead wrong:" | awk '{print $3}')
12949
12950                 [[ $swrong -lt $ewrong ]] &&
12951                         log "statahead was stopped, maybe too many locks held!"
12952                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12953
12954                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12955                         max=$(lctl get_param -n llite.*.statahead_max |
12956                                 head -n 1)
12957                         lctl set_param -n llite.*.statahead_max 0
12958                         lctl get_param llite.*.statahead_max
12959                         cancel_lru_locks mdc
12960                         cancel_lru_locks osc
12961                         stime=$(date +%s)
12962                         time $lsx $DIR/$tdir | wc -l
12963                         etime=$(date +%s)
12964                         delta=$((etime - stime))
12965                         log "$lsx $i files again without statahead: $delta sec"
12966                         lctl set_param llite.*.statahead_max=$max
12967                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12968                                 if [  $SLOWOK -eq 0 ]; then
12969                                         error "$lsx $i files is slower with statahead!"
12970                                 else
12971                                         log "$lsx $i files is slower with statahead!"
12972                                 fi
12973                                 break
12974                         fi
12975                 fi
12976
12977                 [ $delta -gt 20 ] && break
12978                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12979                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12980         done
12981         log "$lsx done"
12982
12983         stime=$(date +%s)
12984         rm -r $DIR/$tdir
12985         sync
12986         etime=$(date +%s)
12987         delta=$((etime - stime))
12988         log "rm -r $DIR/$tdir/: $delta seconds"
12989         log "rm done"
12990         lctl get_param -n llite.*.statahead_stats
12991 }
12992
12993 test_123aa() {
12994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12995
12996         test_123a_base "ls -l"
12997 }
12998 run_test 123aa "verify statahead work"
12999
13000 test_123ab() {
13001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13002
13003         statx_supported || skip_env "Test must be statx() syscall supported"
13004
13005         test_123a_base "$STATX -l"
13006 }
13007 run_test 123ab "verify statahead work by using statx"
13008
13009 test_123ac() {
13010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13011
13012         statx_supported || skip_env "Test must be statx() syscall supported"
13013
13014         local rpcs_before
13015         local rpcs_after
13016         local agl_before
13017         local agl_after
13018
13019         cancel_lru_locks $OSC
13020         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13021         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13022                 awk '/agl.total:/ {print $3}')
13023         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13024         test_123a_base "$STATX --cached=always -D"
13025         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13026                 awk '/agl.total:/ {print $3}')
13027         [ $agl_before -eq $agl_after ] ||
13028                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13029         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13030         [ $rpcs_after -eq $rpcs_before ] ||
13031                 error "$STATX should not send glimpse RPCs to $OSC"
13032 }
13033 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13034
13035 test_123b () { # statahead(bug 15027)
13036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13037
13038         test_mkdir $DIR/$tdir
13039         createmany -o $DIR/$tdir/$tfile-%d 1000
13040
13041         cancel_lru_locks mdc
13042         cancel_lru_locks osc
13043
13044 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13045         lctl set_param fail_loc=0x80000803
13046         ls -lR $DIR/$tdir > /dev/null
13047         log "ls done"
13048         lctl set_param fail_loc=0x0
13049         lctl get_param -n llite.*.statahead_stats
13050         rm -r $DIR/$tdir
13051         sync
13052
13053 }
13054 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13055
13056 test_123c() {
13057         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13058
13059         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13060         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13061         touch $DIR/$tdir.1/{1..3}
13062         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13063
13064         remount_client $MOUNT
13065
13066         $MULTIOP $DIR/$tdir.0 Q
13067
13068         # let statahead to complete
13069         ls -l $DIR/$tdir.0 > /dev/null
13070
13071         testid=$(echo $TESTNAME | tr '_' ' ')
13072         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13073                 error "statahead warning" || true
13074 }
13075 run_test 123c "Can not initialize inode warning on DNE statahead"
13076
13077 test_124a() {
13078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13079         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13080                 skip_env "no lru resize on server"
13081
13082         local NR=2000
13083
13084         test_mkdir $DIR/$tdir
13085
13086         log "create $NR files at $DIR/$tdir"
13087         createmany -o $DIR/$tdir/f $NR ||
13088                 error "failed to create $NR files in $DIR/$tdir"
13089
13090         cancel_lru_locks mdc
13091         ls -l $DIR/$tdir > /dev/null
13092
13093         local NSDIR=""
13094         local LRU_SIZE=0
13095         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13096                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13097                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13098                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13099                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13100                         log "NSDIR=$NSDIR"
13101                         log "NS=$(basename $NSDIR)"
13102                         break
13103                 fi
13104         done
13105
13106         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13107                 skip "Not enough cached locks created!"
13108         fi
13109         log "LRU=$LRU_SIZE"
13110
13111         local SLEEP=30
13112
13113         # We know that lru resize allows one client to hold $LIMIT locks
13114         # for 10h. After that locks begin to be killed by client.
13115         local MAX_HRS=10
13116         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13117         log "LIMIT=$LIMIT"
13118         if [ $LIMIT -lt $LRU_SIZE ]; then
13119                 skip "Limit is too small $LIMIT"
13120         fi
13121
13122         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13123         # killing locks. Some time was spent for creating locks. This means
13124         # that up to the moment of sleep finish we must have killed some of
13125         # them (10-100 locks). This depends on how fast ther were created.
13126         # Many of them were touched in almost the same moment and thus will
13127         # be killed in groups.
13128         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13129
13130         # Use $LRU_SIZE_B here to take into account real number of locks
13131         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13132         local LRU_SIZE_B=$LRU_SIZE
13133         log "LVF=$LVF"
13134         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13135         log "OLD_LVF=$OLD_LVF"
13136         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13137
13138         # Let's make sure that we really have some margin. Client checks
13139         # cached locks every 10 sec.
13140         SLEEP=$((SLEEP+20))
13141         log "Sleep ${SLEEP} sec"
13142         local SEC=0
13143         while ((SEC<$SLEEP)); do
13144                 echo -n "..."
13145                 sleep 5
13146                 SEC=$((SEC+5))
13147                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13148                 echo -n "$LRU_SIZE"
13149         done
13150         echo ""
13151         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13152         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13153
13154         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13155                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13156                 unlinkmany $DIR/$tdir/f $NR
13157                 return
13158         }
13159
13160         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13161         log "unlink $NR files at $DIR/$tdir"
13162         unlinkmany $DIR/$tdir/f $NR
13163 }
13164 run_test 124a "lru resize ======================================="
13165
13166 get_max_pool_limit()
13167 {
13168         local limit=$($LCTL get_param \
13169                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13170         local max=0
13171         for l in $limit; do
13172                 if [[ $l -gt $max ]]; then
13173                         max=$l
13174                 fi
13175         done
13176         echo $max
13177 }
13178
13179 test_124b() {
13180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13181         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13182                 skip_env "no lru resize on server"
13183
13184         LIMIT=$(get_max_pool_limit)
13185
13186         NR=$(($(default_lru_size)*20))
13187         if [[ $NR -gt $LIMIT ]]; then
13188                 log "Limit lock number by $LIMIT locks"
13189                 NR=$LIMIT
13190         fi
13191
13192         IFree=$(mdsrate_inodes_available)
13193         if [ $IFree -lt $NR ]; then
13194                 log "Limit lock number by $IFree inodes"
13195                 NR=$IFree
13196         fi
13197
13198         lru_resize_disable mdc
13199         test_mkdir -p $DIR/$tdir/disable_lru_resize
13200
13201         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13202         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13203         cancel_lru_locks mdc
13204         stime=`date +%s`
13205         PID=""
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         sleep 2
13212         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13213         PID="$PID $!"
13214         wait $PID
13215         etime=`date +%s`
13216         nolruresize_delta=$((etime-stime))
13217         log "ls -la time: $nolruresize_delta seconds"
13218         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13219         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13220
13221         lru_resize_enable mdc
13222         test_mkdir -p $DIR/$tdir/enable_lru_resize
13223
13224         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13225         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13226         cancel_lru_locks mdc
13227         stime=`date +%s`
13228         PID=""
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         sleep 2
13235         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13236         PID="$PID $!"
13237         wait $PID
13238         etime=`date +%s`
13239         lruresize_delta=$((etime-stime))
13240         log "ls -la time: $lruresize_delta seconds"
13241         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13242
13243         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13244                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13245         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13246                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13247         else
13248                 log "lru resize performs the same with no lru resize"
13249         fi
13250         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13251 }
13252 run_test 124b "lru resize (performance test) ======================="
13253
13254 test_124c() {
13255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13256         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13257                 skip_env "no lru resize on server"
13258
13259         # cache ununsed locks on client
13260         local nr=100
13261         cancel_lru_locks mdc
13262         test_mkdir $DIR/$tdir
13263         createmany -o $DIR/$tdir/f $nr ||
13264                 error "failed to create $nr files in $DIR/$tdir"
13265         ls -l $DIR/$tdir > /dev/null
13266
13267         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13268         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13269         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13270         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13271         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13272
13273         # set lru_max_age to 1 sec
13274         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13275         echo "sleep $((recalc_p * 2)) seconds..."
13276         sleep $((recalc_p * 2))
13277
13278         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13279         # restore lru_max_age
13280         $LCTL set_param -n $nsdir.lru_max_age $max_age
13281         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13282         unlinkmany $DIR/$tdir/f $nr
13283 }
13284 run_test 124c "LRUR cancel very aged locks"
13285
13286 test_124d() {
13287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13288         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13289                 skip_env "no lru resize on server"
13290
13291         # cache ununsed locks on client
13292         local nr=100
13293
13294         lru_resize_disable mdc
13295         stack_trap "lru_resize_enable mdc" EXIT
13296
13297         cancel_lru_locks mdc
13298
13299         # asynchronous object destroy at MDT could cause bl ast to client
13300         test_mkdir $DIR/$tdir
13301         createmany -o $DIR/$tdir/f $nr ||
13302                 error "failed to create $nr files in $DIR/$tdir"
13303         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13304
13305         ls -l $DIR/$tdir > /dev/null
13306
13307         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13308         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13309         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13310         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13311
13312         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13313
13314         # set lru_max_age to 1 sec
13315         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13316         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13317
13318         echo "sleep $((recalc_p * 2)) seconds..."
13319         sleep $((recalc_p * 2))
13320
13321         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13322
13323         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13324 }
13325 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13326
13327 test_125() { # 13358
13328         $LCTL get_param -n llite.*.client_type | grep -q local ||
13329                 skip "must run as local client"
13330         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13331                 skip_env "must have acl enabled"
13332         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13333
13334         test_mkdir $DIR/$tdir
13335         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13336         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13337         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13338 }
13339 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13340
13341 test_126() { # bug 12829/13455
13342         $GSS && skip_env "must run as gss disabled"
13343         $LCTL get_param -n llite.*.client_type | grep -q local ||
13344                 skip "must run as local client"
13345         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13346
13347         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13348         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13349         rm -f $DIR/$tfile
13350         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13351 }
13352 run_test 126 "check that the fsgid provided by the client is taken into account"
13353
13354 test_127a() { # bug 15521
13355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13356         local name count samp unit min max sum sumsq
13357
13358         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13359         echo "stats before reset"
13360         $LCTL get_param osc.*.stats
13361         $LCTL set_param osc.*.stats=0
13362         local fsize=$((2048 * 1024))
13363
13364         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13365         cancel_lru_locks osc
13366         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13367
13368         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13369         stack_trap "rm -f $TMP/$tfile.tmp"
13370         while read name count samp unit min max sum sumsq; do
13371                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13372                 [ ! $min ] && error "Missing min value for $name proc entry"
13373                 eval $name=$count || error "Wrong proc format"
13374
13375                 case $name in
13376                 read_bytes|write_bytes)
13377                         [[ "$unit" =~ "bytes" ]] ||
13378                                 error "unit is not 'bytes': $unit"
13379                         (( $min >= 4096 )) || error "min is too small: $min"
13380                         (( $min <= $fsize )) || error "min is too big: $min"
13381                         (( $max >= 4096 )) || error "max is too small: $max"
13382                         (( $max <= $fsize )) || error "max is too big: $max"
13383                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13384                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13385                                 error "sumsquare is too small: $sumsq"
13386                         (( $sumsq <= $fsize * $fsize )) ||
13387                                 error "sumsquare is too big: $sumsq"
13388                         ;;
13389                 ost_read|ost_write)
13390                         [[ "$unit" =~ "usec" ]] ||
13391                                 error "unit is not 'usec': $unit"
13392                         ;;
13393                 *)      ;;
13394                 esac
13395         done < $DIR/$tfile.tmp
13396
13397         #check that we actually got some stats
13398         [ "$read_bytes" ] || error "Missing read_bytes stats"
13399         [ "$write_bytes" ] || error "Missing write_bytes stats"
13400         [ "$read_bytes" != 0 ] || error "no read done"
13401         [ "$write_bytes" != 0 ] || error "no write done"
13402 }
13403 run_test 127a "verify the client stats are sane"
13404
13405 test_127b() { # bug LU-333
13406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13407         local name count samp unit min max sum sumsq
13408
13409         echo "stats before reset"
13410         $LCTL get_param llite.*.stats
13411         $LCTL set_param llite.*.stats=0
13412
13413         # perform 2 reads and writes so MAX is different from SUM.
13414         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13415         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13416         cancel_lru_locks osc
13417         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13418         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13419
13420         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13421         stack_trap "rm -f $TMP/$tfile.tmp"
13422         while read name count samp unit min max sum sumsq; do
13423                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13424                 eval $name=$count || error "Wrong proc format"
13425
13426                 case $name in
13427                 read_bytes|write_bytes)
13428                         [[ "$unit" =~ "bytes" ]] ||
13429                                 error "unit is not 'bytes': $unit"
13430                         (( $count == 2 )) || error "count is not 2: $count"
13431                         (( $min == $PAGE_SIZE )) ||
13432                                 error "min is not $PAGE_SIZE: $min"
13433                         (( $max == $PAGE_SIZE )) ||
13434                                 error "max is not $PAGE_SIZE: $max"
13435                         (( $sum == $PAGE_SIZE * 2 )) ||
13436                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13437                         ;;
13438                 read|write)
13439                         [[ "$unit" =~ "usec" ]] ||
13440                                 error "unit is not 'usec': $unit"
13441                         ;;
13442                 *)      ;;
13443                 esac
13444         done < $TMP/$tfile.tmp
13445
13446         #check that we actually got some stats
13447         [ "$read_bytes" ] || error "Missing read_bytes stats"
13448         [ "$write_bytes" ] || error "Missing write_bytes stats"
13449         [ "$read_bytes" != 0 ] || error "no read done"
13450         [ "$write_bytes" != 0 ] || error "no write done"
13451 }
13452 run_test 127b "verify the llite client stats are sane"
13453
13454 test_127c() { # LU-12394
13455         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13456         local size
13457         local bsize
13458         local reads
13459         local writes
13460         local count
13461
13462         $LCTL set_param llite.*.extents_stats=1
13463         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13464
13465         # Use two stripes so there is enough space in default config
13466         $LFS setstripe -c 2 $DIR/$tfile
13467
13468         # Extent stats start at 0-4K and go in power of two buckets
13469         # LL_HIST_START = 12 --> 2^12 = 4K
13470         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13471         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13472         # small configs
13473         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13474                 do
13475                 # Write and read, 2x each, second time at a non-zero offset
13476                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13477                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13478                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13479                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13480                 rm -f $DIR/$tfile
13481         done
13482
13483         $LCTL get_param llite.*.extents_stats
13484
13485         count=2
13486         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13487                 do
13488                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13489                                 grep -m 1 $bsize)
13490                 reads=$(echo $bucket | awk '{print $5}')
13491                 writes=$(echo $bucket | awk '{print $9}')
13492                 [ "$reads" -eq $count ] ||
13493                         error "$reads reads in < $bsize bucket, expect $count"
13494                 [ "$writes" -eq $count ] ||
13495                         error "$writes writes in < $bsize bucket, expect $count"
13496         done
13497
13498         # Test mmap write and read
13499         $LCTL set_param llite.*.extents_stats=c
13500         size=512
13501         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13502         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13503         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13504
13505         $LCTL get_param llite.*.extents_stats
13506
13507         count=$(((size*1024) / PAGE_SIZE))
13508
13509         bsize=$((2 * PAGE_SIZE / 1024))K
13510
13511         bucket=$($LCTL get_param -n llite.*.extents_stats |
13512                         grep -m 1 $bsize)
13513         reads=$(echo $bucket | awk '{print $5}')
13514         writes=$(echo $bucket | awk '{print $9}')
13515         # mmap writes fault in the page first, creating an additonal read
13516         [ "$reads" -eq $((2 * count)) ] ||
13517                 error "$reads reads in < $bsize bucket, expect $count"
13518         [ "$writes" -eq $count ] ||
13519                 error "$writes writes in < $bsize bucket, expect $count"
13520 }
13521 run_test 127c "test llite extent stats with regular & mmap i/o"
13522
13523 test_128() { # bug 15212
13524         touch $DIR/$tfile
13525         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13526                 find $DIR/$tfile
13527                 find $DIR/$tfile
13528         EOF
13529
13530         result=$(grep error $TMP/$tfile.log)
13531         rm -f $DIR/$tfile $TMP/$tfile.log
13532         [ -z "$result" ] ||
13533                 error "consecutive find's under interactive lfs failed"
13534 }
13535 run_test 128 "interactive lfs for 2 consecutive find's"
13536
13537 set_dir_limits () {
13538         local mntdev
13539         local canondev
13540         local node
13541
13542         local ldproc=/proc/fs/ldiskfs
13543         local facets=$(get_facets MDS)
13544
13545         for facet in ${facets//,/ }; do
13546                 canondev=$(ldiskfs_canon \
13547                            *.$(convert_facet2label $facet).mntdev $facet)
13548                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13549                         ldproc=/sys/fs/ldiskfs
13550                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13551                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13552         done
13553 }
13554
13555 check_mds_dmesg() {
13556         local facets=$(get_facets MDS)
13557         for facet in ${facets//,/ }; do
13558                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13559         done
13560         return 1
13561 }
13562
13563 test_129() {
13564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13565         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13566                 skip "Need MDS version with at least 2.5.56"
13567         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13568                 skip_env "ldiskfs only test"
13569         fi
13570         remote_mds_nodsh && skip "remote MDS with nodsh"
13571
13572         local ENOSPC=28
13573         local has_warning=false
13574
13575         rm -rf $DIR/$tdir
13576         mkdir -p $DIR/$tdir
13577
13578         # block size of mds1
13579         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13580         set_dir_limits $maxsize $((maxsize * 6 / 8))
13581         stack_trap "set_dir_limits 0 0"
13582         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13583         local dirsize=$(stat -c%s "$DIR/$tdir")
13584         local nfiles=0
13585         while (( $dirsize <= $maxsize )); do
13586                 $MCREATE $DIR/$tdir/file_base_$nfiles
13587                 rc=$?
13588                 # check two errors:
13589                 # ENOSPC for ext4 max_dir_size, which has been used since
13590                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13591                 if (( rc == ENOSPC )); then
13592                         set_dir_limits 0 0
13593                         echo "rc=$rc returned as expected after $nfiles files"
13594
13595                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13596                                 error "create failed w/o dir size limit"
13597
13598                         # messages may be rate limited if test is run repeatedly
13599                         check_mds_dmesg '"is approaching max"' ||
13600                                 echo "warning message should be output"
13601                         check_mds_dmesg '"has reached max"' ||
13602                                 echo "reached message should be output"
13603
13604                         dirsize=$(stat -c%s "$DIR/$tdir")
13605
13606                         [[ $dirsize -ge $maxsize ]] && return 0
13607                         error "dirsize $dirsize < $maxsize after $nfiles files"
13608                 elif (( rc != 0 )); then
13609                         break
13610                 fi
13611                 nfiles=$((nfiles + 1))
13612                 dirsize=$(stat -c%s "$DIR/$tdir")
13613         done
13614
13615         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13616 }
13617 run_test 129 "test directory size limit ========================"
13618
13619 OLDIFS="$IFS"
13620 cleanup_130() {
13621         trap 0
13622         IFS="$OLDIFS"
13623 }
13624
13625 test_130a() {
13626         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13627         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13628
13629         trap cleanup_130 EXIT RETURN
13630
13631         local fm_file=$DIR/$tfile
13632         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13633         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13634                 error "dd failed for $fm_file"
13635
13636         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13637         filefrag -ves $fm_file
13638         RC=$?
13639         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13640                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13641         [ $RC != 0 ] && error "filefrag $fm_file failed"
13642
13643         filefrag_op=$(filefrag -ve -k $fm_file |
13644                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13645         lun=$($LFS getstripe -i $fm_file)
13646
13647         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13648         IFS=$'\n'
13649         tot_len=0
13650         for line in $filefrag_op
13651         do
13652                 frag_lun=`echo $line | cut -d: -f5`
13653                 ext_len=`echo $line | cut -d: -f4`
13654                 if (( $frag_lun != $lun )); then
13655                         cleanup_130
13656                         error "FIEMAP on 1-stripe file($fm_file) failed"
13657                         return
13658                 fi
13659                 (( tot_len += ext_len ))
13660         done
13661
13662         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13663                 cleanup_130
13664                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13665                 return
13666         fi
13667
13668         cleanup_130
13669
13670         echo "FIEMAP on single striped file succeeded"
13671 }
13672 run_test 130a "FIEMAP (1-stripe file)"
13673
13674 test_130b() {
13675         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13676
13677         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13678         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13679
13680         trap cleanup_130 EXIT RETURN
13681
13682         local fm_file=$DIR/$tfile
13683         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13684                         error "setstripe on $fm_file"
13685         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13686                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13687
13688         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13689                 error "dd failed on $fm_file"
13690
13691         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13692         filefrag_op=$(filefrag -ve -k $fm_file |
13693                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13694
13695         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13696                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13697
13698         IFS=$'\n'
13699         tot_len=0
13700         num_luns=1
13701         for line in $filefrag_op
13702         do
13703                 frag_lun=$(echo $line | cut -d: -f5 |
13704                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13705                 ext_len=$(echo $line | cut -d: -f4)
13706                 if (( $frag_lun != $last_lun )); then
13707                         if (( tot_len != 1024 )); then
13708                                 cleanup_130
13709                                 error "FIEMAP on $fm_file failed; returned " \
13710                                 "len $tot_len for OST $last_lun instead of 1024"
13711                                 return
13712                         else
13713                                 (( num_luns += 1 ))
13714                                 tot_len=0
13715                         fi
13716                 fi
13717                 (( tot_len += ext_len ))
13718                 last_lun=$frag_lun
13719         done
13720         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13721                 cleanup_130
13722                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13723                         "luns or wrong len for OST $last_lun"
13724                 return
13725         fi
13726
13727         cleanup_130
13728
13729         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13730 }
13731 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13732
13733 test_130c() {
13734         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13735
13736         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13737         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13738
13739         trap cleanup_130 EXIT RETURN
13740
13741         local fm_file=$DIR/$tfile
13742         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13743         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13744                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13745
13746         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13747                         error "dd failed on $fm_file"
13748
13749         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13750         filefrag_op=$(filefrag -ve -k $fm_file |
13751                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13752
13753         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13754                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13755
13756         IFS=$'\n'
13757         tot_len=0
13758         num_luns=1
13759         for line in $filefrag_op
13760         do
13761                 frag_lun=$(echo $line | cut -d: -f5 |
13762                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13763                 ext_len=$(echo $line | cut -d: -f4)
13764                 if (( $frag_lun != $last_lun )); then
13765                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13766                         if (( logical != 512 )); then
13767                                 cleanup_130
13768                                 error "FIEMAP on $fm_file failed; returned " \
13769                                 "logical start for lun $logical instead of 512"
13770                                 return
13771                         fi
13772                         if (( tot_len != 512 )); then
13773                                 cleanup_130
13774                                 error "FIEMAP on $fm_file failed; returned " \
13775                                 "len $tot_len for OST $last_lun instead of 1024"
13776                                 return
13777                         else
13778                                 (( num_luns += 1 ))
13779                                 tot_len=0
13780                         fi
13781                 fi
13782                 (( tot_len += ext_len ))
13783                 last_lun=$frag_lun
13784         done
13785         if (( num_luns != 2 || tot_len != 512 )); then
13786                 cleanup_130
13787                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13788                         "luns or wrong len for OST $last_lun"
13789                 return
13790         fi
13791
13792         cleanup_130
13793
13794         echo "FIEMAP on 2-stripe file with hole succeeded"
13795 }
13796 run_test 130c "FIEMAP (2-stripe file with hole)"
13797
13798 test_130d() {
13799         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13800
13801         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13802         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13803
13804         trap cleanup_130 EXIT RETURN
13805
13806         local fm_file=$DIR/$tfile
13807         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13808                         error "setstripe on $fm_file"
13809         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13810                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13811
13812         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13813         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13814                 error "dd failed on $fm_file"
13815
13816         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13817         filefrag_op=$(filefrag -ve -k $fm_file |
13818                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13819
13820         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13821                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13822
13823         IFS=$'\n'
13824         tot_len=0
13825         num_luns=1
13826         for line in $filefrag_op
13827         do
13828                 frag_lun=$(echo $line | cut -d: -f5 |
13829                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13830                 ext_len=$(echo $line | cut -d: -f4)
13831                 if (( $frag_lun != $last_lun )); then
13832                         if (( tot_len != 1024 )); then
13833                                 cleanup_130
13834                                 error "FIEMAP on $fm_file failed; returned " \
13835                                 "len $tot_len for OST $last_lun instead of 1024"
13836                                 return
13837                         else
13838                                 (( num_luns += 1 ))
13839                                 tot_len=0
13840                         fi
13841                 fi
13842                 (( tot_len += ext_len ))
13843                 last_lun=$frag_lun
13844         done
13845         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13846                 cleanup_130
13847                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13848                         "luns or wrong len for OST $last_lun"
13849                 return
13850         fi
13851
13852         cleanup_130
13853
13854         echo "FIEMAP on N-stripe file succeeded"
13855 }
13856 run_test 130d "FIEMAP (N-stripe file)"
13857
13858 test_130e() {
13859         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13860
13861         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13862         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13863
13864         trap cleanup_130 EXIT RETURN
13865
13866         local fm_file=$DIR/$tfile
13867         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13868
13869         NUM_BLKS=512
13870         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13871         for ((i = 0; i < $NUM_BLKS; i++)); do
13872                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13873                         conv=notrunc > /dev/null 2>&1
13874         done
13875
13876         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13877         filefrag_op=$(filefrag -ve -k $fm_file |
13878                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13879
13880         last_lun=$(echo $filefrag_op | cut -d: -f5)
13881
13882         IFS=$'\n'
13883         tot_len=0
13884         num_luns=1
13885         for line in $filefrag_op; do
13886                 frag_lun=$(echo $line | cut -d: -f5)
13887                 ext_len=$(echo $line | cut -d: -f4)
13888                 if [[ "$frag_lun" != "$last_lun" ]]; then
13889                         if (( tot_len != $EXPECTED_LEN )); then
13890                                 cleanup_130
13891                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13892                         else
13893                                 (( num_luns += 1 ))
13894                                 tot_len=0
13895                         fi
13896                 fi
13897                 (( tot_len += ext_len ))
13898                 last_lun=$frag_lun
13899         done
13900         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13901                 cleanup_130
13902                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13903         fi
13904
13905         echo "FIEMAP with continuation calls succeeded"
13906 }
13907 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13908
13909 test_130f() {
13910         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13911         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13912
13913         local fm_file=$DIR/$tfile
13914         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13915                 error "multiop create with lov_delay_create on $fm_file"
13916
13917         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13918         filefrag_extents=$(filefrag -vek $fm_file |
13919                            awk '/extents? found/ { print $2 }')
13920         if [[ "$filefrag_extents" != "0" ]]; then
13921                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13922         fi
13923
13924         rm -f $fm_file
13925 }
13926 run_test 130f "FIEMAP (unstriped file)"
13927
13928 test_130g() {
13929         local file=$DIR/$tfile
13930         local nr=$((OSTCOUNT * 100))
13931
13932         $LFS setstripe -C $nr $file ||
13933                 error "failed to setstripe -C $nr $file"
13934
13935         dd if=/dev/zero of=$file count=$nr bs=1M
13936         sync
13937         nr=$($LFS getstripe -c $file)
13938
13939         local extents=$(filefrag -v $file |
13940                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13941
13942         echo "filefrag list $extents extents in file with stripecount $nr"
13943         if (( extents < nr )); then
13944                 $LFS getstripe $file
13945                 filefrag -v $file
13946                 error "filefrag printed $extents < $nr extents"
13947         fi
13948
13949         rm -f $file
13950 }
13951 run_test 130g "FIEMAP (overstripe file)"
13952
13953 # Test for writev/readv
13954 test_131a() {
13955         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13956                 error "writev test failed"
13957         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13958                 error "readv failed"
13959         rm -f $DIR/$tfile
13960 }
13961 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13962
13963 test_131b() {
13964         local fsize=$((524288 + 1048576 + 1572864))
13965         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13966                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13967                         error "append writev test failed"
13968
13969         ((fsize += 1572864 + 1048576))
13970         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13971                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13972                         error "append writev test failed"
13973         rm -f $DIR/$tfile
13974 }
13975 run_test 131b "test append writev"
13976
13977 test_131c() {
13978         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13979         error "NOT PASS"
13980 }
13981 run_test 131c "test read/write on file w/o objects"
13982
13983 test_131d() {
13984         rwv -f $DIR/$tfile -w -n 1 1572864
13985         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13986         if [ "$NOB" != 1572864 ]; then
13987                 error "Short read filed: read $NOB bytes instead of 1572864"
13988         fi
13989         rm -f $DIR/$tfile
13990 }
13991 run_test 131d "test short read"
13992
13993 test_131e() {
13994         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13995         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13996         error "read hitting hole failed"
13997         rm -f $DIR/$tfile
13998 }
13999 run_test 131e "test read hitting hole"
14000
14001 check_stats() {
14002         local facet=$1
14003         local op=$2
14004         local want=${3:-0}
14005         local res
14006
14007         case $facet in
14008         mds*) res=$(do_facet $facet \
14009                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
14010                  ;;
14011         ost*) res=$(do_facet $facet \
14012                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
14013                  ;;
14014         *) error "Wrong facet '$facet'" ;;
14015         esac
14016         [ "$res" ] || error "The counter for $op on $facet was not incremented"
14017         # if the argument $3 is zero, it means any stat increment is ok.
14018         if [[ $want -gt 0 ]]; then
14019                 local count=$(echo $res | awk '{ print $2 }')
14020                 [[ $count -ne $want ]] &&
14021                         error "The $op counter on $facet is $count, not $want"
14022         fi
14023 }
14024
14025 test_133a() {
14026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14027         remote_ost_nodsh && skip "remote OST with nodsh"
14028         remote_mds_nodsh && skip "remote MDS with nodsh"
14029         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14030                 skip_env "MDS doesn't support rename stats"
14031
14032         local testdir=$DIR/${tdir}/stats_testdir
14033
14034         mkdir -p $DIR/${tdir}
14035
14036         # clear stats.
14037         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14038         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14039
14040         # verify mdt stats first.
14041         mkdir ${testdir} || error "mkdir failed"
14042         check_stats $SINGLEMDS "mkdir" 1
14043         touch ${testdir}/${tfile} || error "touch failed"
14044         check_stats $SINGLEMDS "open" 1
14045         check_stats $SINGLEMDS "close" 1
14046         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14047                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14048                 check_stats $SINGLEMDS "mknod" 2
14049         }
14050         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14051         check_stats $SINGLEMDS "unlink" 1
14052         rm -f ${testdir}/${tfile} || error "file remove failed"
14053         check_stats $SINGLEMDS "unlink" 2
14054
14055         # remove working dir and check mdt stats again.
14056         rmdir ${testdir} || error "rmdir failed"
14057         check_stats $SINGLEMDS "rmdir" 1
14058
14059         local testdir1=$DIR/${tdir}/stats_testdir1
14060         mkdir -p ${testdir}
14061         mkdir -p ${testdir1}
14062         touch ${testdir1}/test1
14063         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14064         check_stats $SINGLEMDS "crossdir_rename" 1
14065
14066         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14067         check_stats $SINGLEMDS "samedir_rename" 1
14068
14069         rm -rf $DIR/${tdir}
14070 }
14071 run_test 133a "Verifying MDT stats ========================================"
14072
14073 test_133b() {
14074         local res
14075
14076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14077         remote_ost_nodsh && skip "remote OST with nodsh"
14078         remote_mds_nodsh && skip "remote MDS with nodsh"
14079
14080         local testdir=$DIR/${tdir}/stats_testdir
14081
14082         mkdir -p ${testdir} || error "mkdir failed"
14083         touch ${testdir}/${tfile} || error "touch failed"
14084         cancel_lru_locks mdc
14085
14086         # clear stats.
14087         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14088         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14089
14090         # extra mdt stats verification.
14091         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14092         check_stats $SINGLEMDS "setattr" 1
14093         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14094         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14095         then            # LU-1740
14096                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14097                 check_stats $SINGLEMDS "getattr" 1
14098         fi
14099         rm -rf $DIR/${tdir}
14100
14101         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14102         # so the check below is not reliable
14103         [ $MDSCOUNT -eq 1 ] || return 0
14104
14105         # Sleep to avoid a cached response.
14106         #define OBD_STATFS_CACHE_SECONDS 1
14107         sleep 2
14108         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14109         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14110         $LFS df || error "lfs failed"
14111         check_stats $SINGLEMDS "statfs" 1
14112
14113         # check aggregated statfs (LU-10018)
14114         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14115                 return 0
14116         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14117                 return 0
14118         sleep 2
14119         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14120         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14121         df $DIR
14122         check_stats $SINGLEMDS "statfs" 1
14123
14124         # We want to check that the client didn't send OST_STATFS to
14125         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14126         # extra care is needed here.
14127         if remote_mds; then
14128                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14129                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14130
14131                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14132                 [ "$res" ] && error "OST got STATFS"
14133         fi
14134
14135         return 0
14136 }
14137 run_test 133b "Verifying extra MDT stats =================================="
14138
14139 test_133c() {
14140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14141         remote_ost_nodsh && skip "remote OST with nodsh"
14142         remote_mds_nodsh && skip "remote MDS with nodsh"
14143
14144         local testdir=$DIR/$tdir/stats_testdir
14145
14146         test_mkdir -p $testdir
14147
14148         # verify obdfilter stats.
14149         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14150         sync
14151         cancel_lru_locks osc
14152         wait_delete_completed
14153
14154         # clear stats.
14155         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14156         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14157
14158         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14159                 error "dd failed"
14160         sync
14161         cancel_lru_locks osc
14162         check_stats ost1 "write" 1
14163
14164         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14165         check_stats ost1 "read" 1
14166
14167         > $testdir/$tfile || error "truncate failed"
14168         check_stats ost1 "punch" 1
14169
14170         rm -f $testdir/$tfile || error "file remove failed"
14171         wait_delete_completed
14172         check_stats ost1 "destroy" 1
14173
14174         rm -rf $DIR/$tdir
14175 }
14176 run_test 133c "Verifying OST stats ========================================"
14177
14178 order_2() {
14179         local value=$1
14180         local orig=$value
14181         local order=1
14182
14183         while [ $value -ge 2 ]; do
14184                 order=$((order*2))
14185                 value=$((value/2))
14186         done
14187
14188         if [ $orig -gt $order ]; then
14189                 order=$((order*2))
14190         fi
14191         echo $order
14192 }
14193
14194 size_in_KMGT() {
14195     local value=$1
14196     local size=('K' 'M' 'G' 'T');
14197     local i=0
14198     local size_string=$value
14199
14200     while [ $value -ge 1024 ]; do
14201         if [ $i -gt 3 ]; then
14202             #T is the biggest unit we get here, if that is bigger,
14203             #just return XXXT
14204             size_string=${value}T
14205             break
14206         fi
14207         value=$((value >> 10))
14208         if [ $value -lt 1024 ]; then
14209             size_string=${value}${size[$i]}
14210             break
14211         fi
14212         i=$((i + 1))
14213     done
14214
14215     echo $size_string
14216 }
14217
14218 get_rename_size() {
14219         local size=$1
14220         local context=${2:-.}
14221         local sample=$(do_facet $SINGLEMDS $LCTL \
14222                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14223                 grep -A1 $context |
14224                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14225         echo $sample
14226 }
14227
14228 test_133d() {
14229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14230         remote_ost_nodsh && skip "remote OST with nodsh"
14231         remote_mds_nodsh && skip "remote MDS with nodsh"
14232         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14233                 skip_env "MDS doesn't support rename stats"
14234
14235         local testdir1=$DIR/${tdir}/stats_testdir1
14236         local testdir2=$DIR/${tdir}/stats_testdir2
14237         mkdir -p $DIR/${tdir}
14238
14239         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14240
14241         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14242         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14243
14244         createmany -o $testdir1/test 512 || error "createmany failed"
14245
14246         # check samedir rename size
14247         mv ${testdir1}/test0 ${testdir1}/test_0
14248
14249         local testdir1_size=$(ls -l $DIR/${tdir} |
14250                 awk '/stats_testdir1/ {print $5}')
14251         local testdir2_size=$(ls -l $DIR/${tdir} |
14252                 awk '/stats_testdir2/ {print $5}')
14253
14254         testdir1_size=$(order_2 $testdir1_size)
14255         testdir2_size=$(order_2 $testdir2_size)
14256
14257         testdir1_size=$(size_in_KMGT $testdir1_size)
14258         testdir2_size=$(size_in_KMGT $testdir2_size)
14259
14260         echo "source rename dir size: ${testdir1_size}"
14261         echo "target rename dir size: ${testdir2_size}"
14262
14263         local cmd="do_facet $SINGLEMDS $LCTL "
14264         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14265
14266         eval $cmd || error "$cmd failed"
14267         local samedir=$($cmd | grep 'same_dir')
14268         local same_sample=$(get_rename_size $testdir1_size)
14269         [ -z "$samedir" ] && error "samedir_rename_size count error"
14270         [[ $same_sample -eq 1 ]] ||
14271                 error "samedir_rename_size error $same_sample"
14272         echo "Check same dir rename stats success"
14273
14274         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14275
14276         # check crossdir rename size
14277         mv ${testdir1}/test_0 ${testdir2}/test_0
14278
14279         testdir1_size=$(ls -l $DIR/${tdir} |
14280                 awk '/stats_testdir1/ {print $5}')
14281         testdir2_size=$(ls -l $DIR/${tdir} |
14282                 awk '/stats_testdir2/ {print $5}')
14283
14284         testdir1_size=$(order_2 $testdir1_size)
14285         testdir2_size=$(order_2 $testdir2_size)
14286
14287         testdir1_size=$(size_in_KMGT $testdir1_size)
14288         testdir2_size=$(size_in_KMGT $testdir2_size)
14289
14290         echo "source rename dir size: ${testdir1_size}"
14291         echo "target rename dir size: ${testdir2_size}"
14292
14293         eval $cmd || error "$cmd failed"
14294         local crossdir=$($cmd | grep 'crossdir')
14295         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14296         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14297         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14298         [[ $src_sample -eq 1 ]] ||
14299                 error "crossdir_rename_size error $src_sample"
14300         [[ $tgt_sample -eq 1 ]] ||
14301                 error "crossdir_rename_size error $tgt_sample"
14302         echo "Check cross dir rename stats success"
14303         rm -rf $DIR/${tdir}
14304 }
14305 run_test 133d "Verifying rename_stats ========================================"
14306
14307 test_133e() {
14308         remote_mds_nodsh && skip "remote MDS with nodsh"
14309         remote_ost_nodsh && skip "remote OST with nodsh"
14310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14311
14312         local testdir=$DIR/${tdir}/stats_testdir
14313         local ctr f0 f1 bs=32768 count=42 sum
14314
14315         mkdir -p ${testdir} || error "mkdir failed"
14316
14317         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14318
14319         for ctr in {write,read}_bytes; do
14320                 sync
14321                 cancel_lru_locks osc
14322
14323                 do_facet ost1 $LCTL set_param -n \
14324                         "obdfilter.*.exports.clear=clear"
14325
14326                 if [ $ctr = write_bytes ]; then
14327                         f0=/dev/zero
14328                         f1=${testdir}/${tfile}
14329                 else
14330                         f0=${testdir}/${tfile}
14331                         f1=/dev/null
14332                 fi
14333
14334                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14335                         error "dd failed"
14336                 sync
14337                 cancel_lru_locks osc
14338
14339                 sum=$(do_facet ost1 $LCTL get_param \
14340                         "obdfilter.*.exports.*.stats" |
14341                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14342                                 $1 == ctr { sum += $7 }
14343                                 END { printf("%0.0f", sum) }')
14344
14345                 if ((sum != bs * count)); then
14346                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14347                 fi
14348         done
14349
14350         rm -rf $DIR/${tdir}
14351 }
14352 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14353
14354 test_133f() {
14355         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14356                 skip "too old lustre for get_param -R ($facet_ver)"
14357
14358         # verifying readability.
14359         $LCTL get_param -R '*' &> /dev/null
14360
14361         # Verifing writability with badarea_io.
14362         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14363         local skipped_params='force_lbug|changelog_mask|daemon_file'
14364         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14365                 egrep -v "$skipped_params" |
14366                 xargs -n 1 find $proc_dirs -name |
14367                 xargs -n 1 badarea_io ||
14368                 error "client badarea_io failed"
14369
14370         # remount the FS in case writes/reads /proc break the FS
14371         cleanup || error "failed to unmount"
14372         setup || error "failed to setup"
14373 }
14374 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14375
14376 test_133g() {
14377         remote_mds_nodsh && skip "remote MDS with nodsh"
14378         remote_ost_nodsh && skip "remote OST with nodsh"
14379
14380         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14381         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14382         local facet
14383         for facet in mds1 ost1; do
14384                 local facet_ver=$(lustre_version_code $facet)
14385                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14386                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14387                 else
14388                         log "$facet: too old lustre for get_param -R"
14389                 fi
14390                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14391                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14392                                 tr -d = | egrep -v $skipped_params |
14393                                 xargs -n 1 find $proc_dirs -name |
14394                                 xargs -n 1 badarea_io" ||
14395                                         error "$facet badarea_io failed"
14396                 else
14397                         skip_noexit "$facet: too old lustre for get_param -R"
14398                 fi
14399         done
14400
14401         # remount the FS in case writes/reads /proc break the FS
14402         cleanup || error "failed to unmount"
14403         setup || error "failed to setup"
14404 }
14405 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14406
14407 test_133h() {
14408         remote_mds_nodsh && skip "remote MDS with nodsh"
14409         remote_ost_nodsh && skip "remote OST with nodsh"
14410         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14411                 skip "Need MDS version at least 2.9.54"
14412
14413         local facet
14414         for facet in client mds1 ost1; do
14415                 # Get the list of files that are missing the terminating newline
14416                 local plist=$(do_facet $facet
14417                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14418                 local ent
14419                 for ent in $plist; do
14420                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14421                                 awk -v FS='\v' -v RS='\v\v' \
14422                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14423                                         print FILENAME}'" 2>/dev/null)
14424                         [ -z $missing ] || {
14425                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14426                                 error "file does not end with newline: $facet-$ent"
14427                         }
14428                 done
14429         done
14430 }
14431 run_test 133h "Proc files should end with newlines"
14432
14433 test_134a() {
14434         remote_mds_nodsh && skip "remote MDS with nodsh"
14435         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14436                 skip "Need MDS version at least 2.7.54"
14437
14438         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14439         cancel_lru_locks mdc
14440
14441         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14442         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14443         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14444
14445         local nr=1000
14446         createmany -o $DIR/$tdir/f $nr ||
14447                 error "failed to create $nr files in $DIR/$tdir"
14448         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14449
14450         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14451         do_facet mds1 $LCTL set_param fail_loc=0x327
14452         do_facet mds1 $LCTL set_param fail_val=500
14453         touch $DIR/$tdir/m
14454
14455         echo "sleep 10 seconds ..."
14456         sleep 10
14457         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14458
14459         do_facet mds1 $LCTL set_param fail_loc=0
14460         do_facet mds1 $LCTL set_param fail_val=0
14461         [ $lck_cnt -lt $unused ] ||
14462                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14463
14464         rm $DIR/$tdir/m
14465         unlinkmany $DIR/$tdir/f $nr
14466 }
14467 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14468
14469 test_134b() {
14470         remote_mds_nodsh && skip "remote MDS with nodsh"
14471         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14472                 skip "Need MDS version at least 2.7.54"
14473
14474         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14475         cancel_lru_locks mdc
14476
14477         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14478                         ldlm.lock_reclaim_threshold_mb)
14479         # disable reclaim temporarily
14480         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14481
14482         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14483         do_facet mds1 $LCTL set_param fail_loc=0x328
14484         do_facet mds1 $LCTL set_param fail_val=500
14485
14486         $LCTL set_param debug=+trace
14487
14488         local nr=600
14489         createmany -o $DIR/$tdir/f $nr &
14490         local create_pid=$!
14491
14492         echo "Sleep $TIMEOUT seconds ..."
14493         sleep $TIMEOUT
14494         if ! ps -p $create_pid  > /dev/null 2>&1; then
14495                 do_facet mds1 $LCTL set_param fail_loc=0
14496                 do_facet mds1 $LCTL set_param fail_val=0
14497                 do_facet mds1 $LCTL set_param \
14498                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14499                 error "createmany finished incorrectly!"
14500         fi
14501         do_facet mds1 $LCTL set_param fail_loc=0
14502         do_facet mds1 $LCTL set_param fail_val=0
14503         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14504         wait $create_pid || return 1
14505
14506         unlinkmany $DIR/$tdir/f $nr
14507 }
14508 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14509
14510 test_135() {
14511         remote_mds_nodsh && skip "remote MDS with nodsh"
14512         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14513                 skip "Need MDS version at least 2.13.50"
14514         local fname
14515
14516         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14517
14518 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14519         #set only one record at plain llog
14520         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14521
14522         #fill already existed plain llog each 64767
14523         #wrapping whole catalog
14524         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14525
14526         createmany -o $DIR/$tdir/$tfile_ 64700
14527         for (( i = 0; i < 64700; i = i + 2 ))
14528         do
14529                 rm $DIR/$tdir/$tfile_$i &
14530                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14531                 local pid=$!
14532                 wait $pid
14533         done
14534
14535         #waiting osp synchronization
14536         wait_delete_completed
14537 }
14538 run_test 135 "Race catalog processing"
14539
14540 test_136() {
14541         remote_mds_nodsh && skip "remote MDS with nodsh"
14542         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14543                 skip "Need MDS version at least 2.13.50"
14544         local fname
14545
14546         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14547         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14548         #set only one record at plain llog
14549 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14550         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14551
14552         #fill already existed 2 plain llogs each 64767
14553         #wrapping whole catalog
14554         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14555         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14556         wait_delete_completed
14557
14558         createmany -o $DIR/$tdir/$tfile_ 10
14559         sleep 25
14560
14561         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14562         for (( i = 0; i < 10; i = i + 3 ))
14563         do
14564                 rm $DIR/$tdir/$tfile_$i &
14565                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14566                 local pid=$!
14567                 wait $pid
14568                 sleep 7
14569                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14570         done
14571
14572         #waiting osp synchronization
14573         wait_delete_completed
14574 }
14575 run_test 136 "Race catalog processing 2"
14576
14577 test_140() { #bug-17379
14578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14579
14580         test_mkdir $DIR/$tdir
14581         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14582         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14583
14584         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14585         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14586         local i=0
14587         while i=$((i + 1)); do
14588                 test_mkdir $i
14589                 cd $i || error "Changing to $i"
14590                 ln -s ../stat stat || error "Creating stat symlink"
14591                 # Read the symlink until ELOOP present,
14592                 # not LBUGing the system is considered success,
14593                 # we didn't overrun the stack.
14594                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14595                 if [ $ret -ne 0 ]; then
14596                         if [ $ret -eq 40 ]; then
14597                                 break  # -ELOOP
14598                         else
14599                                 error "Open stat symlink"
14600                                         return
14601                         fi
14602                 fi
14603         done
14604         i=$((i - 1))
14605         echo "The symlink depth = $i"
14606         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14607                 error "Invalid symlink depth"
14608
14609         # Test recursive symlink
14610         ln -s symlink_self symlink_self
14611         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14612         echo "open symlink_self returns $ret"
14613         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14614 }
14615 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14616
14617 test_150a() {
14618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14619
14620         local TF="$TMP/$tfile"
14621
14622         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14623         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14624         cp $TF $DIR/$tfile
14625         cancel_lru_locks $OSC
14626         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14627         remount_client $MOUNT
14628         df -P $MOUNT
14629         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14630
14631         $TRUNCATE $TF 6000
14632         $TRUNCATE $DIR/$tfile 6000
14633         cancel_lru_locks $OSC
14634         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14635
14636         echo "12345" >>$TF
14637         echo "12345" >>$DIR/$tfile
14638         cancel_lru_locks $OSC
14639         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14640
14641         echo "12345" >>$TF
14642         echo "12345" >>$DIR/$tfile
14643         cancel_lru_locks $OSC
14644         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14645 }
14646 run_test 150a "truncate/append tests"
14647
14648 test_150b() {
14649         check_set_fallocate_or_skip
14650
14651         touch $DIR/$tfile
14652         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14653         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14654 }
14655 run_test 150b "Verify fallocate (prealloc) functionality"
14656
14657 test_150bb() {
14658         check_set_fallocate_or_skip
14659
14660         touch $DIR/$tfile
14661         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14662         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14663         > $DIR/$tfile
14664         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14665         # precomputed md5sum for 20MB of zeroes
14666         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14667         local sum=($(md5sum $DIR/$tfile))
14668
14669         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14670
14671         check_set_fallocate 1
14672
14673         > $DIR/$tfile
14674         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14675         sum=($(md5sum $DIR/$tfile))
14676
14677         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14678 }
14679 run_test 150bb "Verify fallocate modes both zero space"
14680
14681 test_150c() {
14682         check_set_fallocate_or_skip
14683         local striping="-c2"
14684
14685         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14686         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14687         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14688         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14689         local want=$((OSTCOUNT * 1048576))
14690
14691         # Must allocate all requested space, not more than 5% extra
14692         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14693                 error "bytes $bytes is not $want"
14694
14695         rm -f $DIR/$tfile
14696
14697         echo "verify fallocate on PFL file"
14698
14699         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14700
14701         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14702                 error "Create $DIR/$tfile failed"
14703         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14704         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14705         want=$((512 * 1048576))
14706
14707         # Must allocate all requested space, not more than 5% extra
14708         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14709                 error "bytes $bytes is not $want"
14710 }
14711 run_test 150c "Verify fallocate Size and Blocks"
14712
14713 test_150d() {
14714         check_set_fallocate_or_skip
14715         local striping="-c2"
14716
14717         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14718
14719         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14720         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14721                 error "setstripe failed"
14722         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14723         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14724         local want=$((OSTCOUNT * 1048576))
14725
14726         # Must allocate all requested space, not more than 5% extra
14727         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14728                 error "bytes $bytes is not $want"
14729 }
14730 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14731
14732 test_150e() {
14733         check_set_fallocate_or_skip
14734
14735         echo "df before:"
14736         $LFS df
14737         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14738         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14739                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14740
14741         # Find OST with Minimum Size
14742         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14743                        sort -un | head -1)
14744
14745         # Get 100MB per OST of the available space to reduce run time
14746         # else 60% of the available space if we are running SLOW tests
14747         if [ $SLOW == "no" ]; then
14748                 local space=$((1024 * 100 * OSTCOUNT))
14749         else
14750                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14751         fi
14752
14753         fallocate -l${space}k $DIR/$tfile ||
14754                 error "fallocate ${space}k $DIR/$tfile failed"
14755         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14756
14757         # get size immediately after fallocate. This should be correctly
14758         # updated
14759         local size=$(stat -c '%s' $DIR/$tfile)
14760         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14761
14762         # Sleep for a while for statfs to get updated. And not pull from cache.
14763         sleep 2
14764
14765         echo "df after fallocate:"
14766         $LFS df
14767
14768         (( size / 1024 == space )) || error "size $size != requested $space"
14769         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14770                 error "used $used < space $space"
14771
14772         rm $DIR/$tfile || error "rm failed"
14773         sync
14774         wait_delete_completed
14775
14776         echo "df after unlink:"
14777         $LFS df
14778 }
14779 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14780
14781 test_150f() {
14782         local size
14783         local blocks
14784         local want_size_before=20480 # in bytes
14785         local want_blocks_before=40 # 512 sized blocks
14786         local want_blocks_after=24  # 512 sized blocks
14787         local length=$(((want_blocks_before - want_blocks_after) * 512))
14788
14789         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14790                 skip "need at least 2.14.0 for fallocate punch"
14791
14792         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14793                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14794         fi
14795
14796         check_set_fallocate_or_skip
14797         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14798
14799         [[ "x$DOM" == "xyes" ]] &&
14800                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14801
14802         echo "Verify fallocate punch: Range within the file range"
14803         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14804                 error "dd failed for bs 4096 and count 5"
14805
14806         # Call fallocate with punch range which is within the file range
14807         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14808                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14809         # client must see changes immediately after fallocate
14810         size=$(stat -c '%s' $DIR/$tfile)
14811         blocks=$(stat -c '%b' $DIR/$tfile)
14812
14813         # Verify punch worked.
14814         (( blocks == want_blocks_after )) ||
14815                 error "punch failed: blocks $blocks != $want_blocks_after"
14816
14817         (( size == want_size_before )) ||
14818                 error "punch failed: size $size != $want_size_before"
14819
14820         # Verify there is hole in file
14821         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14822         # precomputed md5sum
14823         local expect="4a9a834a2db02452929c0a348273b4aa"
14824
14825         cksum=($(md5sum $DIR/$tfile))
14826         [[ "${cksum[0]}" == "$expect" ]] ||
14827                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14828
14829         # Start second sub-case for fallocate punch.
14830         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14831         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14832                 error "dd failed for bs 4096 and count 5"
14833
14834         # Punch range less than block size will have no change in block count
14835         want_blocks_after=40  # 512 sized blocks
14836
14837         # Punch overlaps two blocks and less than blocksize
14838         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14839                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14840         size=$(stat -c '%s' $DIR/$tfile)
14841         blocks=$(stat -c '%b' $DIR/$tfile)
14842
14843         # Verify punch worked.
14844         (( blocks == want_blocks_after )) ||
14845                 error "punch failed: blocks $blocks != $want_blocks_after"
14846
14847         (( size == want_size_before )) ||
14848                 error "punch failed: size $size != $want_size_before"
14849
14850         # Verify if range is really zero'ed out. We expect Zeros.
14851         # precomputed md5sum
14852         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14853         cksum=($(md5sum $DIR/$tfile))
14854         [[ "${cksum[0]}" == "$expect" ]] ||
14855                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14856 }
14857 run_test 150f "Verify fallocate punch functionality"
14858
14859 test_150g() {
14860         local space
14861         local size
14862         local blocks
14863         local blocks_after
14864         local size_after
14865         local BS=4096 # Block size in bytes
14866
14867         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14868                 skip "need at least 2.14.0 for fallocate punch"
14869
14870         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14871                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14872         fi
14873
14874         check_set_fallocate_or_skip
14875         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14876
14877         if [[ "x$DOM" == "xyes" ]]; then
14878                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14879                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14880         else
14881                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14882                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14883         fi
14884
14885         # Get 100MB per OST of the available space to reduce run time
14886         # else 60% of the available space if we are running SLOW tests
14887         if [ $SLOW == "no" ]; then
14888                 space=$((1024 * 100 * OSTCOUNT))
14889         else
14890                 # Find OST with Minimum Size
14891                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14892                         sort -un | head -1)
14893                 echo "min size OST: $space"
14894                 space=$(((space * 60)/100 * OSTCOUNT))
14895         fi
14896         # space in 1k units, round to 4k blocks
14897         local blkcount=$((space * 1024 / $BS))
14898
14899         echo "Verify fallocate punch: Very large Range"
14900         fallocate -l${space}k $DIR/$tfile ||
14901                 error "fallocate ${space}k $DIR/$tfile failed"
14902         # write 1M at the end, start and in the middle
14903         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14904                 error "dd failed: bs $BS count 256"
14905         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14906                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14907         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14908                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14909
14910         # Gather stats.
14911         size=$(stat -c '%s' $DIR/$tfile)
14912
14913         # gather punch length.
14914         local punch_size=$((size - (BS * 2)))
14915
14916         echo "punch_size = $punch_size"
14917         echo "size - punch_size: $((size - punch_size))"
14918         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14919
14920         # Call fallocate to punch all except 2 blocks. We leave the
14921         # first and the last block
14922         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14923         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
14924                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
14925
14926         size_after=$(stat -c '%s' $DIR/$tfile)
14927         blocks_after=$(stat -c '%b' $DIR/$tfile)
14928
14929         # Verify punch worked.
14930         # Size should be kept
14931         (( size == size_after )) ||
14932                 error "punch failed: size $size != $size_after"
14933
14934         # two 4k data blocks to remain plus possible 1 extra extent block
14935         (( blocks_after <= ((BS / 512) * 3) )) ||
14936                 error "too many blocks remains: $blocks_after"
14937
14938         # Verify that file has hole between the first and the last blocks
14939         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14940         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14941
14942         echo "Hole at [$hole_start, $hole_end)"
14943         (( hole_start == BS )) ||
14944                 error "no hole at offset $BS after punch"
14945
14946         (( hole_end == BS + punch_size )) ||
14947                 error "data at offset $hole_end < $((BS + punch_size))"
14948 }
14949 run_test 150g "Verify fallocate punch on large range"
14950
14951 #LU-2902 roc_hit was not able to read all values from lproc
14952 function roc_hit_init() {
14953         local list=$(comma_list $(osts_nodes))
14954         local dir=$DIR/$tdir-check
14955         local file=$dir/$tfile
14956         local BEFORE
14957         local AFTER
14958         local idx
14959
14960         test_mkdir $dir
14961         #use setstripe to do a write to every ost
14962         for i in $(seq 0 $((OSTCOUNT-1))); do
14963                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14964                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14965                 idx=$(printf %04x $i)
14966                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14967                         awk '$1 == "cache_access" {sum += $7}
14968                                 END { printf("%0.0f", sum) }')
14969
14970                 cancel_lru_locks osc
14971                 cat $file >/dev/null
14972
14973                 AFTER=$(get_osd_param $list *OST*$idx stats |
14974                         awk '$1 == "cache_access" {sum += $7}
14975                                 END { printf("%0.0f", sum) }')
14976
14977                 echo BEFORE:$BEFORE AFTER:$AFTER
14978                 if ! let "AFTER - BEFORE == 4"; then
14979                         rm -rf $dir
14980                         error "roc_hit is not safe to use"
14981                 fi
14982                 rm $file
14983         done
14984
14985         rm -rf $dir
14986 }
14987
14988 function roc_hit() {
14989         local list=$(comma_list $(osts_nodes))
14990         echo $(get_osd_param $list '' stats |
14991                 awk '$1 == "cache_hit" {sum += $7}
14992                         END { printf("%0.0f", sum) }')
14993 }
14994
14995 function set_cache() {
14996         local on=1
14997
14998         if [ "$2" == "off" ]; then
14999                 on=0;
15000         fi
15001         local list=$(comma_list $(osts_nodes))
15002         set_osd_param $list '' $1_cache_enable $on
15003
15004         cancel_lru_locks osc
15005 }
15006
15007 test_151() {
15008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15009         remote_ost_nodsh && skip "remote OST with nodsh"
15010
15011         local CPAGES=3
15012         local list=$(comma_list $(osts_nodes))
15013
15014         # check whether obdfilter is cache capable at all
15015         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15016                 skip "not cache-capable obdfilter"
15017         fi
15018
15019         # check cache is enabled on all obdfilters
15020         if get_osd_param $list '' read_cache_enable | grep 0; then
15021                 skip "oss cache is disabled"
15022         fi
15023
15024         set_osd_param $list '' writethrough_cache_enable 1
15025
15026         # check write cache is enabled on all obdfilters
15027         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15028                 skip "oss write cache is NOT enabled"
15029         fi
15030
15031         roc_hit_init
15032
15033         #define OBD_FAIL_OBD_NO_LRU  0x609
15034         do_nodes $list $LCTL set_param fail_loc=0x609
15035
15036         # pages should be in the case right after write
15037         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15038                 error "dd failed"
15039
15040         local BEFORE=$(roc_hit)
15041         cancel_lru_locks osc
15042         cat $DIR/$tfile >/dev/null
15043         local AFTER=$(roc_hit)
15044
15045         do_nodes $list $LCTL set_param fail_loc=0
15046
15047         if ! let "AFTER - BEFORE == CPAGES"; then
15048                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15049         fi
15050
15051         cancel_lru_locks osc
15052         # invalidates OST cache
15053         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15054         set_osd_param $list '' read_cache_enable 0
15055         cat $DIR/$tfile >/dev/null
15056
15057         # now data shouldn't be found in the cache
15058         BEFORE=$(roc_hit)
15059         cancel_lru_locks osc
15060         cat $DIR/$tfile >/dev/null
15061         AFTER=$(roc_hit)
15062         if let "AFTER - BEFORE != 0"; then
15063                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15064         fi
15065
15066         set_osd_param $list '' read_cache_enable 1
15067         rm -f $DIR/$tfile
15068 }
15069 run_test 151 "test cache on oss and controls ==============================="
15070
15071 test_152() {
15072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15073
15074         local TF="$TMP/$tfile"
15075
15076         # simulate ENOMEM during write
15077 #define OBD_FAIL_OST_NOMEM      0x226
15078         lctl set_param fail_loc=0x80000226
15079         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15080         cp $TF $DIR/$tfile
15081         sync || error "sync failed"
15082         lctl set_param fail_loc=0
15083
15084         # discard client's cache
15085         cancel_lru_locks osc
15086
15087         # simulate ENOMEM during read
15088         lctl set_param fail_loc=0x80000226
15089         cmp $TF $DIR/$tfile || error "cmp failed"
15090         lctl set_param fail_loc=0
15091
15092         rm -f $TF
15093 }
15094 run_test 152 "test read/write with enomem ============================"
15095
15096 test_153() {
15097         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15098 }
15099 run_test 153 "test if fdatasync does not crash ======================="
15100
15101 dot_lustre_fid_permission_check() {
15102         local fid=$1
15103         local ffid=$MOUNT/.lustre/fid/$fid
15104         local test_dir=$2
15105
15106         echo "stat fid $fid"
15107         stat $ffid > /dev/null || error "stat $ffid failed."
15108         echo "touch fid $fid"
15109         touch $ffid || error "touch $ffid failed."
15110         echo "write to fid $fid"
15111         cat /etc/hosts > $ffid || error "write $ffid failed."
15112         echo "read fid $fid"
15113         diff /etc/hosts $ffid || error "read $ffid failed."
15114         echo "append write to fid $fid"
15115         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15116         echo "rename fid $fid"
15117         mv $ffid $test_dir/$tfile.1 &&
15118                 error "rename $ffid to $tfile.1 should fail."
15119         touch $test_dir/$tfile.1
15120         mv $test_dir/$tfile.1 $ffid &&
15121                 error "rename $tfile.1 to $ffid should fail."
15122         rm -f $test_dir/$tfile.1
15123         echo "truncate fid $fid"
15124         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15125         echo "link fid $fid"
15126         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15127         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15128                 echo "setfacl fid $fid"
15129                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15130                 echo "getfacl fid $fid"
15131                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15132         fi
15133         echo "unlink fid $fid"
15134         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15135         echo "mknod fid $fid"
15136         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15137
15138         fid=[0xf00000400:0x1:0x0]
15139         ffid=$MOUNT/.lustre/fid/$fid
15140
15141         echo "stat non-exist fid $fid"
15142         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15143         echo "write to non-exist fid $fid"
15144         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15145         echo "link new fid $fid"
15146         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15147
15148         mkdir -p $test_dir/$tdir
15149         touch $test_dir/$tdir/$tfile
15150         fid=$($LFS path2fid $test_dir/$tdir)
15151         rc=$?
15152         [ $rc -ne 0 ] &&
15153                 error "error: could not get fid for $test_dir/$dir/$tfile."
15154
15155         ffid=$MOUNT/.lustre/fid/$fid
15156
15157         echo "ls $fid"
15158         ls $ffid > /dev/null || error "ls $ffid failed."
15159         echo "touch $fid/$tfile.1"
15160         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15161
15162         echo "touch $MOUNT/.lustre/fid/$tfile"
15163         touch $MOUNT/.lustre/fid/$tfile && \
15164                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15165
15166         echo "setxattr to $MOUNT/.lustre/fid"
15167         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15168
15169         echo "listxattr for $MOUNT/.lustre/fid"
15170         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15171
15172         echo "delxattr from $MOUNT/.lustre/fid"
15173         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15174
15175         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15176         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15177                 error "touch invalid fid should fail."
15178
15179         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15180         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15181                 error "touch non-normal fid should fail."
15182
15183         echo "rename $tdir to $MOUNT/.lustre/fid"
15184         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15185                 error "rename to $MOUNT/.lustre/fid should fail."
15186
15187         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15188         then            # LU-3547
15189                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15190                 local new_obf_mode=777
15191
15192                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15193                 chmod $new_obf_mode $DIR/.lustre/fid ||
15194                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15195
15196                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15197                 [ $obf_mode -eq $new_obf_mode ] ||
15198                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15199
15200                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15201                 chmod $old_obf_mode $DIR/.lustre/fid ||
15202                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15203         fi
15204
15205         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15206         fid=$($LFS path2fid $test_dir/$tfile-2)
15207
15208         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15209         then # LU-5424
15210                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15211                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15212                         error "create lov data thru .lustre failed"
15213         fi
15214         echo "cp /etc/passwd $test_dir/$tfile-2"
15215         cp /etc/passwd $test_dir/$tfile-2 ||
15216                 error "copy to $test_dir/$tfile-2 failed."
15217         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15218         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15219                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15220
15221         rm -rf $test_dir/tfile.lnk
15222         rm -rf $test_dir/$tfile-2
15223 }
15224
15225 test_154A() {
15226         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15227                 skip "Need MDS version at least 2.4.1"
15228
15229         local tf=$DIR/$tfile
15230         touch $tf
15231
15232         local fid=$($LFS path2fid $tf)
15233         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15234
15235         # check that we get the same pathname back
15236         local rootpath
15237         local found
15238         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15239                 echo "$rootpath $fid"
15240                 found=$($LFS fid2path $rootpath "$fid")
15241                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15242                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15243         done
15244
15245         # check wrong root path format
15246         rootpath=$MOUNT"_wrong"
15247         found=$($LFS fid2path $rootpath "$fid")
15248         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15249 }
15250 run_test 154A "lfs path2fid and fid2path basic checks"
15251
15252 test_154B() {
15253         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15254                 skip "Need MDS version at least 2.4.1"
15255
15256         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15257         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15258         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15259         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15260
15261         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15262         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15263
15264         # check that we get the same pathname
15265         echo "PFID: $PFID, name: $name"
15266         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15267         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15268         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15269                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15270
15271         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15272 }
15273 run_test 154B "verify the ll_decode_linkea tool"
15274
15275 test_154a() {
15276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15277         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15278         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15279                 skip "Need MDS version at least 2.2.51"
15280         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15281
15282         cp /etc/hosts $DIR/$tfile
15283
15284         fid=$($LFS path2fid $DIR/$tfile)
15285         rc=$?
15286         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15287
15288         dot_lustre_fid_permission_check "$fid" $DIR ||
15289                 error "dot lustre permission check $fid failed"
15290
15291         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15292
15293         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15294
15295         touch $MOUNT/.lustre/file &&
15296                 error "creation is not allowed under .lustre"
15297
15298         mkdir $MOUNT/.lustre/dir &&
15299                 error "mkdir is not allowed under .lustre"
15300
15301         rm -rf $DIR/$tfile
15302 }
15303 run_test 154a "Open-by-FID"
15304
15305 test_154b() {
15306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15307         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15308         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15309         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15310                 skip "Need MDS version at least 2.2.51"
15311
15312         local remote_dir=$DIR/$tdir/remote_dir
15313         local MDTIDX=1
15314         local rc=0
15315
15316         mkdir -p $DIR/$tdir
15317         $LFS mkdir -i $MDTIDX $remote_dir ||
15318                 error "create remote directory failed"
15319
15320         cp /etc/hosts $remote_dir/$tfile
15321
15322         fid=$($LFS path2fid $remote_dir/$tfile)
15323         rc=$?
15324         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15325
15326         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15327                 error "dot lustre permission check $fid failed"
15328         rm -rf $DIR/$tdir
15329 }
15330 run_test 154b "Open-by-FID for remote directory"
15331
15332 test_154c() {
15333         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15334                 skip "Need MDS version at least 2.4.1"
15335
15336         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15337         local FID1=$($LFS path2fid $DIR/$tfile.1)
15338         local FID2=$($LFS path2fid $DIR/$tfile.2)
15339         local FID3=$($LFS path2fid $DIR/$tfile.3)
15340
15341         local N=1
15342         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15343                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15344                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15345                 local want=FID$N
15346                 [ "$FID" = "${!want}" ] ||
15347                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15348                 N=$((N + 1))
15349         done
15350
15351         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15352         do
15353                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15354                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15355                 N=$((N + 1))
15356         done
15357 }
15358 run_test 154c "lfs path2fid and fid2path multiple arguments"
15359
15360 test_154d() {
15361         remote_mds_nodsh && skip "remote MDS with nodsh"
15362         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15363                 skip "Need MDS version at least 2.5.53"
15364
15365         if remote_mds; then
15366                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15367         else
15368                 nid="0@lo"
15369         fi
15370         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15371         local fd
15372         local cmd
15373
15374         rm -f $DIR/$tfile
15375         touch $DIR/$tfile
15376
15377         local fid=$($LFS path2fid $DIR/$tfile)
15378         # Open the file
15379         fd=$(free_fd)
15380         cmd="exec $fd<$DIR/$tfile"
15381         eval $cmd
15382         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15383         echo "$fid_list" | grep "$fid"
15384         rc=$?
15385
15386         cmd="exec $fd>/dev/null"
15387         eval $cmd
15388         if [ $rc -ne 0 ]; then
15389                 error "FID $fid not found in open files list $fid_list"
15390         fi
15391 }
15392 run_test 154d "Verify open file fid"
15393
15394 test_154e()
15395 {
15396         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15397                 skip "Need MDS version at least 2.6.50"
15398
15399         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15400                 error ".lustre returned by readdir"
15401         fi
15402 }
15403 run_test 154e ".lustre is not returned by readdir"
15404
15405 test_154f() {
15406         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15407
15408         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15409         mkdir_on_mdt0 $DIR/$tdir
15410         # test dirs inherit from its stripe
15411         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15412         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15413         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15414         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15415         touch $DIR/f
15416
15417         # get fid of parents
15418         local FID0=$($LFS path2fid $DIR/$tdir)
15419         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15420         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15421         local FID3=$($LFS path2fid $DIR)
15422
15423         # check that path2fid --parents returns expected <parent_fid>/name
15424         # 1) test for a directory (single parent)
15425         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15426         [ "$parent" == "$FID0/foo1" ] ||
15427                 error "expected parent: $FID0/foo1, got: $parent"
15428
15429         # 2) test for a file with nlink > 1 (multiple parents)
15430         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15431         echo "$parent" | grep -F "$FID1/$tfile" ||
15432                 error "$FID1/$tfile not returned in parent list"
15433         echo "$parent" | grep -F "$FID2/link" ||
15434                 error "$FID2/link not returned in parent list"
15435
15436         # 3) get parent by fid
15437         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15438         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15439         echo "$parent" | grep -F "$FID1/$tfile" ||
15440                 error "$FID1/$tfile not returned in parent list (by fid)"
15441         echo "$parent" | grep -F "$FID2/link" ||
15442                 error "$FID2/link not returned in parent list (by fid)"
15443
15444         # 4) test for entry in root directory
15445         parent=$($LFS path2fid --parents $DIR/f)
15446         echo "$parent" | grep -F "$FID3/f" ||
15447                 error "$FID3/f not returned in parent list"
15448
15449         # 5) test it on root directory
15450         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15451                 error "$MOUNT should not have parents"
15452
15453         # enable xattr caching and check that linkea is correctly updated
15454         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15455         save_lustre_params client "llite.*.xattr_cache" > $save
15456         lctl set_param llite.*.xattr_cache 1
15457
15458         # 6.1) linkea update on rename
15459         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15460
15461         # get parents by fid
15462         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15463         # foo1 should no longer be returned in parent list
15464         echo "$parent" | grep -F "$FID1" &&
15465                 error "$FID1 should no longer be in parent list"
15466         # the new path should appear
15467         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15468                 error "$FID2/$tfile.moved is not in parent list"
15469
15470         # 6.2) linkea update on unlink
15471         rm -f $DIR/$tdir/foo2/link
15472         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15473         # foo2/link should no longer be returned in parent list
15474         echo "$parent" | grep -F "$FID2/link" &&
15475                 error "$FID2/link should no longer be in parent list"
15476         true
15477
15478         rm -f $DIR/f
15479         restore_lustre_params < $save
15480         rm -f $save
15481 }
15482 run_test 154f "get parent fids by reading link ea"
15483
15484 test_154g()
15485 {
15486         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15487         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15488            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15489                 skip "Need MDS version at least 2.6.92"
15490
15491         mkdir_on_mdt0 $DIR/$tdir
15492         llapi_fid_test -d $DIR/$tdir
15493 }
15494 run_test 154g "various llapi FID tests"
15495
15496 test_155_small_load() {
15497     local temp=$TMP/$tfile
15498     local file=$DIR/$tfile
15499
15500     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15501         error "dd of=$temp bs=6096 count=1 failed"
15502     cp $temp $file
15503     cancel_lru_locks $OSC
15504     cmp $temp $file || error "$temp $file differ"
15505
15506     $TRUNCATE $temp 6000
15507     $TRUNCATE $file 6000
15508     cmp $temp $file || error "$temp $file differ (truncate1)"
15509
15510     echo "12345" >>$temp
15511     echo "12345" >>$file
15512     cmp $temp $file || error "$temp $file differ (append1)"
15513
15514     echo "12345" >>$temp
15515     echo "12345" >>$file
15516     cmp $temp $file || error "$temp $file differ (append2)"
15517
15518     rm -f $temp $file
15519     true
15520 }
15521
15522 test_155_big_load() {
15523         remote_ost_nodsh && skip "remote OST with nodsh"
15524
15525         local temp=$TMP/$tfile
15526         local file=$DIR/$tfile
15527
15528         free_min_max
15529         local cache_size=$(do_facet ost$((MAXI+1)) \
15530                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15531         local large_file_size=$((cache_size * 2))
15532
15533         echo "OSS cache size: $cache_size KB"
15534         echo "Large file size: $large_file_size KB"
15535
15536         [ $MAXV -le $large_file_size ] &&
15537                 skip_env "max available OST size needs > $large_file_size KB"
15538
15539         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15540
15541         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15542                 error "dd of=$temp bs=$large_file_size count=1k failed"
15543         cp $temp $file
15544         ls -lh $temp $file
15545         cancel_lru_locks osc
15546         cmp $temp $file || error "$temp $file differ"
15547
15548         rm -f $temp $file
15549         true
15550 }
15551
15552 save_writethrough() {
15553         local facets=$(get_facets OST)
15554
15555         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15556 }
15557
15558 test_155a() {
15559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15560
15561         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15562
15563         save_writethrough $p
15564
15565         set_cache read on
15566         set_cache writethrough on
15567         test_155_small_load
15568         restore_lustre_params < $p
15569         rm -f $p
15570 }
15571 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15572
15573 test_155b() {
15574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15575
15576         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15577
15578         save_writethrough $p
15579
15580         set_cache read on
15581         set_cache writethrough off
15582         test_155_small_load
15583         restore_lustre_params < $p
15584         rm -f $p
15585 }
15586 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15587
15588 test_155c() {
15589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15590
15591         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15592
15593         save_writethrough $p
15594
15595         set_cache read off
15596         set_cache writethrough on
15597         test_155_small_load
15598         restore_lustre_params < $p
15599         rm -f $p
15600 }
15601 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15602
15603 test_155d() {
15604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15605
15606         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15607
15608         save_writethrough $p
15609
15610         set_cache read off
15611         set_cache writethrough off
15612         test_155_small_load
15613         restore_lustre_params < $p
15614         rm -f $p
15615 }
15616 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15617
15618 test_155e() {
15619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15620
15621         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15622
15623         save_writethrough $p
15624
15625         set_cache read on
15626         set_cache writethrough on
15627         test_155_big_load
15628         restore_lustre_params < $p
15629         rm -f $p
15630 }
15631 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15632
15633 test_155f() {
15634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15635
15636         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15637
15638         save_writethrough $p
15639
15640         set_cache read on
15641         set_cache writethrough off
15642         test_155_big_load
15643         restore_lustre_params < $p
15644         rm -f $p
15645 }
15646 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15647
15648 test_155g() {
15649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15650
15651         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15652
15653         save_writethrough $p
15654
15655         set_cache read off
15656         set_cache writethrough on
15657         test_155_big_load
15658         restore_lustre_params < $p
15659         rm -f $p
15660 }
15661 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15662
15663 test_155h() {
15664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15665
15666         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15667
15668         save_writethrough $p
15669
15670         set_cache read off
15671         set_cache writethrough off
15672         test_155_big_load
15673         restore_lustre_params < $p
15674         rm -f $p
15675 }
15676 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15677
15678 test_156() {
15679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15680         remote_ost_nodsh && skip "remote OST with nodsh"
15681         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15682                 skip "stats not implemented on old servers"
15683         [ "$ost1_FSTYPE" = "zfs" ] &&
15684                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15685
15686         local CPAGES=3
15687         local BEFORE
15688         local AFTER
15689         local file="$DIR/$tfile"
15690         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15691
15692         save_writethrough $p
15693         roc_hit_init
15694
15695         log "Turn on read and write cache"
15696         set_cache read on
15697         set_cache writethrough on
15698
15699         log "Write data and read it back."
15700         log "Read should be satisfied from the cache."
15701         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15702         BEFORE=$(roc_hit)
15703         cancel_lru_locks osc
15704         cat $file >/dev/null
15705         AFTER=$(roc_hit)
15706         if ! let "AFTER - BEFORE == CPAGES"; then
15707                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15708         else
15709                 log "cache hits: before: $BEFORE, after: $AFTER"
15710         fi
15711
15712         log "Read again; it should be satisfied from the cache."
15713         BEFORE=$AFTER
15714         cancel_lru_locks osc
15715         cat $file >/dev/null
15716         AFTER=$(roc_hit)
15717         if ! let "AFTER - BEFORE == CPAGES"; then
15718                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15719         else
15720                 log "cache hits:: before: $BEFORE, after: $AFTER"
15721         fi
15722
15723         log "Turn off the read cache and turn on the write cache"
15724         set_cache read off
15725         set_cache writethrough on
15726
15727         log "Read again; it should be satisfied from the cache."
15728         BEFORE=$(roc_hit)
15729         cancel_lru_locks osc
15730         cat $file >/dev/null
15731         AFTER=$(roc_hit)
15732         if ! let "AFTER - BEFORE == CPAGES"; then
15733                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15734         else
15735                 log "cache hits:: before: $BEFORE, after: $AFTER"
15736         fi
15737
15738         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15739                 # > 2.12.56 uses pagecache if cached
15740                 log "Read again; it should not be satisfied from the cache."
15741                 BEFORE=$AFTER
15742                 cancel_lru_locks osc
15743                 cat $file >/dev/null
15744                 AFTER=$(roc_hit)
15745                 if ! let "AFTER - BEFORE == 0"; then
15746                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15747                 else
15748                         log "cache hits:: before: $BEFORE, after: $AFTER"
15749                 fi
15750         fi
15751
15752         log "Write data and read it back."
15753         log "Read should be satisfied from the cache."
15754         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15755         BEFORE=$(roc_hit)
15756         cancel_lru_locks osc
15757         cat $file >/dev/null
15758         AFTER=$(roc_hit)
15759         if ! let "AFTER - BEFORE == CPAGES"; then
15760                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15761         else
15762                 log "cache hits:: before: $BEFORE, after: $AFTER"
15763         fi
15764
15765         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15766                 # > 2.12.56 uses pagecache if cached
15767                 log "Read again; it should not be satisfied from the cache."
15768                 BEFORE=$AFTER
15769                 cancel_lru_locks osc
15770                 cat $file >/dev/null
15771                 AFTER=$(roc_hit)
15772                 if ! let "AFTER - BEFORE == 0"; then
15773                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15774                 else
15775                         log "cache hits:: before: $BEFORE, after: $AFTER"
15776                 fi
15777         fi
15778
15779         log "Turn off read and write cache"
15780         set_cache read off
15781         set_cache writethrough off
15782
15783         log "Write data and read it back"
15784         log "It should not be satisfied from the cache."
15785         rm -f $file
15786         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15787         cancel_lru_locks osc
15788         BEFORE=$(roc_hit)
15789         cat $file >/dev/null
15790         AFTER=$(roc_hit)
15791         if ! let "AFTER - BEFORE == 0"; then
15792                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15793         else
15794                 log "cache hits:: before: $BEFORE, after: $AFTER"
15795         fi
15796
15797         log "Turn on the read cache and turn off the write cache"
15798         set_cache read on
15799         set_cache writethrough off
15800
15801         log "Write data and read it back"
15802         log "It should not be satisfied from the cache."
15803         rm -f $file
15804         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15805         BEFORE=$(roc_hit)
15806         cancel_lru_locks osc
15807         cat $file >/dev/null
15808         AFTER=$(roc_hit)
15809         if ! let "AFTER - BEFORE == 0"; then
15810                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15811         else
15812                 log "cache hits:: before: $BEFORE, after: $AFTER"
15813         fi
15814
15815         log "Read again; it should be satisfied from the cache."
15816         BEFORE=$(roc_hit)
15817         cancel_lru_locks osc
15818         cat $file >/dev/null
15819         AFTER=$(roc_hit)
15820         if ! let "AFTER - BEFORE == CPAGES"; then
15821                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15822         else
15823                 log "cache hits:: before: $BEFORE, after: $AFTER"
15824         fi
15825
15826         restore_lustre_params < $p
15827         rm -f $p $file
15828 }
15829 run_test 156 "Verification of tunables"
15830
15831 test_160a() {
15832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15833         remote_mds_nodsh && skip "remote MDS with nodsh"
15834         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15835                 skip "Need MDS version at least 2.2.0"
15836
15837         changelog_register || error "changelog_register failed"
15838         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15839         changelog_users $SINGLEMDS | grep -q $cl_user ||
15840                 error "User $cl_user not found in changelog_users"
15841
15842         mkdir_on_mdt0 $DIR/$tdir
15843
15844         # change something
15845         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15846         changelog_clear 0 || error "changelog_clear failed"
15847         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15848         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15849         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15850         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15851         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15852         rm $DIR/$tdir/pics/desktop.jpg
15853
15854         echo "verifying changelog mask"
15855         changelog_chmask "-MKDIR"
15856         changelog_chmask "-CLOSE"
15857
15858         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15859         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15860
15861         changelog_chmask "+MKDIR"
15862         changelog_chmask "+CLOSE"
15863
15864         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15865         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15866
15867         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15868         CLOSES=$(changelog_dump | grep -c "CLOSE")
15869         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15870         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15871
15872         # verify contents
15873         echo "verifying target fid"
15874         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15875         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15876         [ "$fidc" == "$fidf" ] ||
15877                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15878         echo "verifying parent fid"
15879         # The FID returned from the Changelog may be the directory shard on
15880         # a different MDT, and not the FID returned by path2fid on the parent.
15881         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15882         # since this is what will matter when recreating this file in the tree.
15883         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15884         local pathp=$($LFS fid2path $MOUNT "$fidp")
15885         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15886                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15887
15888         echo "getting records for $cl_user"
15889         changelog_users $SINGLEMDS
15890         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15891         local nclr=3
15892         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15893                 error "changelog_clear failed"
15894         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15895         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15896         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15897                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15898
15899         local min0_rec=$(changelog_users $SINGLEMDS |
15900                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15901         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15902                           awk '{ print $1; exit; }')
15903
15904         changelog_dump | tail -n 5
15905         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15906         [ $first_rec == $((min0_rec + 1)) ] ||
15907                 error "first index should be $min0_rec + 1 not $first_rec"
15908
15909         # LU-3446 changelog index reset on MDT restart
15910         local cur_rec1=$(changelog_users $SINGLEMDS |
15911                          awk '/^current.index:/ { print $NF }')
15912         changelog_clear 0 ||
15913                 error "clear all changelog records for $cl_user failed"
15914         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15915         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15916                 error "Fail to start $SINGLEMDS"
15917         local cur_rec2=$(changelog_users $SINGLEMDS |
15918                          awk '/^current.index:/ { print $NF }')
15919         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15920         [ $cur_rec1 == $cur_rec2 ] ||
15921                 error "current index should be $cur_rec1 not $cur_rec2"
15922
15923         echo "verifying users from this test are deregistered"
15924         changelog_deregister || error "changelog_deregister failed"
15925         changelog_users $SINGLEMDS | grep -q $cl_user &&
15926                 error "User '$cl_user' still in changelog_users"
15927
15928         # lctl get_param -n mdd.*.changelog_users
15929         # current_index: 144
15930         # ID    index (idle seconds)
15931         # cl3   144   (2) mask=<list>
15932         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15933                 # this is the normal case where all users were deregistered
15934                 # make sure no new records are added when no users are present
15935                 local last_rec1=$(changelog_users $SINGLEMDS |
15936                                   awk '/^current.index:/ { print $NF }')
15937                 touch $DIR/$tdir/chloe
15938                 local last_rec2=$(changelog_users $SINGLEMDS |
15939                                   awk '/^current.index:/ { print $NF }')
15940                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15941                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15942         else
15943                 # any changelog users must be leftovers from a previous test
15944                 changelog_users $SINGLEMDS
15945                 echo "other changelog users; can't verify off"
15946         fi
15947 }
15948 run_test 160a "changelog sanity"
15949
15950 test_160b() { # LU-3587
15951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15952         remote_mds_nodsh && skip "remote MDS with nodsh"
15953         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15954                 skip "Need MDS version at least 2.2.0"
15955
15956         changelog_register || error "changelog_register failed"
15957         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15958         changelog_users $SINGLEMDS | grep -q $cl_user ||
15959                 error "User '$cl_user' not found in changelog_users"
15960
15961         local longname1=$(str_repeat a 255)
15962         local longname2=$(str_repeat b 255)
15963
15964         cd $DIR
15965         echo "creating very long named file"
15966         touch $longname1 || error "create of '$longname1' failed"
15967         echo "renaming very long named file"
15968         mv $longname1 $longname2
15969
15970         changelog_dump | grep RENME | tail -n 5
15971         rm -f $longname2
15972 }
15973 run_test 160b "Verify that very long rename doesn't crash in changelog"
15974
15975 test_160c() {
15976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15977         remote_mds_nodsh && skip "remote MDS with nodsh"
15978
15979         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15980                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15981                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15982                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15983
15984         local rc=0
15985
15986         # Registration step
15987         changelog_register || error "changelog_register failed"
15988
15989         rm -rf $DIR/$tdir
15990         mkdir -p $DIR/$tdir
15991         $MCREATE $DIR/$tdir/foo_160c
15992         changelog_chmask "-TRUNC"
15993         $TRUNCATE $DIR/$tdir/foo_160c 200
15994         changelog_chmask "+TRUNC"
15995         $TRUNCATE $DIR/$tdir/foo_160c 199
15996         changelog_dump | tail -n 5
15997         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15998         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15999 }
16000 run_test 160c "verify that changelog log catch the truncate event"
16001
16002 test_160d() {
16003         remote_mds_nodsh && skip "remote MDS with nodsh"
16004         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16006         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16007                 skip "Need MDS version at least 2.7.60"
16008
16009         # Registration step
16010         changelog_register || error "changelog_register failed"
16011
16012         mkdir -p $DIR/$tdir/migrate_dir
16013         changelog_clear 0 || error "changelog_clear failed"
16014
16015         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16016         changelog_dump | tail -n 5
16017         local migrates=$(changelog_dump | grep -c "MIGRT")
16018         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16019 }
16020 run_test 160d "verify that changelog log catch the migrate event"
16021
16022 test_160e() {
16023         remote_mds_nodsh && skip "remote MDS with nodsh"
16024
16025         # Create a user
16026         changelog_register || error "changelog_register failed"
16027
16028         local MDT0=$(facet_svc $SINGLEMDS)
16029         local rc
16030
16031         # No user (expect fail)
16032         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16033         rc=$?
16034         if [ $rc -eq 0 ]; then
16035                 error "Should fail without user"
16036         elif [ $rc -ne 4 ]; then
16037                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16038         fi
16039
16040         # Delete a future user (expect fail)
16041         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16042         rc=$?
16043         if [ $rc -eq 0 ]; then
16044                 error "Deleted non-existant user cl77"
16045         elif [ $rc -ne 2 ]; then
16046                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16047         fi
16048
16049         # Clear to a bad index (1 billion should be safe)
16050         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16051         rc=$?
16052
16053         if [ $rc -eq 0 ]; then
16054                 error "Successfully cleared to invalid CL index"
16055         elif [ $rc -ne 22 ]; then
16056                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16057         fi
16058 }
16059 run_test 160e "changelog negative testing (should return errors)"
16060
16061 test_160f() {
16062         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16063         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16064                 skip "Need MDS version at least 2.10.56"
16065
16066         local mdts=$(comma_list $(mdts_nodes))
16067
16068         # Create a user
16069         changelog_register || error "first changelog_register failed"
16070         changelog_register || error "second changelog_register failed"
16071         local cl_users
16072         declare -A cl_user1
16073         declare -A cl_user2
16074         local user_rec1
16075         local user_rec2
16076         local i
16077
16078         # generate some changelog records to accumulate on each MDT
16079         # use all_char because created files should be evenly distributed
16080         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16081                 error "test_mkdir $tdir failed"
16082         log "$(date +%s): creating first files"
16083         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16084                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16085                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16086         done
16087
16088         # check changelogs have been generated
16089         local start=$SECONDS
16090         local idle_time=$((MDSCOUNT * 5 + 5))
16091         local nbcl=$(changelog_dump | wc -l)
16092         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16093
16094         for param in "changelog_max_idle_time=$idle_time" \
16095                      "changelog_gc=1" \
16096                      "changelog_min_gc_interval=2" \
16097                      "changelog_min_free_cat_entries=3"; do
16098                 local MDT0=$(facet_svc $SINGLEMDS)
16099                 local var="${param%=*}"
16100                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16101
16102                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16103                 do_nodes $mdts $LCTL set_param mdd.*.$param
16104         done
16105
16106         # force cl_user2 to be idle (1st part), but also cancel the
16107         # cl_user1 records so that it is not evicted later in the test.
16108         local sleep1=$((idle_time / 2))
16109         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16110         sleep $sleep1
16111
16112         # simulate changelog catalog almost full
16113         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16114         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16115
16116         for i in $(seq $MDSCOUNT); do
16117                 cl_users=(${CL_USERS[mds$i]})
16118                 cl_user1[mds$i]="${cl_users[0]}"
16119                 cl_user2[mds$i]="${cl_users[1]}"
16120
16121                 [ -n "${cl_user1[mds$i]}" ] ||
16122                         error "mds$i: no user registered"
16123                 [ -n "${cl_user2[mds$i]}" ] ||
16124                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16125
16126                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16127                 [ -n "$user_rec1" ] ||
16128                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16129                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16130                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16131                 [ -n "$user_rec2" ] ||
16132                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16133                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16134                      "$user_rec1 + 2 == $user_rec2"
16135                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16136                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16137                               "$user_rec1 + 2, but is $user_rec2"
16138                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16139                 [ -n "$user_rec2" ] ||
16140                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16141                 [ $user_rec1 == $user_rec2 ] ||
16142                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16143                               "$user_rec1, but is $user_rec2"
16144         done
16145
16146         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16147         local sleep2=$((idle_time - (SECONDS - start) + 1))
16148         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16149         sleep $sleep2
16150
16151         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16152         # cl_user1 should be OK because it recently processed records.
16153         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16154         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16155                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16156                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16157         done
16158
16159         # ensure gc thread is done
16160         for i in $(mdts_nodes); do
16161                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16162                         error "$i: GC-thread not done"
16163         done
16164
16165         local first_rec
16166         for (( i = 1; i <= MDSCOUNT; i++ )); do
16167                 # check cl_user1 still registered
16168                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16169                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16170                 # check cl_user2 unregistered
16171                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16172                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16173
16174                 # check changelogs are present and starting at $user_rec1 + 1
16175                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16176                 [ -n "$user_rec1" ] ||
16177                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16178                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16179                             awk '{ print $1; exit; }')
16180
16181                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16182                 [ $((user_rec1 + 1)) == $first_rec ] ||
16183                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16184         done
16185 }
16186 run_test 160f "changelog garbage collect (timestamped users)"
16187
16188 test_160g() {
16189         remote_mds_nodsh && skip "remote MDS with nodsh"
16190         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16191                 skip "Need MDS version at least 2.14.55"
16192
16193         local mdts=$(comma_list $(mdts_nodes))
16194
16195         # Create a user
16196         changelog_register || error "first changelog_register failed"
16197         changelog_register || error "second changelog_register failed"
16198         local cl_users
16199         declare -A cl_user1
16200         declare -A cl_user2
16201         local user_rec1
16202         local user_rec2
16203         local i
16204
16205         # generate some changelog records to accumulate on each MDT
16206         # use all_char because created files should be evenly distributed
16207         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16208                 error "test_mkdir $tdir failed"
16209         for ((i = 0; i < MDSCOUNT; i++)); do
16210                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16211                         error "create $DIR/$tdir/d$i.1 failed"
16212         done
16213
16214         # check changelogs have been generated
16215         local nbcl=$(changelog_dump | wc -l)
16216         (( $nbcl > 0 )) || error "no changelogs found"
16217
16218         # reduce the max_idle_indexes value to make sure we exceed it
16219         for param in "changelog_max_idle_indexes=2" \
16220                      "changelog_gc=1" \
16221                      "changelog_min_gc_interval=2"; do
16222                 local MDT0=$(facet_svc $SINGLEMDS)
16223                 local var="${param%=*}"
16224                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16225
16226                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16227                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16228                         error "unable to set mdd.*.$param"
16229         done
16230
16231         local start=$SECONDS
16232         for i in $(seq $MDSCOUNT); do
16233                 cl_users=(${CL_USERS[mds$i]})
16234                 cl_user1[mds$i]="${cl_users[0]}"
16235                 cl_user2[mds$i]="${cl_users[1]}"
16236
16237                 [ -n "${cl_user1[mds$i]}" ] ||
16238                         error "mds$i: user1 is not registered"
16239                 [ -n "${cl_user2[mds$i]}" ] ||
16240                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16241
16242                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16243                 [ -n "$user_rec1" ] ||
16244                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16245                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16246                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16247                 [ -n "$user_rec2" ] ||
16248                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16249                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16250                      "$user_rec1 + 2 == $user_rec2"
16251                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16252                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16253                               "expected $user_rec1 + 2, but is $user_rec2"
16254                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16255                 [ -n "$user_rec2" ] ||
16256                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16257                 [ $user_rec1 == $user_rec2 ] ||
16258                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16259                               "expected $user_rec1, but is $user_rec2"
16260         done
16261
16262         # ensure we are past the previous changelog_min_gc_interval set above
16263         local sleep2=$((start + 2 - SECONDS))
16264         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16265         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16266         # cl_user1 should be OK because it recently processed records.
16267         for ((i = 0; i < MDSCOUNT; i++)); do
16268                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16269                         error "create $DIR/$tdir/d$i.3 failed"
16270         done
16271
16272         # ensure gc thread is done
16273         for i in $(mdts_nodes); do
16274                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16275                         error "$i: GC-thread not done"
16276         done
16277
16278         local first_rec
16279         for (( i = 1; i <= MDSCOUNT; i++ )); do
16280                 # check cl_user1 still registered
16281                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16282                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16283                 # check cl_user2 unregistered
16284                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16285                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16286
16287                 # check changelogs are present and starting at $user_rec1 + 1
16288                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16289                 [ -n "$user_rec1" ] ||
16290                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16291                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16292                             awk '{ print $1; exit; }')
16293
16294                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16295                 [ $((user_rec1 + 1)) == $first_rec ] ||
16296                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16297         done
16298 }
16299 run_test 160g "changelog garbage collect on idle records"
16300
16301 test_160h() {
16302         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16303         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16304                 skip "Need MDS version at least 2.10.56"
16305
16306         local mdts=$(comma_list $(mdts_nodes))
16307
16308         # Create a user
16309         changelog_register || error "first changelog_register failed"
16310         changelog_register || error "second changelog_register failed"
16311         local cl_users
16312         declare -A cl_user1
16313         declare -A cl_user2
16314         local user_rec1
16315         local user_rec2
16316         local i
16317
16318         # generate some changelog records to accumulate on each MDT
16319         # use all_char because created files should be evenly distributed
16320         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16321                 error "test_mkdir $tdir failed"
16322         for ((i = 0; i < MDSCOUNT; i++)); do
16323                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16324                         error "create $DIR/$tdir/d$i.1 failed"
16325         done
16326
16327         # check changelogs have been generated
16328         local nbcl=$(changelog_dump | wc -l)
16329         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16330
16331         for param in "changelog_max_idle_time=10" \
16332                      "changelog_gc=1" \
16333                      "changelog_min_gc_interval=2"; do
16334                 local MDT0=$(facet_svc $SINGLEMDS)
16335                 local var="${param%=*}"
16336                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16337
16338                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16339                 do_nodes $mdts $LCTL set_param mdd.*.$param
16340         done
16341
16342         # force cl_user2 to be idle (1st part)
16343         sleep 9
16344
16345         for i in $(seq $MDSCOUNT); do
16346                 cl_users=(${CL_USERS[mds$i]})
16347                 cl_user1[mds$i]="${cl_users[0]}"
16348                 cl_user2[mds$i]="${cl_users[1]}"
16349
16350                 [ -n "${cl_user1[mds$i]}" ] ||
16351                         error "mds$i: no user registered"
16352                 [ -n "${cl_user2[mds$i]}" ] ||
16353                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16354
16355                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16356                 [ -n "$user_rec1" ] ||
16357                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16358                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16359                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16360                 [ -n "$user_rec2" ] ||
16361                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16362                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16363                      "$user_rec1 + 2 == $user_rec2"
16364                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16365                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16366                               "$user_rec1 + 2, but is $user_rec2"
16367                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16368                 [ -n "$user_rec2" ] ||
16369                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16370                 [ $user_rec1 == $user_rec2 ] ||
16371                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16372                               "$user_rec1, but is $user_rec2"
16373         done
16374
16375         # force cl_user2 to be idle (2nd part) and to reach
16376         # changelog_max_idle_time
16377         sleep 2
16378
16379         # force each GC-thread start and block then
16380         # one per MDT/MDD, set fail_val accordingly
16381         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16382         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16383
16384         # generate more changelogs to trigger fail_loc
16385         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16386                 error "create $DIR/$tdir/${tfile}bis failed"
16387
16388         # stop MDT to stop GC-thread, should be done in back-ground as it will
16389         # block waiting for the thread to be released and exit
16390         declare -A stop_pids
16391         for i in $(seq $MDSCOUNT); do
16392                 stop mds$i &
16393                 stop_pids[mds$i]=$!
16394         done
16395
16396         for i in $(mdts_nodes); do
16397                 local facet
16398                 local nb=0
16399                 local facets=$(facets_up_on_host $i)
16400
16401                 for facet in ${facets//,/ }; do
16402                         if [[ $facet == mds* ]]; then
16403                                 nb=$((nb + 1))
16404                         fi
16405                 done
16406                 # ensure each MDS's gc threads are still present and all in "R"
16407                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16408                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16409                         error "$i: expected $nb GC-thread"
16410                 wait_update $i \
16411                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16412                         "R" 20 ||
16413                         error "$i: GC-thread not found in R-state"
16414                 # check umounts of each MDT on MDS have reached kthread_stop()
16415                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16416                         error "$i: expected $nb umount"
16417                 wait_update $i \
16418                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16419                         error "$i: umount not found in D-state"
16420         done
16421
16422         # release all GC-threads
16423         do_nodes $mdts $LCTL set_param fail_loc=0
16424
16425         # wait for MDT stop to complete
16426         for i in $(seq $MDSCOUNT); do
16427                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16428         done
16429
16430         # XXX
16431         # may try to check if any orphan changelog records are present
16432         # via ldiskfs/zfs and llog_reader...
16433
16434         # re-start/mount MDTs
16435         for i in $(seq $MDSCOUNT); do
16436                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16437                         error "Fail to start mds$i"
16438         done
16439
16440         local first_rec
16441         for i in $(seq $MDSCOUNT); do
16442                 # check cl_user1 still registered
16443                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16444                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16445                 # check cl_user2 unregistered
16446                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16447                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16448
16449                 # check changelogs are present and starting at $user_rec1 + 1
16450                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16451                 [ -n "$user_rec1" ] ||
16452                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16453                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16454                             awk '{ print $1; exit; }')
16455
16456                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16457                 [ $((user_rec1 + 1)) == $first_rec ] ||
16458                         error "mds$i: first index should be $user_rec1 + 1, " \
16459                               "but is $first_rec"
16460         done
16461 }
16462 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16463               "during mount"
16464
16465 test_160i() {
16466
16467         local mdts=$(comma_list $(mdts_nodes))
16468
16469         changelog_register || error "first changelog_register failed"
16470
16471         # generate some changelog records to accumulate on each MDT
16472         # use all_char because created files should be evenly distributed
16473         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16474                 error "test_mkdir $tdir failed"
16475         for ((i = 0; i < MDSCOUNT; i++)); do
16476                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16477                         error "create $DIR/$tdir/d$i.1 failed"
16478         done
16479
16480         # check changelogs have been generated
16481         local nbcl=$(changelog_dump | wc -l)
16482         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16483
16484         # simulate race between register and unregister
16485         # XXX as fail_loc is set per-MDS, with DNE configs the race
16486         # simulation will only occur for one MDT per MDS and for the
16487         # others the normal race scenario will take place
16488         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16489         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16490         do_nodes $mdts $LCTL set_param fail_val=1
16491
16492         # unregister 1st user
16493         changelog_deregister &
16494         local pid1=$!
16495         # wait some time for deregister work to reach race rdv
16496         sleep 2
16497         # register 2nd user
16498         changelog_register || error "2nd user register failed"
16499
16500         wait $pid1 || error "1st user deregister failed"
16501
16502         local i
16503         local last_rec
16504         declare -A LAST_REC
16505         for i in $(seq $MDSCOUNT); do
16506                 if changelog_users mds$i | grep "^cl"; then
16507                         # make sure new records are added with one user present
16508                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16509                                           awk '/^current.index:/ { print $NF }')
16510                 else
16511                         error "mds$i has no user registered"
16512                 fi
16513         done
16514
16515         # generate more changelog records to accumulate on each MDT
16516         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16517                 error "create $DIR/$tdir/${tfile}bis failed"
16518
16519         for i in $(seq $MDSCOUNT); do
16520                 last_rec=$(changelog_users $SINGLEMDS |
16521                            awk '/^current.index:/ { print $NF }')
16522                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16523                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16524                         error "changelogs are off on mds$i"
16525         done
16526 }
16527 run_test 160i "changelog user register/unregister race"
16528
16529 test_160j() {
16530         remote_mds_nodsh && skip "remote MDS with nodsh"
16531         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16532                 skip "Need MDS version at least 2.12.56"
16533
16534         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16535         stack_trap "umount $MOUNT2" EXIT
16536
16537         changelog_register || error "first changelog_register failed"
16538         stack_trap "changelog_deregister" EXIT
16539
16540         # generate some changelog
16541         # use all_char because created files should be evenly distributed
16542         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16543                 error "mkdir $tdir failed"
16544         for ((i = 0; i < MDSCOUNT; i++)); do
16545                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16546                         error "create $DIR/$tdir/d$i.1 failed"
16547         done
16548
16549         # open the changelog device
16550         exec 3>/dev/changelog-$FSNAME-MDT0000
16551         stack_trap "exec 3>&-" EXIT
16552         exec 4</dev/changelog-$FSNAME-MDT0000
16553         stack_trap "exec 4<&-" EXIT
16554
16555         # umount the first lustre mount
16556         umount $MOUNT
16557         stack_trap "mount_client $MOUNT" EXIT
16558
16559         # read changelog, which may or may not fail, but should not crash
16560         cat <&4 >/dev/null
16561
16562         # clear changelog
16563         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16564         changelog_users $SINGLEMDS | grep -q $cl_user ||
16565                 error "User $cl_user not found in changelog_users"
16566
16567         printf 'clear:'$cl_user':0' >&3
16568 }
16569 run_test 160j "client can be umounted while its chanangelog is being used"
16570
16571 test_160k() {
16572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16573         remote_mds_nodsh && skip "remote MDS with nodsh"
16574
16575         mkdir -p $DIR/$tdir/1/1
16576
16577         changelog_register || error "changelog_register failed"
16578         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16579
16580         changelog_users $SINGLEMDS | grep -q $cl_user ||
16581                 error "User '$cl_user' not found in changelog_users"
16582 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16583         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16584         rmdir $DIR/$tdir/1/1 & sleep 1
16585         mkdir $DIR/$tdir/2
16586         touch $DIR/$tdir/2/2
16587         rm -rf $DIR/$tdir/2
16588
16589         wait
16590         sleep 4
16591
16592         changelog_dump | grep rmdir || error "rmdir not recorded"
16593 }
16594 run_test 160k "Verify that changelog records are not lost"
16595
16596 # Verifies that a file passed as a parameter has recently had an operation
16597 # performed on it that has generated an MTIME changelog which contains the
16598 # correct parent FID. As files might reside on a different MDT from the
16599 # parent directory in DNE configurations, the FIDs are translated to paths
16600 # before being compared, which should be identical
16601 compare_mtime_changelog() {
16602         local file="${1}"
16603         local mdtidx
16604         local mtime
16605         local cl_fid
16606         local pdir
16607         local dir
16608
16609         mdtidx=$($LFS getstripe --mdt-index $file)
16610         mdtidx=$(printf "%04x" $mdtidx)
16611
16612         # Obtain the parent FID from the MTIME changelog
16613         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16614         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16615
16616         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16617         [ -z "$cl_fid" ] && error "parent FID not present"
16618
16619         # Verify that the path for the parent FID is the same as the path for
16620         # the test directory
16621         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16622
16623         dir=$(dirname $1)
16624
16625         [[ "${pdir%/}" == "$dir" ]] ||
16626                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16627 }
16628
16629 test_160l() {
16630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16631
16632         remote_mds_nodsh && skip "remote MDS with nodsh"
16633         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16634                 skip "Need MDS version at least 2.13.55"
16635
16636         local cl_user
16637
16638         changelog_register || error "changelog_register failed"
16639         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16640
16641         changelog_users $SINGLEMDS | grep -q $cl_user ||
16642                 error "User '$cl_user' not found in changelog_users"
16643
16644         # Clear some types so that MTIME changelogs are generated
16645         changelog_chmask "-CREAT"
16646         changelog_chmask "-CLOSE"
16647
16648         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16649
16650         # Test CL_MTIME during setattr
16651         touch $DIR/$tdir/$tfile
16652         compare_mtime_changelog $DIR/$tdir/$tfile
16653
16654         # Test CL_MTIME during close
16655         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16656         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16657 }
16658 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16659
16660 test_160m() {
16661         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16662         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16663                 skip "Need MDS version at least 2.14.51"
16664         local cl_users
16665         local cl_user1
16666         local cl_user2
16667         local pid1
16668
16669         # Create a user
16670         changelog_register || error "first changelog_register failed"
16671         changelog_register || error "second changelog_register failed"
16672
16673         cl_users=(${CL_USERS[mds1]})
16674         cl_user1="${cl_users[0]}"
16675         cl_user2="${cl_users[1]}"
16676         # generate some changelog records to accumulate on MDT0
16677         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16678         createmany -m $DIR/$tdir/$tfile 50 ||
16679                 error "create $DIR/$tdir/$tfile failed"
16680         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16681         rm -f $DIR/$tdir
16682
16683         # check changelogs have been generated
16684         local nbcl=$(changelog_dump | wc -l)
16685         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16686
16687 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16688         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16689
16690         __changelog_clear mds1 $cl_user1 +10
16691         __changelog_clear mds1 $cl_user2 0 &
16692         pid1=$!
16693         sleep 2
16694         __changelog_clear mds1 $cl_user1 0 ||
16695                 error "fail to cancel record for $cl_user1"
16696         wait $pid1
16697         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16698 }
16699 run_test 160m "Changelog clear race"
16700
16701 test_160n() {
16702         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16703         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16704                 skip "Need MDS version at least 2.14.51"
16705         local cl_users
16706         local cl_user1
16707         local cl_user2
16708         local pid1
16709         local first_rec
16710         local last_rec=0
16711
16712         # Create a user
16713         changelog_register || error "first changelog_register failed"
16714
16715         cl_users=(${CL_USERS[mds1]})
16716         cl_user1="${cl_users[0]}"
16717
16718         # generate some changelog records to accumulate on MDT0
16719         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16720         first_rec=$(changelog_users $SINGLEMDS |
16721                         awk '/^current.index:/ { print $NF }')
16722         while (( last_rec < (( first_rec + 65000)) )); do
16723                 createmany -m $DIR/$tdir/$tfile 10000 ||
16724                         error "create $DIR/$tdir/$tfile failed"
16725
16726                 for i in $(seq 0 10000); do
16727                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16728                                 > /dev/null
16729                 done
16730
16731                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16732                         error "unlinkmany failed unlink"
16733                 last_rec=$(changelog_users $SINGLEMDS |
16734                         awk '/^current.index:/ { print $NF }')
16735                 echo last record $last_rec
16736                 (( last_rec == 0 )) && error "no changelog found"
16737         done
16738
16739 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16740         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16741
16742         __changelog_clear mds1 $cl_user1 0 &
16743         pid1=$!
16744         sleep 2
16745         __changelog_clear mds1 $cl_user1 0 ||
16746                 error "fail to cancel record for $cl_user1"
16747         wait $pid1
16748         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16749 }
16750 run_test 160n "Changelog destroy race"
16751
16752 test_160o() {
16753         local mdt="$(facet_svc $SINGLEMDS)"
16754
16755         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16756         remote_mds_nodsh && skip "remote MDS with nodsh"
16757         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16758                 skip "Need MDS version at least 2.14.52"
16759
16760         changelog_register --user test_160o -m unlnk+close+open ||
16761                 error "changelog_register failed"
16762
16763         do_facet $SINGLEMDS $LCTL --device $mdt \
16764                                 changelog_register -u "Tt3_-#" &&
16765                 error "bad symbols in name should fail"
16766
16767         do_facet $SINGLEMDS $LCTL --device $mdt \
16768                                 changelog_register -u test_160o &&
16769                 error "the same name registration should fail"
16770
16771         do_facet $SINGLEMDS $LCTL --device $mdt \
16772                         changelog_register -u test_160toolongname &&
16773                 error "too long name registration should fail"
16774
16775         changelog_chmask "MARK+HSM"
16776         lctl get_param mdd.*.changelog*mask
16777         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16778         changelog_users $SINGLEMDS | grep -q $cl_user ||
16779                 error "User $cl_user not found in changelog_users"
16780         #verify username
16781         echo $cl_user | grep -q test_160o ||
16782                 error "User $cl_user has no specific name 'test160o'"
16783
16784         # change something
16785         changelog_clear 0 || error "changelog_clear failed"
16786         # generate some changelog records to accumulate on MDT0
16787         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16788         touch $DIR/$tdir/$tfile                 # open 1
16789
16790         OPENS=$(changelog_dump | grep -c "OPEN")
16791         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16792
16793         # must be no MKDIR it wasn't set as user mask
16794         MKDIR=$(changelog_dump | grep -c "MKDIR")
16795         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16796
16797         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16798                                 mdd.$mdt.changelog_current_mask -n)
16799         # register maskless user
16800         changelog_register || error "changelog_register failed"
16801         # effective mask should be not changed because it is not minimal
16802         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16803                                 mdd.$mdt.changelog_current_mask -n)
16804         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16805         # set server mask to minimal value
16806         changelog_chmask "MARK"
16807         # check effective mask again, should be treated as DEFMASK now
16808         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16809                                 mdd.$mdt.changelog_current_mask -n)
16810         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16811
16812         do_facet $SINGLEMDS $LCTL --device $mdt \
16813                                 changelog_deregister -u test_160o ||
16814                 error "cannot deregister by name"
16815 }
16816 run_test 160o "changelog user name and mask"
16817
16818 test_160p() {
16819         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16820         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16821                 skip "Need MDS version at least 2.14.51"
16822         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16823         local cl_users
16824         local cl_user1
16825         local entry_count
16826
16827         # Create a user
16828         changelog_register || error "first changelog_register failed"
16829
16830         cl_users=(${CL_USERS[mds1]})
16831         cl_user1="${cl_users[0]}"
16832
16833         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16834         createmany -m $DIR/$tdir/$tfile 50 ||
16835                 error "create $DIR/$tdir/$tfile failed"
16836         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16837         rm -rf $DIR/$tdir
16838
16839         # check changelogs have been generated
16840         entry_count=$(changelog_dump | wc -l)
16841         ((entry_count != 0)) || error "no changelog entries found"
16842
16843         # remove changelog_users and check that orphan entries are removed
16844         stop mds1
16845         local dev=$(mdsdevname 1)
16846         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16847         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16848         entry_count=$(changelog_dump | wc -l)
16849         ((entry_count == 0)) ||
16850                 error "found $entry_count changelog entries, expected none"
16851 }
16852 run_test 160p "Changelog orphan cleanup with no users"
16853
16854 test_160q() {
16855         local mdt="$(facet_svc $SINGLEMDS)"
16856         local clu
16857
16858         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16859         remote_mds_nodsh && skip "remote MDS with nodsh"
16860         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16861                 skip "Need MDS version at least 2.14.54"
16862
16863         # set server mask to minimal value like server init does
16864         changelog_chmask "MARK"
16865         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16866                 error "changelog_register failed"
16867         # check effective mask again, should be treated as DEFMASK now
16868         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16869                                 mdd.$mdt.changelog_current_mask -n)
16870         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16871                 error "changelog_deregister failed"
16872         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16873 }
16874 run_test 160q "changelog effective mask is DEFMASK if not set"
16875
16876 test_160s() {
16877         remote_mds_nodsh && skip "remote MDS with nodsh"
16878         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16879                 skip "Need MDS version at least 2.14.55"
16880
16881         local mdts=$(comma_list $(mdts_nodes))
16882
16883         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16884         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16885                                        fail_val=$((24 * 3600 * 10))
16886
16887         # Create a user which is 10 days old
16888         changelog_register || error "first changelog_register failed"
16889         local cl_users
16890         declare -A cl_user1
16891         local i
16892
16893         # generate some changelog records to accumulate on each MDT
16894         # use all_char because created files should be evenly distributed
16895         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16896                 error "test_mkdir $tdir failed"
16897         for ((i = 0; i < MDSCOUNT; i++)); do
16898                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16899                         error "create $DIR/$tdir/d$i.1 failed"
16900         done
16901
16902         # check changelogs have been generated
16903         local nbcl=$(changelog_dump | wc -l)
16904         (( nbcl > 0 )) || error "no changelogs found"
16905
16906         # reduce the max_idle_indexes value to make sure we exceed it
16907         for param in "changelog_max_idle_indexes=2097446912" \
16908                      "changelog_max_idle_time=2592000" \
16909                      "changelog_gc=1" \
16910                      "changelog_min_gc_interval=2"; do
16911                 local MDT0=$(facet_svc $SINGLEMDS)
16912                 local var="${param%=*}"
16913                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16914
16915                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16916                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16917                         error "unable to set mdd.*.$param"
16918         done
16919
16920         local start=$SECONDS
16921         for i in $(seq $MDSCOUNT); do
16922                 cl_users=(${CL_USERS[mds$i]})
16923                 cl_user1[mds$i]="${cl_users[0]}"
16924
16925                 [[ -n "${cl_user1[mds$i]}" ]] ||
16926                         error "mds$i: no user registered"
16927         done
16928
16929         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16930         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16931
16932         # ensure we are past the previous changelog_min_gc_interval set above
16933         local sleep2=$((start + 2 - SECONDS))
16934         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16935
16936         # Generate one more changelog to trigger GC
16937         for ((i = 0; i < MDSCOUNT; i++)); do
16938                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16939                         error "create $DIR/$tdir/d$i.3 failed"
16940         done
16941
16942         # ensure gc thread is done
16943         for node in $(mdts_nodes); do
16944                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16945                         error "$node: GC-thread not done"
16946         done
16947
16948         do_nodes $mdts $LCTL set_param fail_loc=0
16949
16950         for (( i = 1; i <= MDSCOUNT; i++ )); do
16951                 # check cl_user1 is purged
16952                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16953                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16954         done
16955         return 0
16956 }
16957 run_test 160s "changelog garbage collect on idle records * time"
16958
16959 test_161a() {
16960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16961
16962         test_mkdir -c1 $DIR/$tdir
16963         cp /etc/hosts $DIR/$tdir/$tfile
16964         test_mkdir -c1 $DIR/$tdir/foo1
16965         test_mkdir -c1 $DIR/$tdir/foo2
16966         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16967         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16968         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16969         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16970         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16971         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16972                 $LFS fid2path $DIR $FID
16973                 error "bad link ea"
16974         fi
16975         # middle
16976         rm $DIR/$tdir/foo2/zachary
16977         # last
16978         rm $DIR/$tdir/foo2/thor
16979         # first
16980         rm $DIR/$tdir/$tfile
16981         # rename
16982         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16983         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16984                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16985         rm $DIR/$tdir/foo2/maggie
16986
16987         # overflow the EA
16988         local longname=$tfile.avg_len_is_thirty_two_
16989         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16990                 error_noexit 'failed to unlink many hardlinks'" EXIT
16991         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16992                 error "failed to hardlink many files"
16993         links=$($LFS fid2path $DIR $FID | wc -l)
16994         echo -n "${links}/1000 links in link EA"
16995         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16996 }
16997 run_test 161a "link ea sanity"
16998
16999 test_161b() {
17000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17001         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17002
17003         local MDTIDX=1
17004         local remote_dir=$DIR/$tdir/remote_dir
17005
17006         mkdir -p $DIR/$tdir
17007         $LFS mkdir -i $MDTIDX $remote_dir ||
17008                 error "create remote directory failed"
17009
17010         cp /etc/hosts $remote_dir/$tfile
17011         mkdir -p $remote_dir/foo1
17012         mkdir -p $remote_dir/foo2
17013         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17014         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17015         ln $remote_dir/$tfile $remote_dir/foo1/luna
17016         ln $remote_dir/$tfile $remote_dir/foo2/thor
17017
17018         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17019                      tr -d ']')
17020         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17021                 $LFS fid2path $DIR $FID
17022                 error "bad link ea"
17023         fi
17024         # middle
17025         rm $remote_dir/foo2/zachary
17026         # last
17027         rm $remote_dir/foo2/thor
17028         # first
17029         rm $remote_dir/$tfile
17030         # rename
17031         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17032         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17033         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17034                 $LFS fid2path $DIR $FID
17035                 error "bad link rename"
17036         fi
17037         rm $remote_dir/foo2/maggie
17038
17039         # overflow the EA
17040         local longname=filename_avg_len_is_thirty_two_
17041         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17042                 error "failed to hardlink many files"
17043         links=$($LFS fid2path $DIR $FID | wc -l)
17044         echo -n "${links}/1000 links in link EA"
17045         [[ ${links} -gt 60 ]] ||
17046                 error "expected at least 60 links in link EA"
17047         unlinkmany $remote_dir/foo2/$longname 1000 ||
17048         error "failed to unlink many hardlinks"
17049 }
17050 run_test 161b "link ea sanity under remote directory"
17051
17052 test_161c() {
17053         remote_mds_nodsh && skip "remote MDS with nodsh"
17054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17055         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17056                 skip "Need MDS version at least 2.1.5"
17057
17058         # define CLF_RENAME_LAST 0x0001
17059         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17060         changelog_register || error "changelog_register failed"
17061
17062         rm -rf $DIR/$tdir
17063         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17064         touch $DIR/$tdir/foo_161c
17065         touch $DIR/$tdir/bar_161c
17066         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17067         changelog_dump | grep RENME | tail -n 5
17068         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17069         changelog_clear 0 || error "changelog_clear failed"
17070         if [ x$flags != "x0x1" ]; then
17071                 error "flag $flags is not 0x1"
17072         fi
17073
17074         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17075         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17076         touch $DIR/$tdir/foo_161c
17077         touch $DIR/$tdir/bar_161c
17078         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17079         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17080         changelog_dump | grep RENME | tail -n 5
17081         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17082         changelog_clear 0 || error "changelog_clear failed"
17083         if [ x$flags != "x0x0" ]; then
17084                 error "flag $flags is not 0x0"
17085         fi
17086         echo "rename overwrite a target having nlink > 1," \
17087                 "changelog record has flags of $flags"
17088
17089         # rename doesn't overwrite a target (changelog flag 0x0)
17090         touch $DIR/$tdir/foo_161c
17091         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17092         changelog_dump | grep RENME | tail -n 5
17093         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17094         changelog_clear 0 || error "changelog_clear failed"
17095         if [ x$flags != "x0x0" ]; then
17096                 error "flag $flags is not 0x0"
17097         fi
17098         echo "rename doesn't overwrite a target," \
17099                 "changelog record has flags of $flags"
17100
17101         # define CLF_UNLINK_LAST 0x0001
17102         # unlink a file having nlink = 1 (changelog flag 0x1)
17103         rm -f $DIR/$tdir/foo2_161c
17104         changelog_dump | grep UNLNK | tail -n 5
17105         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17106         changelog_clear 0 || error "changelog_clear failed"
17107         if [ x$flags != "x0x1" ]; then
17108                 error "flag $flags is not 0x1"
17109         fi
17110         echo "unlink a file having nlink = 1," \
17111                 "changelog record has flags of $flags"
17112
17113         # unlink a file having nlink > 1 (changelog flag 0x0)
17114         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17115         rm -f $DIR/$tdir/foobar_161c
17116         changelog_dump | grep UNLNK | tail -n 5
17117         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17118         changelog_clear 0 || error "changelog_clear failed"
17119         if [ x$flags != "x0x0" ]; then
17120                 error "flag $flags is not 0x0"
17121         fi
17122         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17123 }
17124 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17125
17126 test_161d() {
17127         remote_mds_nodsh && skip "remote MDS with nodsh"
17128         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17129
17130         local pid
17131         local fid
17132
17133         changelog_register || error "changelog_register failed"
17134
17135         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17136         # interfer with $MOUNT/.lustre/fid/ access
17137         mkdir $DIR/$tdir
17138         [[ $? -eq 0 ]] || error "mkdir failed"
17139
17140         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17141         $LCTL set_param fail_loc=0x8000140c
17142         # 5s pause
17143         $LCTL set_param fail_val=5
17144
17145         # create file
17146         echo foofoo > $DIR/$tdir/$tfile &
17147         pid=$!
17148
17149         # wait for create to be delayed
17150         sleep 2
17151
17152         ps -p $pid
17153         [[ $? -eq 0 ]] || error "create should be blocked"
17154
17155         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17156         stack_trap "rm -f $tempfile"
17157         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17158         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17159         # some delay may occur during ChangeLog publishing and file read just
17160         # above, that could allow file write to happen finally
17161         [[ -s $tempfile ]] && echo "file should be empty"
17162
17163         $LCTL set_param fail_loc=0
17164
17165         wait $pid
17166         [[ $? -eq 0 ]] || error "create failed"
17167 }
17168 run_test 161d "create with concurrent .lustre/fid access"
17169
17170 check_path() {
17171         local expected="$1"
17172         shift
17173         local fid="$2"
17174
17175         local path
17176         path=$($LFS fid2path "$@")
17177         local rc=$?
17178
17179         if [ $rc -ne 0 ]; then
17180                 error "path looked up of '$expected' failed: rc=$rc"
17181         elif [ "$path" != "$expected" ]; then
17182                 error "path looked up '$path' instead of '$expected'"
17183         else
17184                 echo "FID '$fid' resolves to path '$path' as expected"
17185         fi
17186 }
17187
17188 test_162a() { # was test_162
17189         test_mkdir -p -c1 $DIR/$tdir/d2
17190         touch $DIR/$tdir/d2/$tfile
17191         touch $DIR/$tdir/d2/x1
17192         touch $DIR/$tdir/d2/x2
17193         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17194         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17195         # regular file
17196         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17197         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17198
17199         # softlink
17200         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17201         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17202         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17203
17204         # softlink to wrong file
17205         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17206         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17207         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17208
17209         # hardlink
17210         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17211         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17212         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17213         # fid2path dir/fsname should both work
17214         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17215         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17216
17217         # hardlink count: check that there are 2 links
17218         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17219         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17220
17221         # hardlink indexing: remove the first link
17222         rm $DIR/$tdir/d2/p/q/r/hlink
17223         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17224 }
17225 run_test 162a "path lookup sanity"
17226
17227 test_162b() {
17228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17229         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17230
17231         mkdir $DIR/$tdir
17232         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17233                                 error "create striped dir failed"
17234
17235         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17236                                         tail -n 1 | awk '{print $2}')
17237         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17238
17239         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17240         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17241
17242         # regular file
17243         for ((i=0;i<5;i++)); do
17244                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17245                         error "get fid for f$i failed"
17246                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17247
17248                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17249                         error "get fid for d$i failed"
17250                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17251         done
17252
17253         return 0
17254 }
17255 run_test 162b "striped directory path lookup sanity"
17256
17257 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17258 test_162c() {
17259         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17260                 skip "Need MDS version at least 2.7.51"
17261
17262         local lpath=$tdir.local
17263         local rpath=$tdir.remote
17264
17265         test_mkdir $DIR/$lpath
17266         test_mkdir $DIR/$rpath
17267
17268         for ((i = 0; i <= 101; i++)); do
17269                 lpath="$lpath/$i"
17270                 mkdir $DIR/$lpath
17271                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17272                         error "get fid for local directory $DIR/$lpath failed"
17273                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17274
17275                 rpath="$rpath/$i"
17276                 test_mkdir $DIR/$rpath
17277                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17278                         error "get fid for remote directory $DIR/$rpath failed"
17279                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17280         done
17281
17282         return 0
17283 }
17284 run_test 162c "fid2path works with paths 100 or more directories deep"
17285
17286 oalr_event_count() {
17287         local event="${1}"
17288         local trace="${2}"
17289
17290         awk -v name="${FSNAME}-OST0000" \
17291             -v event="${event}" \
17292             '$1 == "TRACE" && $2 == event && $3 == name' \
17293             "${trace}" |
17294         wc -l
17295 }
17296
17297 oalr_expect_event_count() {
17298         local event="${1}"
17299         local trace="${2}"
17300         local expect="${3}"
17301         local count
17302
17303         count=$(oalr_event_count "${event}" "${trace}")
17304         if ((count == expect)); then
17305                 return 0
17306         fi
17307
17308         error_noexit "${event} event count was '${count}', expected ${expect}"
17309         cat "${trace}" >&2
17310         exit 1
17311 }
17312
17313 cleanup_165() {
17314         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17315         stop ost1
17316         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17317 }
17318
17319 setup_165() {
17320         sync # Flush previous IOs so we can count log entries.
17321         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17322         stack_trap cleanup_165 EXIT
17323 }
17324
17325 test_165a() {
17326         local trace="/tmp/${tfile}.trace"
17327         local rc
17328         local count
17329
17330         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17331                 skip "OFD access log unsupported"
17332
17333         setup_165
17334         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17335         sleep 5
17336
17337         do_facet ost1 ofd_access_log_reader --list
17338         stop ost1
17339
17340         do_facet ost1 killall -TERM ofd_access_log_reader
17341         wait
17342         rc=$?
17343
17344         if ((rc != 0)); then
17345                 error "ofd_access_log_reader exited with rc = '${rc}'"
17346         fi
17347
17348         # Parse trace file for discovery events:
17349         oalr_expect_event_count alr_log_add "${trace}" 1
17350         oalr_expect_event_count alr_log_eof "${trace}" 1
17351         oalr_expect_event_count alr_log_free "${trace}" 1
17352 }
17353 run_test 165a "ofd access log discovery"
17354
17355 test_165b() {
17356         local trace="/tmp/${tfile}.trace"
17357         local file="${DIR}/${tfile}"
17358         local pfid1
17359         local pfid2
17360         local -a entry
17361         local rc
17362         local count
17363         local size
17364         local flags
17365
17366         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17367                 skip "OFD access log unsupported"
17368
17369         setup_165
17370         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17371         sleep 5
17372
17373         do_facet ost1 ofd_access_log_reader --list
17374
17375         lfs setstripe -c 1 -i 0 "${file}"
17376         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17377                 error "cannot create '${file}'"
17378
17379         sleep 5
17380         do_facet ost1 killall -TERM ofd_access_log_reader
17381         wait
17382         rc=$?
17383
17384         if ((rc != 0)); then
17385                 error "ofd_access_log_reader exited with rc = '${rc}'"
17386         fi
17387
17388         oalr_expect_event_count alr_log_entry "${trace}" 1
17389
17390         pfid1=$($LFS path2fid "${file}")
17391
17392         # 1     2             3   4    5     6   7    8    9     10
17393         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17394         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17395
17396         echo "entry = '${entry[*]}'" >&2
17397
17398         pfid2=${entry[4]}
17399         if [[ "${pfid1}" != "${pfid2}" ]]; then
17400                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17401         fi
17402
17403         size=${entry[8]}
17404         if ((size != 1048576)); then
17405                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17406         fi
17407
17408         flags=${entry[10]}
17409         if [[ "${flags}" != "w" ]]; then
17410                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17411         fi
17412
17413         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17414         sleep 5
17415
17416         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17417                 error "cannot read '${file}'"
17418         sleep 5
17419
17420         do_facet ost1 killall -TERM ofd_access_log_reader
17421         wait
17422         rc=$?
17423
17424         if ((rc != 0)); then
17425                 error "ofd_access_log_reader exited with rc = '${rc}'"
17426         fi
17427
17428         oalr_expect_event_count alr_log_entry "${trace}" 1
17429
17430         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17431         echo "entry = '${entry[*]}'" >&2
17432
17433         pfid2=${entry[4]}
17434         if [[ "${pfid1}" != "${pfid2}" ]]; then
17435                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17436         fi
17437
17438         size=${entry[8]}
17439         if ((size != 524288)); then
17440                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17441         fi
17442
17443         flags=${entry[10]}
17444         if [[ "${flags}" != "r" ]]; then
17445                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17446         fi
17447 }
17448 run_test 165b "ofd access log entries are produced and consumed"
17449
17450 test_165c() {
17451         local trace="/tmp/${tfile}.trace"
17452         local file="${DIR}/${tdir}/${tfile}"
17453
17454         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17455                 skip "OFD access log unsupported"
17456
17457         test_mkdir "${DIR}/${tdir}"
17458
17459         setup_165
17460         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17461         sleep 5
17462
17463         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17464
17465         # 4096 / 64 = 64. Create twice as many entries.
17466         for ((i = 0; i < 128; i++)); do
17467                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17468                         error "cannot create file"
17469         done
17470
17471         sync
17472
17473         do_facet ost1 killall -TERM ofd_access_log_reader
17474         wait
17475         rc=$?
17476         if ((rc != 0)); then
17477                 error "ofd_access_log_reader exited with rc = '${rc}'"
17478         fi
17479
17480         unlinkmany  "${file}-%d" 128
17481 }
17482 run_test 165c "full ofd access logs do not block IOs"
17483
17484 oal_get_read_count() {
17485         local stats="$1"
17486
17487         # STATS lustre-OST0001 alr_read_count 1
17488
17489         do_facet ost1 cat "${stats}" |
17490         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17491              END { print count; }'
17492 }
17493
17494 oal_expect_read_count() {
17495         local stats="$1"
17496         local count
17497         local expect="$2"
17498
17499         # Ask ofd_access_log_reader to write stats.
17500         do_facet ost1 killall -USR1 ofd_access_log_reader
17501
17502         # Allow some time for things to happen.
17503         sleep 1
17504
17505         count=$(oal_get_read_count "${stats}")
17506         if ((count == expect)); then
17507                 return 0
17508         fi
17509
17510         error_noexit "bad read count, got ${count}, expected ${expect}"
17511         do_facet ost1 cat "${stats}" >&2
17512         exit 1
17513 }
17514
17515 test_165d() {
17516         local stats="/tmp/${tfile}.stats"
17517         local file="${DIR}/${tdir}/${tfile}"
17518         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17519
17520         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17521                 skip "OFD access log unsupported"
17522
17523         test_mkdir "${DIR}/${tdir}"
17524
17525         setup_165
17526         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17527         sleep 5
17528
17529         lfs setstripe -c 1 -i 0 "${file}"
17530
17531         do_facet ost1 lctl set_param "${param}=rw"
17532         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17533                 error "cannot create '${file}'"
17534         oal_expect_read_count "${stats}" 1
17535
17536         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17537                 error "cannot read '${file}'"
17538         oal_expect_read_count "${stats}" 2
17539
17540         do_facet ost1 lctl set_param "${param}=r"
17541         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17542                 error "cannot create '${file}'"
17543         oal_expect_read_count "${stats}" 2
17544
17545         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17546                 error "cannot read '${file}'"
17547         oal_expect_read_count "${stats}" 3
17548
17549         do_facet ost1 lctl set_param "${param}=w"
17550         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17551                 error "cannot create '${file}'"
17552         oal_expect_read_count "${stats}" 4
17553
17554         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17555                 error "cannot read '${file}'"
17556         oal_expect_read_count "${stats}" 4
17557
17558         do_facet ost1 lctl set_param "${param}=0"
17559         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17560                 error "cannot create '${file}'"
17561         oal_expect_read_count "${stats}" 4
17562
17563         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17564                 error "cannot read '${file}'"
17565         oal_expect_read_count "${stats}" 4
17566
17567         do_facet ost1 killall -TERM ofd_access_log_reader
17568         wait
17569         rc=$?
17570         if ((rc != 0)); then
17571                 error "ofd_access_log_reader exited with rc = '${rc}'"
17572         fi
17573 }
17574 run_test 165d "ofd_access_log mask works"
17575
17576 test_165e() {
17577         local stats="/tmp/${tfile}.stats"
17578         local file0="${DIR}/${tdir}-0/${tfile}"
17579         local file1="${DIR}/${tdir}-1/${tfile}"
17580
17581         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17582                 skip "OFD access log unsupported"
17583
17584         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17585
17586         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17587         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17588
17589         lfs setstripe -c 1 -i 0 "${file0}"
17590         lfs setstripe -c 1 -i 0 "${file1}"
17591
17592         setup_165
17593         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17594         sleep 5
17595
17596         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17597                 error "cannot create '${file0}'"
17598         sync
17599         oal_expect_read_count "${stats}" 0
17600
17601         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17602                 error "cannot create '${file1}'"
17603         sync
17604         oal_expect_read_count "${stats}" 1
17605
17606         do_facet ost1 killall -TERM ofd_access_log_reader
17607         wait
17608         rc=$?
17609         if ((rc != 0)); then
17610                 error "ofd_access_log_reader exited with rc = '${rc}'"
17611         fi
17612 }
17613 run_test 165e "ofd_access_log MDT index filter works"
17614
17615 test_165f() {
17616         local trace="/tmp/${tfile}.trace"
17617         local rc
17618         local count
17619
17620         setup_165
17621         do_facet ost1 timeout 60 ofd_access_log_reader \
17622                 --exit-on-close --debug=- --trace=- > "${trace}" &
17623         sleep 5
17624         stop ost1
17625
17626         wait
17627         rc=$?
17628
17629         if ((rc != 0)); then
17630                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17631                 cat "${trace}"
17632                 exit 1
17633         fi
17634 }
17635 run_test 165f "ofd_access_log_reader --exit-on-close works"
17636
17637 test_169() {
17638         # do directio so as not to populate the page cache
17639         log "creating a 10 Mb file"
17640         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17641                 error "multiop failed while creating a file"
17642         log "starting reads"
17643         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17644         log "truncating the file"
17645         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17646                 error "multiop failed while truncating the file"
17647         log "killing dd"
17648         kill %+ || true # reads might have finished
17649         echo "wait until dd is finished"
17650         wait
17651         log "removing the temporary file"
17652         rm -rf $DIR/$tfile || error "tmp file removal failed"
17653 }
17654 run_test 169 "parallel read and truncate should not deadlock"
17655
17656 test_170() {
17657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17658
17659         $LCTL clear     # bug 18514
17660         $LCTL debug_daemon start $TMP/${tfile}_log_good
17661         touch $DIR/$tfile
17662         $LCTL debug_daemon stop
17663         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17664                 error "sed failed to read log_good"
17665
17666         $LCTL debug_daemon start $TMP/${tfile}_log_good
17667         rm -rf $DIR/$tfile
17668         $LCTL debug_daemon stop
17669
17670         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17671                error "lctl df log_bad failed"
17672
17673         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17674         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17675
17676         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17677         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17678
17679         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17680                 error "bad_line good_line1 good_line2 are empty"
17681
17682         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17683         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17684         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17685
17686         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17687         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17688         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17689
17690         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17691                 error "bad_line_new good_line_new are empty"
17692
17693         local expected_good=$((good_line1 + good_line2*2))
17694
17695         rm -f $TMP/${tfile}*
17696         # LU-231, short malformed line may not be counted into bad lines
17697         if [ $bad_line -ne $bad_line_new ] &&
17698                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17699                 error "expected $bad_line bad lines, but got $bad_line_new"
17700                 return 1
17701         fi
17702
17703         if [ $expected_good -ne $good_line_new ]; then
17704                 error "expected $expected_good good lines, but got $good_line_new"
17705                 return 2
17706         fi
17707         true
17708 }
17709 run_test 170 "test lctl df to handle corrupted log ====================="
17710
17711 test_171() { # bug20592
17712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17713
17714         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17715         $LCTL set_param fail_loc=0x50e
17716         $LCTL set_param fail_val=3000
17717         multiop_bg_pause $DIR/$tfile O_s || true
17718         local MULTIPID=$!
17719         kill -USR1 $MULTIPID
17720         # cause log dump
17721         sleep 3
17722         wait $MULTIPID
17723         if dmesg | grep "recursive fault"; then
17724                 error "caught a recursive fault"
17725         fi
17726         $LCTL set_param fail_loc=0
17727         true
17728 }
17729 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17730
17731 # it would be good to share it with obdfilter-survey/iokit-libecho code
17732 setup_obdecho_osc () {
17733         local rc=0
17734         local ost_nid=$1
17735         local obdfilter_name=$2
17736         echo "Creating new osc for $obdfilter_name on $ost_nid"
17737         # make sure we can find loopback nid
17738         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17739
17740         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17741                            ${obdfilter_name}_osc_UUID || rc=2; }
17742         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17743                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17744         return $rc
17745 }
17746
17747 cleanup_obdecho_osc () {
17748         local obdfilter_name=$1
17749         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17750         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17751         return 0
17752 }
17753
17754 obdecho_test() {
17755         local OBD=$1
17756         local node=$2
17757         local pages=${3:-64}
17758         local rc=0
17759         local id
17760
17761         local count=10
17762         local obd_size=$(get_obd_size $node $OBD)
17763         local page_size=$(get_page_size $node)
17764         if [[ -n "$obd_size" ]]; then
17765                 local new_count=$((obd_size / (pages * page_size / 1024)))
17766                 [[ $new_count -ge $count ]] || count=$new_count
17767         fi
17768
17769         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17770         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17771                            rc=2; }
17772         if [ $rc -eq 0 ]; then
17773             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17774             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17775         fi
17776         echo "New object id is $id"
17777         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17778                            rc=4; }
17779         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17780                            "test_brw $count w v $pages $id" || rc=4; }
17781         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17782                            rc=4; }
17783         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17784                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17785         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17786                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17787         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17788         return $rc
17789 }
17790
17791 test_180a() {
17792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17793
17794         if ! [ -d /sys/fs/lustre/echo_client ] &&
17795            ! module_loaded obdecho; then
17796                 load_module obdecho/obdecho &&
17797                         stack_trap "rmmod obdecho" EXIT ||
17798                         error "unable to load obdecho on client"
17799         fi
17800
17801         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17802         local host=$($LCTL get_param -n osc.$osc.import |
17803                      awk '/current_connection:/ { print $2 }' )
17804         local target=$($LCTL get_param -n osc.$osc.import |
17805                        awk '/target:/ { print $2 }' )
17806         target=${target%_UUID}
17807
17808         if [ -n "$target" ]; then
17809                 setup_obdecho_osc $host $target &&
17810                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17811                         { error "obdecho setup failed with $?"; return; }
17812
17813                 obdecho_test ${target}_osc client ||
17814                         error "obdecho_test failed on ${target}_osc"
17815         else
17816                 $LCTL get_param osc.$osc.import
17817                 error "there is no osc.$osc.import target"
17818         fi
17819 }
17820 run_test 180a "test obdecho on osc"
17821
17822 test_180b() {
17823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17824         remote_ost_nodsh && skip "remote OST with nodsh"
17825
17826         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17827                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17828                 error "failed to load module obdecho"
17829
17830         local target=$(do_facet ost1 $LCTL dl |
17831                        awk '/obdfilter/ { print $4; exit; }')
17832
17833         if [ -n "$target" ]; then
17834                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17835         else
17836                 do_facet ost1 $LCTL dl
17837                 error "there is no obdfilter target on ost1"
17838         fi
17839 }
17840 run_test 180b "test obdecho directly on obdfilter"
17841
17842 test_180c() { # LU-2598
17843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17844         remote_ost_nodsh && skip "remote OST with nodsh"
17845         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17846                 skip "Need MDS version at least 2.4.0"
17847
17848         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17849                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17850                 error "failed to load module obdecho"
17851
17852         local target=$(do_facet ost1 $LCTL dl |
17853                        awk '/obdfilter/ { print $4; exit; }')
17854
17855         if [ -n "$target" ]; then
17856                 local pages=16384 # 64MB bulk I/O RPC size
17857
17858                 obdecho_test "$target" ost1 "$pages" ||
17859                         error "obdecho_test with pages=$pages failed with $?"
17860         else
17861                 do_facet ost1 $LCTL dl
17862                 error "there is no obdfilter target on ost1"
17863         fi
17864 }
17865 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17866
17867 test_181() { # bug 22177
17868         test_mkdir $DIR/$tdir
17869         # create enough files to index the directory
17870         createmany -o $DIR/$tdir/foobar 4000
17871         # print attributes for debug purpose
17872         lsattr -d .
17873         # open dir
17874         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17875         MULTIPID=$!
17876         # remove the files & current working dir
17877         unlinkmany $DIR/$tdir/foobar 4000
17878         rmdir $DIR/$tdir
17879         kill -USR1 $MULTIPID
17880         wait $MULTIPID
17881         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17882         return 0
17883 }
17884 run_test 181 "Test open-unlinked dir ========================"
17885
17886 test_182() {
17887         local fcount=1000
17888         local tcount=10
17889
17890         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17891
17892         $LCTL set_param mdc.*.rpc_stats=clear
17893
17894         for (( i = 0; i < $tcount; i++ )) ; do
17895                 mkdir $DIR/$tdir/$i
17896         done
17897
17898         for (( i = 0; i < $tcount; i++ )) ; do
17899                 createmany -o $DIR/$tdir/$i/f- $fcount &
17900         done
17901         wait
17902
17903         for (( i = 0; i < $tcount; i++ )) ; do
17904                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17905         done
17906         wait
17907
17908         $LCTL get_param mdc.*.rpc_stats
17909
17910         rm -rf $DIR/$tdir
17911 }
17912 run_test 182 "Test parallel modify metadata operations ================"
17913
17914 test_183() { # LU-2275
17915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17916         remote_mds_nodsh && skip "remote MDS with nodsh"
17917         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17918                 skip "Need MDS version at least 2.3.56"
17919
17920         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17921         echo aaa > $DIR/$tdir/$tfile
17922
17923 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17924         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17925
17926         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17927         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17928
17929         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17930
17931         # Flush negative dentry cache
17932         touch $DIR/$tdir/$tfile
17933
17934         # We are not checking for any leaked references here, they'll
17935         # become evident next time we do cleanup with module unload.
17936         rm -rf $DIR/$tdir
17937 }
17938 run_test 183 "No crash or request leak in case of strange dispositions ========"
17939
17940 # test suite 184 is for LU-2016, LU-2017
17941 test_184a() {
17942         check_swap_layouts_support
17943
17944         dir0=$DIR/$tdir/$testnum
17945         test_mkdir -p -c1 $dir0
17946         ref1=/etc/passwd
17947         ref2=/etc/group
17948         file1=$dir0/f1
17949         file2=$dir0/f2
17950         $LFS setstripe -c1 $file1
17951         cp $ref1 $file1
17952         $LFS setstripe -c2 $file2
17953         cp $ref2 $file2
17954         gen1=$($LFS getstripe -g $file1)
17955         gen2=$($LFS getstripe -g $file2)
17956
17957         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17958         gen=$($LFS getstripe -g $file1)
17959         [[ $gen1 != $gen ]] ||
17960                 error "Layout generation on $file1 does not change"
17961         gen=$($LFS getstripe -g $file2)
17962         [[ $gen2 != $gen ]] ||
17963                 error "Layout generation on $file2 does not change"
17964
17965         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17966         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17967
17968         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17969 }
17970 run_test 184a "Basic layout swap"
17971
17972 test_184b() {
17973         check_swap_layouts_support
17974
17975         dir0=$DIR/$tdir/$testnum
17976         mkdir -p $dir0 || error "creating dir $dir0"
17977         file1=$dir0/f1
17978         file2=$dir0/f2
17979         file3=$dir0/f3
17980         dir1=$dir0/d1
17981         dir2=$dir0/d2
17982         mkdir $dir1 $dir2
17983         $LFS setstripe -c1 $file1
17984         $LFS setstripe -c2 $file2
17985         $LFS setstripe -c1 $file3
17986         chown $RUNAS_ID $file3
17987         gen1=$($LFS getstripe -g $file1)
17988         gen2=$($LFS getstripe -g $file2)
17989
17990         $LFS swap_layouts $dir1 $dir2 &&
17991                 error "swap of directories layouts should fail"
17992         $LFS swap_layouts $dir1 $file1 &&
17993                 error "swap of directory and file layouts should fail"
17994         $RUNAS $LFS swap_layouts $file1 $file2 &&
17995                 error "swap of file we cannot write should fail"
17996         $LFS swap_layouts $file1 $file3 &&
17997                 error "swap of file with different owner should fail"
17998         /bin/true # to clear error code
17999 }
18000 run_test 184b "Forbidden layout swap (will generate errors)"
18001
18002 test_184c() {
18003         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18004         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18005         check_swap_layouts_support
18006         check_swap_layout_no_dom $DIR
18007
18008         local dir0=$DIR/$tdir/$testnum
18009         mkdir -p $dir0 || error "creating dir $dir0"
18010
18011         local ref1=$dir0/ref1
18012         local ref2=$dir0/ref2
18013         local file1=$dir0/file1
18014         local file2=$dir0/file2
18015         # create a file large enough for the concurrent test
18016         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18017         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18018         echo "ref file size: ref1($(stat -c %s $ref1))," \
18019              "ref2($(stat -c %s $ref2))"
18020
18021         cp $ref2 $file2
18022         dd if=$ref1 of=$file1 bs=16k &
18023         local DD_PID=$!
18024
18025         # Make sure dd starts to copy file, but wait at most 5 seconds
18026         local loops=0
18027         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18028
18029         $LFS swap_layouts $file1 $file2
18030         local rc=$?
18031         wait $DD_PID
18032         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18033         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18034
18035         # how many bytes copied before swapping layout
18036         local copied=$(stat -c %s $file2)
18037         local remaining=$(stat -c %s $ref1)
18038         remaining=$((remaining - copied))
18039         echo "Copied $copied bytes before swapping layout..."
18040
18041         cmp -n $copied $file1 $ref2 | grep differ &&
18042                 error "Content mismatch [0, $copied) of ref2 and file1"
18043         cmp -n $copied $file2 $ref1 ||
18044                 error "Content mismatch [0, $copied) of ref1 and file2"
18045         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18046                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18047
18048         # clean up
18049         rm -f $ref1 $ref2 $file1 $file2
18050 }
18051 run_test 184c "Concurrent write and layout swap"
18052
18053 test_184d() {
18054         check_swap_layouts_support
18055         check_swap_layout_no_dom $DIR
18056         [ -z "$(which getfattr 2>/dev/null)" ] &&
18057                 skip_env "no getfattr command"
18058
18059         local file1=$DIR/$tdir/$tfile-1
18060         local file2=$DIR/$tdir/$tfile-2
18061         local file3=$DIR/$tdir/$tfile-3
18062         local lovea1
18063         local lovea2
18064
18065         mkdir -p $DIR/$tdir
18066         touch $file1 || error "create $file1 failed"
18067         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18068                 error "create $file2 failed"
18069         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18070                 error "create $file3 failed"
18071         lovea1=$(get_layout_param $file1)
18072
18073         $LFS swap_layouts $file2 $file3 ||
18074                 error "swap $file2 $file3 layouts failed"
18075         $LFS swap_layouts $file1 $file2 ||
18076                 error "swap $file1 $file2 layouts failed"
18077
18078         lovea2=$(get_layout_param $file2)
18079         echo "$lovea1"
18080         echo "$lovea2"
18081         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18082
18083         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18084         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18085 }
18086 run_test 184d "allow stripeless layouts swap"
18087
18088 test_184e() {
18089         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18090                 skip "Need MDS version at least 2.6.94"
18091         check_swap_layouts_support
18092         check_swap_layout_no_dom $DIR
18093         [ -z "$(which getfattr 2>/dev/null)" ] &&
18094                 skip_env "no getfattr command"
18095
18096         local file1=$DIR/$tdir/$tfile-1
18097         local file2=$DIR/$tdir/$tfile-2
18098         local file3=$DIR/$tdir/$tfile-3
18099         local lovea
18100
18101         mkdir -p $DIR/$tdir
18102         touch $file1 || error "create $file1 failed"
18103         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18104                 error "create $file2 failed"
18105         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18106                 error "create $file3 failed"
18107
18108         $LFS swap_layouts $file1 $file2 ||
18109                 error "swap $file1 $file2 layouts failed"
18110
18111         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18112         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18113
18114         echo 123 > $file1 || error "Should be able to write into $file1"
18115
18116         $LFS swap_layouts $file1 $file3 ||
18117                 error "swap $file1 $file3 layouts failed"
18118
18119         echo 123 > $file1 || error "Should be able to write into $file1"
18120
18121         rm -rf $file1 $file2 $file3
18122 }
18123 run_test 184e "Recreate layout after stripeless layout swaps"
18124
18125 test_184f() {
18126         # Create a file with name longer than sizeof(struct stat) ==
18127         # 144 to see if we can get chars from the file name to appear
18128         # in the returned striping. Note that 'f' == 0x66.
18129         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18130
18131         mkdir -p $DIR/$tdir
18132         mcreate $DIR/$tdir/$file
18133         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18134                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18135         fi
18136 }
18137 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18138
18139 test_185() { # LU-2441
18140         # LU-3553 - no volatile file support in old servers
18141         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18142                 skip "Need MDS version at least 2.3.60"
18143
18144         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18145         touch $DIR/$tdir/spoo
18146         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18147         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18148                 error "cannot create/write a volatile file"
18149         [ "$FILESET" == "" ] &&
18150         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18151                 error "FID is still valid after close"
18152
18153         multiop_bg_pause $DIR/$tdir vVw4096_c
18154         local multi_pid=$!
18155
18156         local OLD_IFS=$IFS
18157         IFS=":"
18158         local fidv=($fid)
18159         IFS=$OLD_IFS
18160         # assume that the next FID for this client is sequential, since stdout
18161         # is unfortunately eaten by multiop_bg_pause
18162         local n=$((${fidv[1]} + 1))
18163         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18164         if [ "$FILESET" == "" ]; then
18165                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18166                         error "FID is missing before close"
18167         fi
18168         kill -USR1 $multi_pid
18169         # 1 second delay, so if mtime change we will see it
18170         sleep 1
18171         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18172         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18173 }
18174 run_test 185 "Volatile file support"
18175
18176 function create_check_volatile() {
18177         local idx=$1
18178         local tgt
18179
18180         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18181         local PID=$!
18182         sleep 1
18183         local FID=$(cat /tmp/${tfile}.fid)
18184         [ "$FID" == "" ] && error "can't get FID for volatile"
18185         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18186         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18187         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18188         kill -USR1 $PID
18189         wait
18190         sleep 1
18191         cancel_lru_locks mdc # flush opencache
18192         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18193         return 0
18194 }
18195
18196 test_185a(){
18197         # LU-12516 - volatile creation via .lustre
18198         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18199                 skip "Need MDS version at least 2.3.55"
18200
18201         create_check_volatile 0
18202         [ $MDSCOUNT -lt 2 ] && return 0
18203
18204         # DNE case
18205         create_check_volatile 1
18206
18207         return 0
18208 }
18209 run_test 185a "Volatile file creation in .lustre/fid/"
18210
18211 test_187a() {
18212         remote_mds_nodsh && skip "remote MDS with nodsh"
18213         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18214                 skip "Need MDS version at least 2.3.0"
18215
18216         local dir0=$DIR/$tdir/$testnum
18217         mkdir -p $dir0 || error "creating dir $dir0"
18218
18219         local file=$dir0/file1
18220         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18221         local dv1=$($LFS data_version $file)
18222         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18223         local dv2=$($LFS data_version $file)
18224         [[ $dv1 != $dv2 ]] ||
18225                 error "data version did not change on write $dv1 == $dv2"
18226
18227         # clean up
18228         rm -f $file1
18229 }
18230 run_test 187a "Test data version change"
18231
18232 test_187b() {
18233         remote_mds_nodsh && skip "remote MDS with nodsh"
18234         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18235                 skip "Need MDS version at least 2.3.0"
18236
18237         local dir0=$DIR/$tdir/$testnum
18238         mkdir -p $dir0 || error "creating dir $dir0"
18239
18240         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18241         [[ ${DV[0]} != ${DV[1]} ]] ||
18242                 error "data version did not change on write"\
18243                       " ${DV[0]} == ${DV[1]}"
18244
18245         # clean up
18246         rm -f $file1
18247 }
18248 run_test 187b "Test data version change on volatile file"
18249
18250 test_200() {
18251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18252         remote_mgs_nodsh && skip "remote MGS with nodsh"
18253         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18254
18255         local POOL=${POOL:-cea1}
18256         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18257         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18258         # Pool OST targets
18259         local first_ost=0
18260         local last_ost=$(($OSTCOUNT - 1))
18261         local ost_step=2
18262         local ost_list=$(seq $first_ost $ost_step $last_ost)
18263         local ost_range="$first_ost $last_ost $ost_step"
18264         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18265         local file_dir=$POOL_ROOT/file_tst
18266         local subdir=$test_path/subdir
18267         local rc=0
18268
18269         while : ; do
18270                 # former test_200a test_200b
18271                 pool_add $POOL                          || { rc=$? ; break; }
18272                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18273                 # former test_200c test_200d
18274                 mkdir -p $test_path
18275                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18276                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18277                 mkdir -p $subdir
18278                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18279                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18280                                                         || { rc=$? ; break; }
18281                 # former test_200e test_200f
18282                 local files=$((OSTCOUNT*3))
18283                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18284                                                         || { rc=$? ; break; }
18285                 pool_create_files $POOL $file_dir $files "$ost_list" \
18286                                                         || { rc=$? ; break; }
18287                 # former test_200g test_200h
18288                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18289                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18290
18291                 # former test_201a test_201b test_201c
18292                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18293
18294                 local f=$test_path/$tfile
18295                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18296                 pool_remove $POOL $f                    || { rc=$? ; break; }
18297                 break
18298         done
18299
18300         destroy_test_pools
18301
18302         return $rc
18303 }
18304 run_test 200 "OST pools"
18305
18306 # usage: default_attr <count | size | offset>
18307 default_attr() {
18308         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18309 }
18310
18311 # usage: check_default_stripe_attr
18312 check_default_stripe_attr() {
18313         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18314         case $1 in
18315         --stripe-count|-c)
18316                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18317         --stripe-size|-S)
18318                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18319         --stripe-index|-i)
18320                 EXPECTED=-1;;
18321         *)
18322                 error "unknown getstripe attr '$1'"
18323         esac
18324
18325         [ $ACTUAL == $EXPECTED ] ||
18326                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18327 }
18328
18329 test_204a() {
18330         test_mkdir $DIR/$tdir
18331         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18332
18333         check_default_stripe_attr --stripe-count
18334         check_default_stripe_attr --stripe-size
18335         check_default_stripe_attr --stripe-index
18336 }
18337 run_test 204a "Print default stripe attributes"
18338
18339 test_204b() {
18340         test_mkdir $DIR/$tdir
18341         $LFS setstripe --stripe-count 1 $DIR/$tdir
18342
18343         check_default_stripe_attr --stripe-size
18344         check_default_stripe_attr --stripe-index
18345 }
18346 run_test 204b "Print default stripe size and offset"
18347
18348 test_204c() {
18349         test_mkdir $DIR/$tdir
18350         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18351
18352         check_default_stripe_attr --stripe-count
18353         check_default_stripe_attr --stripe-index
18354 }
18355 run_test 204c "Print default stripe count and offset"
18356
18357 test_204d() {
18358         test_mkdir $DIR/$tdir
18359         $LFS setstripe --stripe-index 0 $DIR/$tdir
18360
18361         check_default_stripe_attr --stripe-count
18362         check_default_stripe_attr --stripe-size
18363 }
18364 run_test 204d "Print default stripe count and size"
18365
18366 test_204e() {
18367         test_mkdir $DIR/$tdir
18368         $LFS setstripe -d $DIR/$tdir
18369
18370         check_default_stripe_attr --stripe-count --raw
18371         check_default_stripe_attr --stripe-size --raw
18372         check_default_stripe_attr --stripe-index --raw
18373 }
18374 run_test 204e "Print raw stripe attributes"
18375
18376 test_204f() {
18377         test_mkdir $DIR/$tdir
18378         $LFS setstripe --stripe-count 1 $DIR/$tdir
18379
18380         check_default_stripe_attr --stripe-size --raw
18381         check_default_stripe_attr --stripe-index --raw
18382 }
18383 run_test 204f "Print raw stripe size and offset"
18384
18385 test_204g() {
18386         test_mkdir $DIR/$tdir
18387         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18388
18389         check_default_stripe_attr --stripe-count --raw
18390         check_default_stripe_attr --stripe-index --raw
18391 }
18392 run_test 204g "Print raw stripe count and offset"
18393
18394 test_204h() {
18395         test_mkdir $DIR/$tdir
18396         $LFS setstripe --stripe-index 0 $DIR/$tdir
18397
18398         check_default_stripe_attr --stripe-count --raw
18399         check_default_stripe_attr --stripe-size --raw
18400 }
18401 run_test 204h "Print raw stripe count and size"
18402
18403 # Figure out which job scheduler is being used, if any,
18404 # or use a fake one
18405 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18406         JOBENV=SLURM_JOB_ID
18407 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18408         JOBENV=LSB_JOBID
18409 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18410         JOBENV=PBS_JOBID
18411 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18412         JOBENV=LOADL_STEP_ID
18413 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18414         JOBENV=JOB_ID
18415 else
18416         $LCTL list_param jobid_name > /dev/null 2>&1
18417         if [ $? -eq 0 ]; then
18418                 JOBENV=nodelocal
18419         else
18420                 JOBENV=FAKE_JOBID
18421         fi
18422 fi
18423 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18424
18425 verify_jobstats() {
18426         local cmd=($1)
18427         shift
18428         local facets="$@"
18429
18430 # we don't really need to clear the stats for this test to work, since each
18431 # command has a unique jobid, but it makes debugging easier if needed.
18432 #       for facet in $facets; do
18433 #               local dev=$(convert_facet2label $facet)
18434 #               # clear old jobstats
18435 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18436 #       done
18437
18438         # use a new JobID for each test, or we might see an old one
18439         [ "$JOBENV" = "FAKE_JOBID" ] &&
18440                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18441
18442         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18443
18444         [ "$JOBENV" = "nodelocal" ] && {
18445                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18446                 $LCTL set_param jobid_name=$FAKE_JOBID
18447                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18448         }
18449
18450         log "Test: ${cmd[*]}"
18451         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18452
18453         if [ $JOBENV = "FAKE_JOBID" ]; then
18454                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18455         else
18456                 ${cmd[*]}
18457         fi
18458
18459         # all files are created on OST0000
18460         for facet in $facets; do
18461                 local stats="*.$(convert_facet2label $facet).job_stats"
18462
18463                 # strip out libtool wrappers for in-tree executables
18464                 if (( $(do_facet $facet lctl get_param $stats |
18465                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18466                         do_facet $facet lctl get_param $stats
18467                         error "No jobstats for $JOBVAL found on $facet::$stats"
18468                 fi
18469         done
18470 }
18471
18472 jobstats_set() {
18473         local new_jobenv=$1
18474
18475         set_persistent_param_and_check client "jobid_var" \
18476                 "$FSNAME.sys.jobid_var" $new_jobenv
18477 }
18478
18479 test_205a() { # Job stats
18480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18481         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18482                 skip "Need MDS version with at least 2.7.1"
18483         remote_mgs_nodsh && skip "remote MGS with nodsh"
18484         remote_mds_nodsh && skip "remote MDS with nodsh"
18485         remote_ost_nodsh && skip "remote OST with nodsh"
18486         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18487                 skip "Server doesn't support jobstats"
18488         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18489
18490         local old_jobenv=$($LCTL get_param -n jobid_var)
18491         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18492
18493         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18494                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18495         else
18496                 stack_trap "do_facet mgs $PERM_CMD \
18497                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18498         fi
18499         changelog_register
18500
18501         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18502                                 mdt.*.job_cleanup_interval | head -n 1)
18503         local new_interval=5
18504         do_facet $SINGLEMDS \
18505                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18506         stack_trap "do_facet $SINGLEMDS \
18507                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18508         local start=$SECONDS
18509
18510         local cmd
18511         # mkdir
18512         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18513         verify_jobstats "$cmd" "$SINGLEMDS"
18514         # rmdir
18515         cmd="rmdir $DIR/$tdir"
18516         verify_jobstats "$cmd" "$SINGLEMDS"
18517         # mkdir on secondary MDT
18518         if [ $MDSCOUNT -gt 1 ]; then
18519                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18520                 verify_jobstats "$cmd" "mds2"
18521         fi
18522         # mknod
18523         cmd="mknod $DIR/$tfile c 1 3"
18524         verify_jobstats "$cmd" "$SINGLEMDS"
18525         # unlink
18526         cmd="rm -f $DIR/$tfile"
18527         verify_jobstats "$cmd" "$SINGLEMDS"
18528         # create all files on OST0000 so verify_jobstats can find OST stats
18529         # open & close
18530         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18531         verify_jobstats "$cmd" "$SINGLEMDS"
18532         # setattr
18533         cmd="touch $DIR/$tfile"
18534         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18535         # write
18536         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18537         verify_jobstats "$cmd" "ost1"
18538         # read
18539         cancel_lru_locks osc
18540         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18541         verify_jobstats "$cmd" "ost1"
18542         # truncate
18543         cmd="$TRUNCATE $DIR/$tfile 0"
18544         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18545         # rename
18546         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18547         verify_jobstats "$cmd" "$SINGLEMDS"
18548         # jobstats expiry - sleep until old stats should be expired
18549         local left=$((new_interval + 5 - (SECONDS - start)))
18550         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18551                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18552                         "0" $left
18553         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18554         verify_jobstats "$cmd" "$SINGLEMDS"
18555         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18556             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18557
18558         # Ensure that jobid are present in changelog (if supported by MDS)
18559         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18560                 changelog_dump | tail -10
18561                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18562                 [ $jobids -eq 9 ] ||
18563                         error "Wrong changelog jobid count $jobids != 9"
18564
18565                 # LU-5862
18566                 JOBENV="disable"
18567                 jobstats_set $JOBENV
18568                 touch $DIR/$tfile
18569                 changelog_dump | grep $tfile
18570                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18571                 [ $jobids -eq 0 ] ||
18572                         error "Unexpected jobids when jobid_var=$JOBENV"
18573         fi
18574
18575         # test '%j' access to environment variable - if supported
18576         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18577                 JOBENV="JOBCOMPLEX"
18578                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18579
18580                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18581         fi
18582
18583         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18584                 JOBENV="JOBCOMPLEX"
18585                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18586
18587                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18588         fi
18589
18590         # test '%j' access to per-session jobid - if supported
18591         if lctl list_param jobid_this_session > /dev/null 2>&1
18592         then
18593                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18594                 lctl set_param jobid_this_session=$USER
18595
18596                 JOBENV="JOBCOMPLEX"
18597                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18598
18599                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18600         fi
18601 }
18602 run_test 205a "Verify job stats"
18603
18604 # LU-13117, LU-13597
18605 test_205b() {
18606         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18607                 skip "Need MDS version at least 2.13.54.91"
18608
18609         job_stats="mdt.*.job_stats"
18610         $LCTL set_param $job_stats=clear
18611         # Setting jobid_var to USER might not be supported
18612         $LCTL set_param jobid_var=USER || true
18613         $LCTL set_param jobid_name="%e.%u"
18614         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18615         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18616                 grep "job_id:.*foolish" &&
18617                         error "Unexpected jobid found"
18618         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18619                 grep "open:.*min.*max.*sum" ||
18620                         error "wrong job_stats format found"
18621 }
18622 run_test 205b "Verify job stats jobid and output format"
18623
18624 # LU-13733
18625 test_205c() {
18626         $LCTL set_param llite.*.stats=0
18627         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18628         $LCTL get_param llite.*.stats
18629         $LCTL get_param llite.*.stats | grep \
18630                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18631                         error "wrong client stats format found"
18632 }
18633 run_test 205c "Verify client stats format"
18634
18635 # LU-1480, LU-1773 and LU-1657
18636 test_206() {
18637         mkdir -p $DIR/$tdir
18638         $LFS setstripe -c -1 $DIR/$tdir
18639 #define OBD_FAIL_LOV_INIT 0x1403
18640         $LCTL set_param fail_loc=0xa0001403
18641         $LCTL set_param fail_val=1
18642         touch $DIR/$tdir/$tfile || true
18643 }
18644 run_test 206 "fail lov_init_raid0() doesn't lbug"
18645
18646 test_207a() {
18647         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18648         local fsz=`stat -c %s $DIR/$tfile`
18649         cancel_lru_locks mdc
18650
18651         # do not return layout in getattr intent
18652 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18653         $LCTL set_param fail_loc=0x170
18654         local sz=`stat -c %s $DIR/$tfile`
18655
18656         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18657
18658         rm -rf $DIR/$tfile
18659 }
18660 run_test 207a "can refresh layout at glimpse"
18661
18662 test_207b() {
18663         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18664         local cksum=`md5sum $DIR/$tfile`
18665         local fsz=`stat -c %s $DIR/$tfile`
18666         cancel_lru_locks mdc
18667         cancel_lru_locks osc
18668
18669         # do not return layout in getattr intent
18670 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18671         $LCTL set_param fail_loc=0x171
18672
18673         # it will refresh layout after the file is opened but before read issues
18674         echo checksum is "$cksum"
18675         echo "$cksum" |md5sum -c --quiet || error "file differs"
18676
18677         rm -rf $DIR/$tfile
18678 }
18679 run_test 207b "can refresh layout at open"
18680
18681 test_208() {
18682         # FIXME: in this test suite, only RD lease is used. This is okay
18683         # for now as only exclusive open is supported. After generic lease
18684         # is done, this test suite should be revised. - Jinshan
18685
18686         remote_mds_nodsh && skip "remote MDS with nodsh"
18687         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18688                 skip "Need MDS version at least 2.4.52"
18689
18690         echo "==== test 1: verify get lease work"
18691         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18692
18693         echo "==== test 2: verify lease can be broken by upcoming open"
18694         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18695         local PID=$!
18696         sleep 2
18697
18698         $MULTIOP $DIR/$tfile oO_RDWR:c
18699         kill -USR1 $PID && wait $PID || error "break lease error"
18700
18701         echo "==== test 3: verify lease can't be granted if an open already exists"
18702         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18703         local PID=$!
18704         sleep 2
18705
18706         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18707         kill -USR1 $PID && wait $PID || error "open file error"
18708
18709         echo "==== test 4: lease can sustain over recovery"
18710         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18711         PID=$!
18712         sleep 2
18713
18714         fail mds1
18715
18716         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18717
18718         echo "==== test 5: lease broken can't be regained by replay"
18719         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18720         PID=$!
18721         sleep 2
18722
18723         # open file to break lease and then recovery
18724         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18725         fail mds1
18726
18727         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18728
18729         rm -f $DIR/$tfile
18730 }
18731 run_test 208 "Exclusive open"
18732
18733 test_209() {
18734         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18735                 skip_env "must have disp_stripe"
18736
18737         touch $DIR/$tfile
18738         sync; sleep 5; sync;
18739
18740         echo 3 > /proc/sys/vm/drop_caches
18741         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18742                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18743         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18744
18745         # open/close 500 times
18746         for i in $(seq 500); do
18747                 cat $DIR/$tfile
18748         done
18749
18750         echo 3 > /proc/sys/vm/drop_caches
18751         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18752                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18753         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18754
18755         echo "before: $req_before, after: $req_after"
18756         [ $((req_after - req_before)) -ge 300 ] &&
18757                 error "open/close requests are not freed"
18758         return 0
18759 }
18760 run_test 209 "read-only open/close requests should be freed promptly"
18761
18762 test_210() {
18763         local pid
18764
18765         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18766         pid=$!
18767         sleep 1
18768
18769         $LFS getstripe $DIR/$tfile
18770         kill -USR1 $pid
18771         wait $pid || error "multiop failed"
18772
18773         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18774         pid=$!
18775         sleep 1
18776
18777         $LFS getstripe $DIR/$tfile
18778         kill -USR1 $pid
18779         wait $pid || error "multiop failed"
18780 }
18781 run_test 210 "lfs getstripe does not break leases"
18782
18783 test_212() {
18784         size=`date +%s`
18785         size=$((size % 8192 + 1))
18786         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18787         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18788         rm -f $DIR/f212 $DIR/f212.xyz
18789 }
18790 run_test 212 "Sendfile test ============================================"
18791
18792 test_213() {
18793         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18794         cancel_lru_locks osc
18795         lctl set_param fail_loc=0x8000040f
18796         # generate a read lock
18797         cat $DIR/$tfile > /dev/null
18798         # write to the file, it will try to cancel the above read lock.
18799         cat /etc/hosts >> $DIR/$tfile
18800 }
18801 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18802
18803 test_214() { # for bug 20133
18804         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18805         for (( i=0; i < 340; i++ )) ; do
18806                 touch $DIR/$tdir/d214c/a$i
18807         done
18808
18809         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18810         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18811         ls $DIR/d214c || error "ls $DIR/d214c failed"
18812         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18813         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18814 }
18815 run_test 214 "hash-indexed directory test - bug 20133"
18816
18817 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18818 create_lnet_proc_files() {
18819         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18820 }
18821
18822 # counterpart of create_lnet_proc_files
18823 remove_lnet_proc_files() {
18824         rm -f $TMP/lnet_$1.sys
18825 }
18826
18827 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18828 # 3rd arg as regexp for body
18829 check_lnet_proc_stats() {
18830         local l=$(cat "$TMP/lnet_$1" |wc -l)
18831         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18832
18833         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18834 }
18835
18836 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18837 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18838 # optional and can be regexp for 2nd line (lnet.routes case)
18839 check_lnet_proc_entry() {
18840         local blp=2          # blp stands for 'position of 1st line of body'
18841         [ -z "$5" ] || blp=3 # lnet.routes case
18842
18843         local l=$(cat "$TMP/lnet_$1" |wc -l)
18844         # subtracting one from $blp because the body can be empty
18845         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18846
18847         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18848                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18849
18850         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18851                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18852
18853         # bail out if any unexpected line happened
18854         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18855         [ "$?" != 0 ] || error "$2 misformatted"
18856 }
18857
18858 test_215() { # for bugs 18102, 21079, 21517
18859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18860
18861         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18862         local P='[1-9][0-9]*'           # positive numeric
18863         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18864         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18865         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18866         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18867
18868         local L1 # regexp for 1st line
18869         local L2 # regexp for 2nd line (optional)
18870         local BR # regexp for the rest (body)
18871
18872         # lnet.stats should look as 11 space-separated non-negative numerics
18873         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18874         create_lnet_proc_files "stats"
18875         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18876         remove_lnet_proc_files "stats"
18877
18878         # lnet.routes should look like this:
18879         # Routing disabled/enabled
18880         # net hops priority state router
18881         # where net is a string like tcp0, hops > 0, priority >= 0,
18882         # state is up/down,
18883         # router is a string like 192.168.1.1@tcp2
18884         L1="^Routing (disabled|enabled)$"
18885         L2="^net +hops +priority +state +router$"
18886         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18887         create_lnet_proc_files "routes"
18888         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18889         remove_lnet_proc_files "routes"
18890
18891         # lnet.routers should look like this:
18892         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18893         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18894         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18895         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18896         L1="^ref +rtr_ref +alive +router$"
18897         BR="^$P +$P +(up|down) +$NID$"
18898         create_lnet_proc_files "routers"
18899         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18900         remove_lnet_proc_files "routers"
18901
18902         # lnet.peers should look like this:
18903         # nid refs state last max rtr min tx min queue
18904         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18905         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18906         # numeric (0 or >0 or <0), queue >= 0.
18907         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18908         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18909         create_lnet_proc_files "peers"
18910         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18911         remove_lnet_proc_files "peers"
18912
18913         # lnet.buffers  should look like this:
18914         # pages count credits min
18915         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18916         L1="^pages +count +credits +min$"
18917         BR="^ +$N +$N +$I +$I$"
18918         create_lnet_proc_files "buffers"
18919         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18920         remove_lnet_proc_files "buffers"
18921
18922         # lnet.nis should look like this:
18923         # nid status alive refs peer rtr max tx min
18924         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18925         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18926         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18927         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18928         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18929         create_lnet_proc_files "nis"
18930         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18931         remove_lnet_proc_files "nis"
18932
18933         # can we successfully write to lnet.stats?
18934         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18935 }
18936 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18937
18938 test_216() { # bug 20317
18939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18940         remote_ost_nodsh && skip "remote OST with nodsh"
18941
18942         local node
18943         local facets=$(get_facets OST)
18944         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18945
18946         save_lustre_params client "osc.*.contention_seconds" > $p
18947         save_lustre_params $facets \
18948                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18949         save_lustre_params $facets \
18950                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18951         save_lustre_params $facets \
18952                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18953         clear_stats osc.*.osc_stats
18954
18955         # agressive lockless i/o settings
18956         do_nodes $(comma_list $(osts_nodes)) \
18957                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18958                         ldlm.namespaces.filter-*.contended_locks=0 \
18959                         ldlm.namespaces.filter-*.contention_seconds=60"
18960         lctl set_param -n osc.*.contention_seconds=60
18961
18962         $DIRECTIO write $DIR/$tfile 0 10 4096
18963         $CHECKSTAT -s 40960 $DIR/$tfile
18964
18965         # disable lockless i/o
18966         do_nodes $(comma_list $(osts_nodes)) \
18967                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18968                         ldlm.namespaces.filter-*.contended_locks=32 \
18969                         ldlm.namespaces.filter-*.contention_seconds=0"
18970         lctl set_param -n osc.*.contention_seconds=0
18971         clear_stats osc.*.osc_stats
18972
18973         dd if=/dev/zero of=$DIR/$tfile count=0
18974         $CHECKSTAT -s 0 $DIR/$tfile
18975
18976         restore_lustre_params <$p
18977         rm -f $p
18978         rm $DIR/$tfile
18979 }
18980 run_test 216 "check lockless direct write updates file size and kms correctly"
18981
18982 test_217() { # bug 22430
18983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18984
18985         local node
18986         local nid
18987
18988         for node in $(nodes_list); do
18989                 nid=$(host_nids_address $node $NETTYPE)
18990                 if [[ $nid = *-* ]] ; then
18991                         echo "lctl ping $(h2nettype $nid)"
18992                         lctl ping $(h2nettype $nid)
18993                 else
18994                         echo "skipping $node (no hyphen detected)"
18995                 fi
18996         done
18997 }
18998 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18999
19000 test_218() {
19001        # do directio so as not to populate the page cache
19002        log "creating a 10 Mb file"
19003        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19004        log "starting reads"
19005        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19006        log "truncating the file"
19007        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19008        log "killing dd"
19009        kill %+ || true # reads might have finished
19010        echo "wait until dd is finished"
19011        wait
19012        log "removing the temporary file"
19013        rm -rf $DIR/$tfile || error "tmp file removal failed"
19014 }
19015 run_test 218 "parallel read and truncate should not deadlock"
19016
19017 test_219() {
19018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19019
19020         # write one partial page
19021         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19022         # set no grant so vvp_io_commit_write will do sync write
19023         $LCTL set_param fail_loc=0x411
19024         # write a full page at the end of file
19025         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19026
19027         $LCTL set_param fail_loc=0
19028         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19029         $LCTL set_param fail_loc=0x411
19030         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19031
19032         # LU-4201
19033         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19034         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19035 }
19036 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19037
19038 test_220() { #LU-325
19039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19040         remote_ost_nodsh && skip "remote OST with nodsh"
19041         remote_mds_nodsh && skip "remote MDS with nodsh"
19042         remote_mgs_nodsh && skip "remote MGS with nodsh"
19043
19044         local OSTIDX=0
19045
19046         # create on MDT0000 so the last_id and next_id are correct
19047         mkdir_on_mdt0 $DIR/$tdir
19048         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19049         OST=${OST%_UUID}
19050
19051         # on the mdt's osc
19052         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19053         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19054                         osp.$mdtosc_proc1.prealloc_last_id)
19055         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19056                         osp.$mdtosc_proc1.prealloc_next_id)
19057
19058         $LFS df -i
19059
19060         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19061         #define OBD_FAIL_OST_ENOINO              0x229
19062         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19063         create_pool $FSNAME.$TESTNAME || return 1
19064         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19065
19066         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19067
19068         MDSOBJS=$((last_id - next_id))
19069         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19070
19071         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19072         echo "OST still has $count kbytes free"
19073
19074         echo "create $MDSOBJS files @next_id..."
19075         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19076
19077         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19078                         osp.$mdtosc_proc1.prealloc_last_id)
19079         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19080                         osp.$mdtosc_proc1.prealloc_next_id)
19081
19082         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19083         $LFS df -i
19084
19085         echo "cleanup..."
19086
19087         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19088         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19089
19090         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19091                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19092         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19093                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19094         echo "unlink $MDSOBJS files @$next_id..."
19095         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19096 }
19097 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19098
19099 test_221() {
19100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19101
19102         dd if=`which date` of=$MOUNT/date oflag=sync
19103         chmod +x $MOUNT/date
19104
19105         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19106         $LCTL set_param fail_loc=0x80001401
19107
19108         $MOUNT/date > /dev/null
19109         rm -f $MOUNT/date
19110 }
19111 run_test 221 "make sure fault and truncate race to not cause OOM"
19112
19113 test_222a () {
19114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19115
19116         rm -rf $DIR/$tdir
19117         test_mkdir $DIR/$tdir
19118         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19119         createmany -o $DIR/$tdir/$tfile 10
19120         cancel_lru_locks mdc
19121         cancel_lru_locks osc
19122         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19123         $LCTL set_param fail_loc=0x31a
19124         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19125         $LCTL set_param fail_loc=0
19126         rm -r $DIR/$tdir
19127 }
19128 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19129
19130 test_222b () {
19131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19132
19133         rm -rf $DIR/$tdir
19134         test_mkdir $DIR/$tdir
19135         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19136         createmany -o $DIR/$tdir/$tfile 10
19137         cancel_lru_locks mdc
19138         cancel_lru_locks osc
19139         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19140         $LCTL set_param fail_loc=0x31a
19141         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19142         $LCTL set_param fail_loc=0
19143 }
19144 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19145
19146 test_223 () {
19147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19148
19149         rm -rf $DIR/$tdir
19150         test_mkdir $DIR/$tdir
19151         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19152         createmany -o $DIR/$tdir/$tfile 10
19153         cancel_lru_locks mdc
19154         cancel_lru_locks osc
19155         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19156         $LCTL set_param fail_loc=0x31b
19157         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19158         $LCTL set_param fail_loc=0
19159         rm -r $DIR/$tdir
19160 }
19161 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19162
19163 test_224a() { # LU-1039, MRP-303
19164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19165         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19166         $LCTL set_param fail_loc=0x508
19167         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19168         $LCTL set_param fail_loc=0
19169         df $DIR
19170 }
19171 run_test 224a "Don't panic on bulk IO failure"
19172
19173 test_224bd_sub() { # LU-1039, MRP-303
19174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19175         local timeout=$1
19176
19177         shift
19178         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19179
19180         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19181
19182         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19183         cancel_lru_locks osc
19184         set_checksums 0
19185         stack_trap "set_checksums $ORIG_CSUM" EXIT
19186         local at_max_saved=0
19187
19188         # adaptive timeouts may prevent seeing the issue
19189         if at_is_enabled; then
19190                 at_max_saved=$(at_max_get mds)
19191                 at_max_set 0 mds client
19192                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19193         fi
19194
19195         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19196         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19197         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19198
19199         do_facet ost1 $LCTL set_param fail_loc=0
19200         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19201         df $DIR
19202 }
19203
19204 test_224b() {
19205         test_224bd_sub 3 error "dd failed"
19206 }
19207 run_test 224b "Don't panic on bulk IO failure"
19208
19209 test_224c() { # LU-6441
19210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19211         remote_mds_nodsh && skip "remote MDS with nodsh"
19212
19213         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19214         save_writethrough $p
19215         set_cache writethrough on
19216
19217         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19218         local at_max=$($LCTL get_param -n at_max)
19219         local timeout=$($LCTL get_param -n timeout)
19220         local test_at="at_max"
19221         local param_at="$FSNAME.sys.at_max"
19222         local test_timeout="timeout"
19223         local param_timeout="$FSNAME.sys.timeout"
19224
19225         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19226
19227         set_persistent_param_and_check client "$test_at" "$param_at" 0
19228         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19229
19230         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19231         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19232         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19233         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19234         sync
19235         do_facet ost1 "$LCTL set_param fail_loc=0"
19236
19237         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19238         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19239                 $timeout
19240
19241         $LCTL set_param -n $pages_per_rpc
19242         restore_lustre_params < $p
19243         rm -f $p
19244 }
19245 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19246
19247 test_224d() { # LU-11169
19248         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19249 }
19250 run_test 224d "Don't corrupt data on bulk IO timeout"
19251
19252 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19253 test_225a () {
19254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19255         if [ -z ${MDSSURVEY} ]; then
19256                 skip_env "mds-survey not found"
19257         fi
19258         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19259                 skip "Need MDS version at least 2.2.51"
19260
19261         local mds=$(facet_host $SINGLEMDS)
19262         local target=$(do_nodes $mds 'lctl dl' |
19263                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19264
19265         local cmd1="file_count=1000 thrhi=4"
19266         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19267         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19268         local cmd="$cmd1 $cmd2 $cmd3"
19269
19270         rm -f ${TMP}/mds_survey*
19271         echo + $cmd
19272         eval $cmd || error "mds-survey with zero-stripe failed"
19273         cat ${TMP}/mds_survey*
19274         rm -f ${TMP}/mds_survey*
19275 }
19276 run_test 225a "Metadata survey sanity with zero-stripe"
19277
19278 test_225b () {
19279         if [ -z ${MDSSURVEY} ]; then
19280                 skip_env "mds-survey not found"
19281         fi
19282         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19283                 skip "Need MDS version at least 2.2.51"
19284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19285         remote_mds_nodsh && skip "remote MDS with nodsh"
19286         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19287                 skip_env "Need to mount OST to test"
19288         fi
19289
19290         local mds=$(facet_host $SINGLEMDS)
19291         local target=$(do_nodes $mds 'lctl dl' |
19292                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19293
19294         local cmd1="file_count=1000 thrhi=4"
19295         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19296         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19297         local cmd="$cmd1 $cmd2 $cmd3"
19298
19299         rm -f ${TMP}/mds_survey*
19300         echo + $cmd
19301         eval $cmd || error "mds-survey with stripe_count failed"
19302         cat ${TMP}/mds_survey*
19303         rm -f ${TMP}/mds_survey*
19304 }
19305 run_test 225b "Metadata survey sanity with stripe_count = 1"
19306
19307 mcreate_path2fid () {
19308         local mode=$1
19309         local major=$2
19310         local minor=$3
19311         local name=$4
19312         local desc=$5
19313         local path=$DIR/$tdir/$name
19314         local fid
19315         local rc
19316         local fid_path
19317
19318         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19319                 error "cannot create $desc"
19320
19321         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19322         rc=$?
19323         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19324
19325         fid_path=$($LFS fid2path $MOUNT $fid)
19326         rc=$?
19327         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19328
19329         [ "$path" == "$fid_path" ] ||
19330                 error "fid2path returned $fid_path, expected $path"
19331
19332         echo "pass with $path and $fid"
19333 }
19334
19335 test_226a () {
19336         rm -rf $DIR/$tdir
19337         mkdir -p $DIR/$tdir
19338
19339         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19340         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19341         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19342         mcreate_path2fid 0040666 0 0 dir "directory"
19343         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19344         mcreate_path2fid 0100666 0 0 file "regular file"
19345         mcreate_path2fid 0120666 0 0 link "symbolic link"
19346         mcreate_path2fid 0140666 0 0 sock "socket"
19347 }
19348 run_test 226a "call path2fid and fid2path on files of all type"
19349
19350 test_226b () {
19351         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19352
19353         local MDTIDX=1
19354
19355         rm -rf $DIR/$tdir
19356         mkdir -p $DIR/$tdir
19357         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19358                 error "create remote directory failed"
19359         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19360         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19361                                 "character special file (null)"
19362         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19363                                 "character special file (no device)"
19364         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19365         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19366                                 "block special file (loop)"
19367         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19368         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19369         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19370 }
19371 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19372
19373 test_226c () {
19374         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19375         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19376                 skip "Need MDS version at least 2.13.55"
19377
19378         local submnt=/mnt/submnt
19379         local srcfile=/etc/passwd
19380         local dstfile=$submnt/passwd
19381         local path
19382         local fid
19383
19384         rm -rf $DIR/$tdir
19385         rm -rf $submnt
19386         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19387                 error "create remote directory failed"
19388         mkdir -p $submnt || error "create $submnt failed"
19389         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19390                 error "mount $submnt failed"
19391         stack_trap "umount $submnt" EXIT
19392
19393         cp $srcfile $dstfile
19394         fid=$($LFS path2fid $dstfile)
19395         path=$($LFS fid2path $submnt "$fid")
19396         [ "$path" = "$dstfile" ] ||
19397                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19398 }
19399 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19400
19401 # LU-1299 Executing or running ldd on a truncated executable does not
19402 # cause an out-of-memory condition.
19403 test_227() {
19404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19405         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19406
19407         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19408         chmod +x $MOUNT/date
19409
19410         $MOUNT/date > /dev/null
19411         ldd $MOUNT/date > /dev/null
19412         rm -f $MOUNT/date
19413 }
19414 run_test 227 "running truncated executable does not cause OOM"
19415
19416 # LU-1512 try to reuse idle OI blocks
19417 test_228a() {
19418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19419         remote_mds_nodsh && skip "remote MDS with nodsh"
19420         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19421
19422         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19423         local myDIR=$DIR/$tdir
19424
19425         mkdir -p $myDIR
19426         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19427         $LCTL set_param fail_loc=0x80001002
19428         createmany -o $myDIR/t- 10000
19429         $LCTL set_param fail_loc=0
19430         # The guard is current the largest FID holder
19431         touch $myDIR/guard
19432         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19433                     tr -d '[')
19434         local IDX=$(($SEQ % 64))
19435
19436         do_facet $SINGLEMDS sync
19437         # Make sure journal flushed.
19438         sleep 6
19439         local blk1=$(do_facet $SINGLEMDS \
19440                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19441                      grep Blockcount | awk '{print $4}')
19442
19443         # Remove old files, some OI blocks will become idle.
19444         unlinkmany $myDIR/t- 10000
19445         # Create new files, idle OI blocks should be reused.
19446         createmany -o $myDIR/t- 2000
19447         do_facet $SINGLEMDS sync
19448         # Make sure journal flushed.
19449         sleep 6
19450         local blk2=$(do_facet $SINGLEMDS \
19451                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19452                      grep Blockcount | awk '{print $4}')
19453
19454         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19455 }
19456 run_test 228a "try to reuse idle OI blocks"
19457
19458 test_228b() {
19459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19460         remote_mds_nodsh && skip "remote MDS with nodsh"
19461         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19462
19463         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19464         local myDIR=$DIR/$tdir
19465
19466         mkdir -p $myDIR
19467         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19468         $LCTL set_param fail_loc=0x80001002
19469         createmany -o $myDIR/t- 10000
19470         $LCTL set_param fail_loc=0
19471         # The guard is current the largest FID holder
19472         touch $myDIR/guard
19473         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19474                     tr -d '[')
19475         local IDX=$(($SEQ % 64))
19476
19477         do_facet $SINGLEMDS sync
19478         # Make sure journal flushed.
19479         sleep 6
19480         local blk1=$(do_facet $SINGLEMDS \
19481                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19482                      grep Blockcount | awk '{print $4}')
19483
19484         # Remove old files, some OI blocks will become idle.
19485         unlinkmany $myDIR/t- 10000
19486
19487         # stop the MDT
19488         stop $SINGLEMDS || error "Fail to stop MDT."
19489         # remount the MDT
19490         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19491                 error "Fail to start MDT."
19492
19493         df $MOUNT || error "Fail to df."
19494         # Create new files, idle OI blocks should be reused.
19495         createmany -o $myDIR/t- 2000
19496         do_facet $SINGLEMDS sync
19497         # Make sure journal flushed.
19498         sleep 6
19499         local blk2=$(do_facet $SINGLEMDS \
19500                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19501                      grep Blockcount | awk '{print $4}')
19502
19503         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19504 }
19505 run_test 228b "idle OI blocks can be reused after MDT restart"
19506
19507 #LU-1881
19508 test_228c() {
19509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19510         remote_mds_nodsh && skip "remote MDS with nodsh"
19511         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19512
19513         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19514         local myDIR=$DIR/$tdir
19515
19516         mkdir -p $myDIR
19517         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19518         $LCTL set_param fail_loc=0x80001002
19519         # 20000 files can guarantee there are index nodes in the OI file
19520         createmany -o $myDIR/t- 20000
19521         $LCTL set_param fail_loc=0
19522         # The guard is current the largest FID holder
19523         touch $myDIR/guard
19524         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19525                     tr -d '[')
19526         local IDX=$(($SEQ % 64))
19527
19528         do_facet $SINGLEMDS sync
19529         # Make sure journal flushed.
19530         sleep 6
19531         local blk1=$(do_facet $SINGLEMDS \
19532                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19533                      grep Blockcount | awk '{print $4}')
19534
19535         # Remove old files, some OI blocks will become idle.
19536         unlinkmany $myDIR/t- 20000
19537         rm -f $myDIR/guard
19538         # The OI file should become empty now
19539
19540         # Create new files, idle OI blocks should be reused.
19541         createmany -o $myDIR/t- 2000
19542         do_facet $SINGLEMDS sync
19543         # Make sure journal flushed.
19544         sleep 6
19545         local blk2=$(do_facet $SINGLEMDS \
19546                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19547                      grep Blockcount | awk '{print $4}')
19548
19549         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19550 }
19551 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19552
19553 test_229() { # LU-2482, LU-3448
19554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19555         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19556         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19557                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19558
19559         rm -f $DIR/$tfile
19560
19561         # Create a file with a released layout and stripe count 2.
19562         $MULTIOP $DIR/$tfile H2c ||
19563                 error "failed to create file with released layout"
19564
19565         $LFS getstripe -v $DIR/$tfile
19566
19567         local pattern=$($LFS getstripe -L $DIR/$tfile)
19568         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19569
19570         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19571                 error "getstripe"
19572         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19573         stat $DIR/$tfile || error "failed to stat released file"
19574
19575         chown $RUNAS_ID $DIR/$tfile ||
19576                 error "chown $RUNAS_ID $DIR/$tfile failed"
19577
19578         chgrp $RUNAS_ID $DIR/$tfile ||
19579                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19580
19581         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19582         rm $DIR/$tfile || error "failed to remove released file"
19583 }
19584 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19585
19586 test_230a() {
19587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19588         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19589         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19590                 skip "Need MDS version at least 2.11.52"
19591
19592         local MDTIDX=1
19593
19594         test_mkdir $DIR/$tdir
19595         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19596         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19597         [ $mdt_idx -ne 0 ] &&
19598                 error "create local directory on wrong MDT $mdt_idx"
19599
19600         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19601                         error "create remote directory failed"
19602         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19603         [ $mdt_idx -ne $MDTIDX ] &&
19604                 error "create remote directory on wrong MDT $mdt_idx"
19605
19606         createmany -o $DIR/$tdir/test_230/t- 10 ||
19607                 error "create files on remote directory failed"
19608         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19609         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19610         rm -r $DIR/$tdir || error "unlink remote directory failed"
19611 }
19612 run_test 230a "Create remote directory and files under the remote directory"
19613
19614 test_230b() {
19615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19616         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19617         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19618                 skip "Need MDS version at least 2.11.52"
19619
19620         local MDTIDX=1
19621         local mdt_index
19622         local i
19623         local file
19624         local pid
19625         local stripe_count
19626         local migrate_dir=$DIR/$tdir/migrate_dir
19627         local other_dir=$DIR/$tdir/other_dir
19628
19629         test_mkdir $DIR/$tdir
19630         test_mkdir -i0 -c1 $migrate_dir
19631         test_mkdir -i0 -c1 $other_dir
19632         for ((i=0; i<10; i++)); do
19633                 mkdir -p $migrate_dir/dir_${i}
19634                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19635                         error "create files under remote dir failed $i"
19636         done
19637
19638         cp /etc/passwd $migrate_dir/$tfile
19639         cp /etc/passwd $other_dir/$tfile
19640         chattr +SAD $migrate_dir
19641         chattr +SAD $migrate_dir/$tfile
19642
19643         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19644         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19645         local old_dir_mode=$(stat -c%f $migrate_dir)
19646         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19647
19648         mkdir -p $migrate_dir/dir_default_stripe2
19649         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19650         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19651
19652         mkdir -p $other_dir
19653         ln $migrate_dir/$tfile $other_dir/luna
19654         ln $migrate_dir/$tfile $migrate_dir/sofia
19655         ln $other_dir/$tfile $migrate_dir/david
19656         ln -s $migrate_dir/$tfile $other_dir/zachary
19657         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19658         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19659
19660         local len
19661         local lnktgt
19662
19663         # inline symlink
19664         for len in 58 59 60; do
19665                 lnktgt=$(str_repeat 'l' $len)
19666                 touch $migrate_dir/$lnktgt
19667                 ln -s $lnktgt $migrate_dir/${len}char_ln
19668         done
19669
19670         # PATH_MAX
19671         for len in 4094 4095; do
19672                 lnktgt=$(str_repeat 'l' $len)
19673                 ln -s $lnktgt $migrate_dir/${len}char_ln
19674         done
19675
19676         # NAME_MAX
19677         for len in 254 255; do
19678                 touch $migrate_dir/$(str_repeat 'l' $len)
19679         done
19680
19681         $LFS migrate -m $MDTIDX $migrate_dir ||
19682                 error "fails on migrating remote dir to MDT1"
19683
19684         echo "migratate to MDT1, then checking.."
19685         for ((i = 0; i < 10; i++)); do
19686                 for file in $(find $migrate_dir/dir_${i}); do
19687                         mdt_index=$($LFS getstripe -m $file)
19688                         # broken symlink getstripe will fail
19689                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19690                                 error "$file is not on MDT${MDTIDX}"
19691                 done
19692         done
19693
19694         # the multiple link file should still in MDT0
19695         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19696         [ $mdt_index == 0 ] ||
19697                 error "$file is not on MDT${MDTIDX}"
19698
19699         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19700         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19701                 error " expect $old_dir_flag get $new_dir_flag"
19702
19703         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19704         [ "$old_file_flag" = "$new_file_flag" ] ||
19705                 error " expect $old_file_flag get $new_file_flag"
19706
19707         local new_dir_mode=$(stat -c%f $migrate_dir)
19708         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19709                 error "expect mode $old_dir_mode get $new_dir_mode"
19710
19711         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19712         [ "$old_file_mode" = "$new_file_mode" ] ||
19713                 error "expect mode $old_file_mode get $new_file_mode"
19714
19715         diff /etc/passwd $migrate_dir/$tfile ||
19716                 error "$tfile different after migration"
19717
19718         diff /etc/passwd $other_dir/luna ||
19719                 error "luna different after migration"
19720
19721         diff /etc/passwd $migrate_dir/sofia ||
19722                 error "sofia different after migration"
19723
19724         diff /etc/passwd $migrate_dir/david ||
19725                 error "david different after migration"
19726
19727         diff /etc/passwd $other_dir/zachary ||
19728                 error "zachary different after migration"
19729
19730         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19731                 error "${tfile}_ln different after migration"
19732
19733         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19734                 error "${tfile}_ln_other different after migration"
19735
19736         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19737         [ $stripe_count = 2 ] ||
19738                 error "dir strpe_count $d != 2 after migration."
19739
19740         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19741         [ $stripe_count = 2 ] ||
19742                 error "file strpe_count $d != 2 after migration."
19743
19744         #migrate back to MDT0
19745         MDTIDX=0
19746
19747         $LFS migrate -m $MDTIDX $migrate_dir ||
19748                 error "fails on migrating remote dir to MDT0"
19749
19750         echo "migrate back to MDT0, checking.."
19751         for file in $(find $migrate_dir); do
19752                 mdt_index=$($LFS getstripe -m $file)
19753                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19754                         error "$file is not on MDT${MDTIDX}"
19755         done
19756
19757         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19758         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19759                 error " expect $old_dir_flag get $new_dir_flag"
19760
19761         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19762         [ "$old_file_flag" = "$new_file_flag" ] ||
19763                 error " expect $old_file_flag get $new_file_flag"
19764
19765         local new_dir_mode=$(stat -c%f $migrate_dir)
19766         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19767                 error "expect mode $old_dir_mode get $new_dir_mode"
19768
19769         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19770         [ "$old_file_mode" = "$new_file_mode" ] ||
19771                 error "expect mode $old_file_mode get $new_file_mode"
19772
19773         diff /etc/passwd ${migrate_dir}/$tfile ||
19774                 error "$tfile different after migration"
19775
19776         diff /etc/passwd ${other_dir}/luna ||
19777                 error "luna different after migration"
19778
19779         diff /etc/passwd ${migrate_dir}/sofia ||
19780                 error "sofia different after migration"
19781
19782         diff /etc/passwd ${other_dir}/zachary ||
19783                 error "zachary different after migration"
19784
19785         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19786                 error "${tfile}_ln different after migration"
19787
19788         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19789                 error "${tfile}_ln_other different after migration"
19790
19791         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19792         [ $stripe_count = 2 ] ||
19793                 error "dir strpe_count $d != 2 after migration."
19794
19795         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19796         [ $stripe_count = 2 ] ||
19797                 error "file strpe_count $d != 2 after migration."
19798
19799         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19800 }
19801 run_test 230b "migrate directory"
19802
19803 test_230c() {
19804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19805         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19806         remote_mds_nodsh && skip "remote MDS with nodsh"
19807         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19808                 skip "Need MDS version at least 2.11.52"
19809
19810         local MDTIDX=1
19811         local total=3
19812         local mdt_index
19813         local file
19814         local migrate_dir=$DIR/$tdir/migrate_dir
19815
19816         #If migrating directory fails in the middle, all entries of
19817         #the directory is still accessiable.
19818         test_mkdir $DIR/$tdir
19819         test_mkdir -i0 -c1 $migrate_dir
19820         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19821         stat $migrate_dir
19822         createmany -o $migrate_dir/f $total ||
19823                 error "create files under ${migrate_dir} failed"
19824
19825         # fail after migrating top dir, and this will fail only once, so the
19826         # first sub file migration will fail (currently f3), others succeed.
19827         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19828         do_facet mds1 lctl set_param fail_loc=0x1801
19829         local t=$(ls $migrate_dir | wc -l)
19830         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19831                 error "migrate should fail"
19832         local u=$(ls $migrate_dir | wc -l)
19833         [ "$u" == "$t" ] || error "$u != $t during migration"
19834
19835         # add new dir/file should succeed
19836         mkdir $migrate_dir/dir ||
19837                 error "mkdir failed under migrating directory"
19838         touch $migrate_dir/file ||
19839                 error "create file failed under migrating directory"
19840
19841         # add file with existing name should fail
19842         for file in $migrate_dir/f*; do
19843                 stat $file > /dev/null || error "stat $file failed"
19844                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19845                         error "open(O_CREAT|O_EXCL) $file should fail"
19846                 $MULTIOP $file m && error "create $file should fail"
19847                 touch $DIR/$tdir/remote_dir/$tfile ||
19848                         error "touch $tfile failed"
19849                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19850                         error "link $file should fail"
19851                 mdt_index=$($LFS getstripe -m $file)
19852                 if [ $mdt_index == 0 ]; then
19853                         # file failed to migrate is not allowed to rename to
19854                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19855                                 error "rename to $file should fail"
19856                 else
19857                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19858                                 error "rename to $file failed"
19859                 fi
19860                 echo hello >> $file || error "write $file failed"
19861         done
19862
19863         # resume migration with different options should fail
19864         $LFS migrate -m 0 $migrate_dir &&
19865                 error "migrate -m 0 $migrate_dir should fail"
19866
19867         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19868                 error "migrate -c 2 $migrate_dir should fail"
19869
19870         # resume migration should succeed
19871         $LFS migrate -m $MDTIDX $migrate_dir ||
19872                 error "migrate $migrate_dir failed"
19873
19874         echo "Finish migration, then checking.."
19875         for file in $(find $migrate_dir); do
19876                 mdt_index=$($LFS getstripe -m $file)
19877                 [ $mdt_index == $MDTIDX ] ||
19878                         error "$file is not on MDT${MDTIDX}"
19879         done
19880
19881         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19882 }
19883 run_test 230c "check directory accessiblity if migration failed"
19884
19885 test_230d() {
19886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19887         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19888         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19889                 skip "Need MDS version at least 2.11.52"
19890         # LU-11235
19891         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19892
19893         local migrate_dir=$DIR/$tdir/migrate_dir
19894         local old_index
19895         local new_index
19896         local old_count
19897         local new_count
19898         local new_hash
19899         local mdt_index
19900         local i
19901         local j
19902
19903         old_index=$((RANDOM % MDSCOUNT))
19904         old_count=$((MDSCOUNT - old_index))
19905         new_index=$((RANDOM % MDSCOUNT))
19906         new_count=$((MDSCOUNT - new_index))
19907         new_hash=1 # for all_char
19908
19909         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19910         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19911
19912         test_mkdir $DIR/$tdir
19913         test_mkdir -i $old_index -c $old_count $migrate_dir
19914
19915         for ((i=0; i<100; i++)); do
19916                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19917                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19918                         error "create files under remote dir failed $i"
19919         done
19920
19921         echo -n "Migrate from MDT$old_index "
19922         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19923         echo -n "to MDT$new_index"
19924         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19925         echo
19926
19927         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19928         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19929                 error "migrate remote dir error"
19930
19931         echo "Finish migration, then checking.."
19932         for file in $(find $migrate_dir -maxdepth 1); do
19933                 mdt_index=$($LFS getstripe -m $file)
19934                 if [ $mdt_index -lt $new_index ] ||
19935                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19936                         error "$file is on MDT$mdt_index"
19937                 fi
19938         done
19939
19940         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19941 }
19942 run_test 230d "check migrate big directory"
19943
19944 test_230e() {
19945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19946         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19947         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19948                 skip "Need MDS version at least 2.11.52"
19949
19950         local i
19951         local j
19952         local a_fid
19953         local b_fid
19954
19955         mkdir_on_mdt0 $DIR/$tdir
19956         mkdir $DIR/$tdir/migrate_dir
19957         mkdir $DIR/$tdir/other_dir
19958         touch $DIR/$tdir/migrate_dir/a
19959         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19960         ls $DIR/$tdir/other_dir
19961
19962         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19963                 error "migrate dir fails"
19964
19965         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19966         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19967
19968         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19969         [ $mdt_index == 0 ] || error "a is not on MDT0"
19970
19971         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19972                 error "migrate dir fails"
19973
19974         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19975         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19976
19977         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19978         [ $mdt_index == 1 ] || error "a is not on MDT1"
19979
19980         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19981         [ $mdt_index == 1 ] || error "b is not on MDT1"
19982
19983         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19984         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19985
19986         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19987
19988         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19989 }
19990 run_test 230e "migrate mulitple local link files"
19991
19992 test_230f() {
19993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19994         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19995         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19996                 skip "Need MDS version at least 2.11.52"
19997
19998         local a_fid
19999         local ln_fid
20000
20001         mkdir -p $DIR/$tdir
20002         mkdir $DIR/$tdir/migrate_dir
20003         $LFS mkdir -i1 $DIR/$tdir/other_dir
20004         touch $DIR/$tdir/migrate_dir/a
20005         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20006         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20007         ls $DIR/$tdir/other_dir
20008
20009         # a should be migrated to MDT1, since no other links on MDT0
20010         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20011                 error "#1 migrate dir fails"
20012         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20013         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20014         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20015         [ $mdt_index == 1 ] || error "a is not on MDT1"
20016
20017         # a should stay on MDT1, because it is a mulitple link file
20018         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20019                 error "#2 migrate dir fails"
20020         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20021         [ $mdt_index == 1 ] || error "a is not on MDT1"
20022
20023         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20024                 error "#3 migrate dir fails"
20025
20026         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20027         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20028         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20029
20030         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20031         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20032
20033         # a should be migrated to MDT0, since no other links on MDT1
20034         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20035                 error "#4 migrate dir fails"
20036         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20037         [ $mdt_index == 0 ] || error "a is not on MDT0"
20038
20039         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20040 }
20041 run_test 230f "migrate mulitple remote link files"
20042
20043 test_230g() {
20044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20045         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20046         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20047                 skip "Need MDS version at least 2.11.52"
20048
20049         mkdir -p $DIR/$tdir/migrate_dir
20050
20051         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20052                 error "migrating dir to non-exist MDT succeeds"
20053         true
20054 }
20055 run_test 230g "migrate dir to non-exist MDT"
20056
20057 test_230h() {
20058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20059         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20060         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20061                 skip "Need MDS version at least 2.11.52"
20062
20063         local mdt_index
20064
20065         mkdir -p $DIR/$tdir/migrate_dir
20066
20067         $LFS migrate -m1 $DIR &&
20068                 error "migrating mountpoint1 should fail"
20069
20070         $LFS migrate -m1 $DIR/$tdir/.. &&
20071                 error "migrating mountpoint2 should fail"
20072
20073         # same as mv
20074         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20075                 error "migrating $tdir/migrate_dir/.. should fail"
20076
20077         true
20078 }
20079 run_test 230h "migrate .. and root"
20080
20081 test_230i() {
20082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20083         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20084         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20085                 skip "Need MDS version at least 2.11.52"
20086
20087         mkdir -p $DIR/$tdir/migrate_dir
20088
20089         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20090                 error "migration fails with a tailing slash"
20091
20092         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20093                 error "migration fails with two tailing slashes"
20094 }
20095 run_test 230i "lfs migrate -m tolerates trailing slashes"
20096
20097 test_230j() {
20098         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20099         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20100                 skip "Need MDS version at least 2.11.52"
20101
20102         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20103         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20104                 error "create $tfile failed"
20105         cat /etc/passwd > $DIR/$tdir/$tfile
20106
20107         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20108
20109         cmp /etc/passwd $DIR/$tdir/$tfile ||
20110                 error "DoM file mismatch after migration"
20111 }
20112 run_test 230j "DoM file data not changed after dir migration"
20113
20114 test_230k() {
20115         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20116         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20117                 skip "Need MDS version at least 2.11.56"
20118
20119         local total=20
20120         local files_on_starting_mdt=0
20121
20122         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20123         $LFS getdirstripe $DIR/$tdir
20124         for i in $(seq $total); do
20125                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20126                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20127                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20128         done
20129
20130         echo "$files_on_starting_mdt files on MDT0"
20131
20132         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20133         $LFS getdirstripe $DIR/$tdir
20134
20135         files_on_starting_mdt=0
20136         for i in $(seq $total); do
20137                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20138                         error "file $tfile.$i mismatch after migration"
20139                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20140                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20141         done
20142
20143         echo "$files_on_starting_mdt files on MDT1 after migration"
20144         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20145
20146         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20147         $LFS getdirstripe $DIR/$tdir
20148
20149         files_on_starting_mdt=0
20150         for i in $(seq $total); do
20151                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20152                         error "file $tfile.$i mismatch after 2nd migration"
20153                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20154                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20155         done
20156
20157         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20158         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20159
20160         true
20161 }
20162 run_test 230k "file data not changed after dir migration"
20163
20164 test_230l() {
20165         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20166         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20167                 skip "Need MDS version at least 2.11.56"
20168
20169         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20170         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20171                 error "create files under remote dir failed $i"
20172         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20173 }
20174 run_test 230l "readdir between MDTs won't crash"
20175
20176 test_230m() {
20177         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20178         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20179                 skip "Need MDS version at least 2.11.56"
20180
20181         local MDTIDX=1
20182         local mig_dir=$DIR/$tdir/migrate_dir
20183         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20184         local shortstr="b"
20185         local val
20186
20187         echo "Creating files and dirs with xattrs"
20188         test_mkdir $DIR/$tdir
20189         test_mkdir -i0 -c1 $mig_dir
20190         mkdir $mig_dir/dir
20191         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20192                 error "cannot set xattr attr1 on dir"
20193         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20194                 error "cannot set xattr attr2 on dir"
20195         touch $mig_dir/dir/f0
20196         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20197                 error "cannot set xattr attr1 on file"
20198         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20199                 error "cannot set xattr attr2 on file"
20200         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20201         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20202         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20203         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20204         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20205         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20206         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20207         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20208         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20209
20210         echo "Migrating to MDT1"
20211         $LFS migrate -m $MDTIDX $mig_dir ||
20212                 error "fails on migrating dir to MDT1"
20213
20214         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20215         echo "Checking xattrs"
20216         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20217         [ "$val" = $longstr ] ||
20218                 error "expecting xattr1 $longstr on dir, found $val"
20219         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20220         [ "$val" = $shortstr ] ||
20221                 error "expecting xattr2 $shortstr on dir, found $val"
20222         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20223         [ "$val" = $longstr ] ||
20224                 error "expecting xattr1 $longstr on file, found $val"
20225         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20226         [ "$val" = $shortstr ] ||
20227                 error "expecting xattr2 $shortstr on file, found $val"
20228 }
20229 run_test 230m "xattrs not changed after dir migration"
20230
20231 test_230n() {
20232         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20233         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20234                 skip "Need MDS version at least 2.13.53"
20235
20236         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20237         cat /etc/hosts > $DIR/$tdir/$tfile
20238         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20239         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20240
20241         cmp /etc/hosts $DIR/$tdir/$tfile ||
20242                 error "File data mismatch after migration"
20243 }
20244 run_test 230n "Dir migration with mirrored file"
20245
20246 test_230o() {
20247         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20248         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20249                 skip "Need MDS version at least 2.13.52"
20250
20251         local mdts=$(comma_list $(mdts_nodes))
20252         local timeout=100
20253         local restripe_status
20254         local delta
20255         local i
20256
20257         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20258
20259         # in case "crush" hash type is not set
20260         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20261
20262         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20263                            mdt.*MDT0000.enable_dir_restripe)
20264         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20265         stack_trap "do_nodes $mdts $LCTL set_param \
20266                     mdt.*.enable_dir_restripe=$restripe_status"
20267
20268         mkdir $DIR/$tdir
20269         createmany -m $DIR/$tdir/f 100 ||
20270                 error "create files under remote dir failed $i"
20271         createmany -d $DIR/$tdir/d 100 ||
20272                 error "create dirs under remote dir failed $i"
20273
20274         for i in $(seq 2 $MDSCOUNT); do
20275                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20276                 $LFS setdirstripe -c $i $DIR/$tdir ||
20277                         error "split -c $i $tdir failed"
20278                 wait_update $HOSTNAME \
20279                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20280                         error "dir split not finished"
20281                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20282                         awk '/migrate/ {sum += $2} END { print sum }')
20283                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20284                 # delta is around total_files/stripe_count
20285                 (( $delta < 200 / (i - 1) + 4 )) ||
20286                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20287         done
20288 }
20289 run_test 230o "dir split"
20290
20291 test_230p() {
20292         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20293         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20294                 skip "Need MDS version at least 2.13.52"
20295
20296         local mdts=$(comma_list $(mdts_nodes))
20297         local timeout=100
20298         local restripe_status
20299         local delta
20300         local c
20301
20302         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20303
20304         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20305
20306         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20307                            mdt.*MDT0000.enable_dir_restripe)
20308         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20309         stack_trap "do_nodes $mdts $LCTL set_param \
20310                     mdt.*.enable_dir_restripe=$restripe_status"
20311
20312         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20313         createmany -m $DIR/$tdir/f 100 ||
20314                 error "create files under remote dir failed"
20315         createmany -d $DIR/$tdir/d 100 ||
20316                 error "create dirs under remote dir failed"
20317
20318         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20319                 local mdt_hash="crush"
20320
20321                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20322                 $LFS setdirstripe -c $c $DIR/$tdir ||
20323                         error "split -c $c $tdir failed"
20324                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20325                         mdt_hash="$mdt_hash,fixed"
20326                 elif [ $c -eq 1 ]; then
20327                         mdt_hash="none"
20328                 fi
20329                 wait_update $HOSTNAME \
20330                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20331                         error "dir merge not finished"
20332                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20333                         awk '/migrate/ {sum += $2} END { print sum }')
20334                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20335                 # delta is around total_files/stripe_count
20336                 (( delta < 200 / c + 4 )) ||
20337                         error "$delta files migrated >= $((200 / c + 4))"
20338         done
20339 }
20340 run_test 230p "dir merge"
20341
20342 test_230q() {
20343         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20344         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20345                 skip "Need MDS version at least 2.13.52"
20346
20347         local mdts=$(comma_list $(mdts_nodes))
20348         local saved_threshold=$(do_facet mds1 \
20349                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20350         local saved_delta=$(do_facet mds1 \
20351                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20352         local threshold=100
20353         local delta=2
20354         local total=0
20355         local stripe_count=0
20356         local stripe_index
20357         local nr_files
20358         local create
20359
20360         # test with fewer files on ZFS
20361         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20362
20363         stack_trap "do_nodes $mdts $LCTL set_param \
20364                     mdt.*.dir_split_count=$saved_threshold"
20365         stack_trap "do_nodes $mdts $LCTL set_param \
20366                     mdt.*.dir_split_delta=$saved_delta"
20367         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20368         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20369         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20370         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20371         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20372         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20373
20374         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20375         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20376
20377         create=$((threshold * 3 / 2))
20378         while [ $stripe_count -lt $MDSCOUNT ]; do
20379                 createmany -m $DIR/$tdir/f $total $create ||
20380                         error "create sub files failed"
20381                 stat $DIR/$tdir > /dev/null
20382                 total=$((total + create))
20383                 stripe_count=$((stripe_count + delta))
20384                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20385
20386                 wait_update $HOSTNAME \
20387                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20388                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20389
20390                 wait_update $HOSTNAME \
20391                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20392                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20393
20394                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20395                 echo "$nr_files/$total files on MDT$stripe_index after split"
20396                 # allow 10% margin of imbalance with crush hash
20397                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20398                         error "$nr_files files on MDT$stripe_index after split"
20399
20400                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20401                 [ $nr_files -eq $total ] ||
20402                         error "total sub files $nr_files != $total"
20403         done
20404
20405         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20406
20407         echo "fixed layout directory won't auto split"
20408         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20409         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20410                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20411         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20412                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20413 }
20414 run_test 230q "dir auto split"
20415
20416 test_230r() {
20417         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20418         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20419         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20420                 skip "Need MDS version at least 2.13.54"
20421
20422         # maximum amount of local locks:
20423         # parent striped dir - 2 locks
20424         # new stripe in parent to migrate to - 1 lock
20425         # source and target - 2 locks
20426         # Total 5 locks for regular file
20427         mkdir -p $DIR/$tdir
20428         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20429         touch $DIR/$tdir/dir1/eee
20430
20431         # create 4 hardlink for 4 more locks
20432         # Total: 9 locks > RS_MAX_LOCKS (8)
20433         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20434         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20435         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20436         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20437         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20438         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20439         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20440         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20441
20442         cancel_lru_locks mdc
20443
20444         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20445                 error "migrate dir fails"
20446
20447         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20448 }
20449 run_test 230r "migrate with too many local locks"
20450
20451 test_230s() {
20452         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20453                 skip "Need MDS version at least 2.14.52"
20454
20455         local mdts=$(comma_list $(mdts_nodes))
20456         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20457                                 mdt.*MDT0000.enable_dir_restripe)
20458
20459         stack_trap "do_nodes $mdts $LCTL set_param \
20460                     mdt.*.enable_dir_restripe=$restripe_status"
20461
20462         local st
20463         for st in 0 1; do
20464                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20465                 test_mkdir $DIR/$tdir
20466                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20467                         error "$LFS mkdir should return EEXIST if target exists"
20468                 rmdir $DIR/$tdir
20469         done
20470 }
20471 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20472
20473 test_230t()
20474 {
20475         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20476         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20477                 skip "Need MDS version at least 2.14.50"
20478
20479         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20480         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20481         $LFS project -p 1 -s $DIR/$tdir ||
20482                 error "set $tdir project id failed"
20483         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20484                 error "set subdir project id failed"
20485         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20486 }
20487 run_test 230t "migrate directory with project ID set"
20488
20489 test_230u()
20490 {
20491         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20492         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20493                 skip "Need MDS version at least 2.14.53"
20494
20495         local count
20496
20497         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20498         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20499         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20500         for i in $(seq 0 $((MDSCOUNT - 1))); do
20501                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20502                 echo "$count dirs migrated to MDT$i"
20503         done
20504         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20505         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20506 }
20507 run_test 230u "migrate directory by QOS"
20508
20509 test_230v()
20510 {
20511         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20512         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20513                 skip "Need MDS version at least 2.14.53"
20514
20515         local count
20516
20517         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20518         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20519         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20520         for i in $(seq 0 $((MDSCOUNT - 1))); do
20521                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20522                 echo "$count subdirs migrated to MDT$i"
20523                 (( i == 3 )) && (( count > 0 )) &&
20524                         error "subdir shouldn't be migrated to MDT3"
20525         done
20526         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20527         (( count == 3 )) || error "dirs migrated to $count MDTs"
20528 }
20529 run_test 230v "subdir migrated to the MDT where its parent is located"
20530
20531 test_230w() {
20532         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20533         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20534                 skip "Need MDS version at least 2.14.53"
20535
20536         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20537
20538         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20539                 error "migrate failed"
20540
20541         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20542                 error "$tdir stripe count mismatch"
20543
20544         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20545                 error "$tdir/sub is striped"
20546 }
20547 run_test 230w "non-recursive mode dir migration"
20548
20549 test_231a()
20550 {
20551         # For simplicity this test assumes that max_pages_per_rpc
20552         # is the same across all OSCs
20553         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20554         local bulk_size=$((max_pages * PAGE_SIZE))
20555         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20556                                        head -n 1)
20557
20558         mkdir -p $DIR/$tdir
20559         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20560                 error "failed to set stripe with -S ${brw_size}M option"
20561
20562         # clear the OSC stats
20563         $LCTL set_param osc.*.stats=0 &>/dev/null
20564         stop_writeback
20565
20566         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20567         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20568                 oflag=direct &>/dev/null || error "dd failed"
20569
20570         sync; sleep 1; sync # just to be safe
20571         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20572         if [ x$nrpcs != "x1" ]; then
20573                 $LCTL get_param osc.*.stats
20574                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20575         fi
20576
20577         start_writeback
20578         # Drop the OSC cache, otherwise we will read from it
20579         cancel_lru_locks osc
20580
20581         # clear the OSC stats
20582         $LCTL set_param osc.*.stats=0 &>/dev/null
20583
20584         # Client reads $bulk_size.
20585         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20586                 iflag=direct &>/dev/null || error "dd failed"
20587
20588         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20589         if [ x$nrpcs != "x1" ]; then
20590                 $LCTL get_param osc.*.stats
20591                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20592         fi
20593 }
20594 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20595
20596 test_231b() {
20597         mkdir -p $DIR/$tdir
20598         local i
20599         for i in {0..1023}; do
20600                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20601                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20602                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20603         done
20604         sync
20605 }
20606 run_test 231b "must not assert on fully utilized OST request buffer"
20607
20608 test_232a() {
20609         mkdir -p $DIR/$tdir
20610         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20611
20612         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20613         do_facet ost1 $LCTL set_param fail_loc=0x31c
20614
20615         # ignore dd failure
20616         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20617
20618         do_facet ost1 $LCTL set_param fail_loc=0
20619         umount_client $MOUNT || error "umount failed"
20620         mount_client $MOUNT || error "mount failed"
20621         stop ost1 || error "cannot stop ost1"
20622         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20623 }
20624 run_test 232a "failed lock should not block umount"
20625
20626 test_232b() {
20627         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20628                 skip "Need MDS version at least 2.10.58"
20629
20630         mkdir -p $DIR/$tdir
20631         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20632         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20633         sync
20634         cancel_lru_locks osc
20635
20636         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20637         do_facet ost1 $LCTL set_param fail_loc=0x31c
20638
20639         # ignore failure
20640         $LFS data_version $DIR/$tdir/$tfile || true
20641
20642         do_facet ost1 $LCTL set_param fail_loc=0
20643         umount_client $MOUNT || error "umount failed"
20644         mount_client $MOUNT || error "mount failed"
20645         stop ost1 || error "cannot stop ost1"
20646         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20647 }
20648 run_test 232b "failed data version lock should not block umount"
20649
20650 test_233a() {
20651         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20652                 skip "Need MDS version at least 2.3.64"
20653         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20654
20655         local fid=$($LFS path2fid $MOUNT)
20656
20657         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20658                 error "cannot access $MOUNT using its FID '$fid'"
20659 }
20660 run_test 233a "checking that OBF of the FS root succeeds"
20661
20662 test_233b() {
20663         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20664                 skip "Need MDS version at least 2.5.90"
20665         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20666
20667         local fid=$($LFS path2fid $MOUNT/.lustre)
20668
20669         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20670                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20671
20672         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20673         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20674                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20675 }
20676 run_test 233b "checking that OBF of the FS .lustre succeeds"
20677
20678 test_234() {
20679         local p="$TMP/sanityN-$TESTNAME.parameters"
20680         save_lustre_params client "llite.*.xattr_cache" > $p
20681         lctl set_param llite.*.xattr_cache 1 ||
20682                 skip_env "xattr cache is not supported"
20683
20684         mkdir -p $DIR/$tdir || error "mkdir failed"
20685         touch $DIR/$tdir/$tfile || error "touch failed"
20686         # OBD_FAIL_LLITE_XATTR_ENOMEM
20687         $LCTL set_param fail_loc=0x1405
20688         getfattr -n user.attr $DIR/$tdir/$tfile &&
20689                 error "getfattr should have failed with ENOMEM"
20690         $LCTL set_param fail_loc=0x0
20691         rm -rf $DIR/$tdir
20692
20693         restore_lustre_params < $p
20694         rm -f $p
20695 }
20696 run_test 234 "xattr cache should not crash on ENOMEM"
20697
20698 test_235() {
20699         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20700                 skip "Need MDS version at least 2.4.52"
20701
20702         flock_deadlock $DIR/$tfile
20703         local RC=$?
20704         case $RC in
20705                 0)
20706                 ;;
20707                 124) error "process hangs on a deadlock"
20708                 ;;
20709                 *) error "error executing flock_deadlock $DIR/$tfile"
20710                 ;;
20711         esac
20712 }
20713 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20714
20715 #LU-2935
20716 test_236() {
20717         check_swap_layouts_support
20718
20719         local ref1=/etc/passwd
20720         local ref2=/etc/group
20721         local file1=$DIR/$tdir/f1
20722         local file2=$DIR/$tdir/f2
20723
20724         test_mkdir -c1 $DIR/$tdir
20725         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20726         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20727         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20728         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20729         local fd=$(free_fd)
20730         local cmd="exec $fd<>$file2"
20731         eval $cmd
20732         rm $file2
20733         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20734                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20735         cmd="exec $fd>&-"
20736         eval $cmd
20737         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20738
20739         #cleanup
20740         rm -rf $DIR/$tdir
20741 }
20742 run_test 236 "Layout swap on open unlinked file"
20743
20744 # LU-4659 linkea consistency
20745 test_238() {
20746         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20747                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20748                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20749                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20750
20751         touch $DIR/$tfile
20752         ln $DIR/$tfile $DIR/$tfile.lnk
20753         touch $DIR/$tfile.new
20754         mv $DIR/$tfile.new $DIR/$tfile
20755         local fid1=$($LFS path2fid $DIR/$tfile)
20756         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20757         local path1=$($LFS fid2path $FSNAME "$fid1")
20758         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20759         local path2=$($LFS fid2path $FSNAME "$fid2")
20760         [ $tfile.lnk == $path2 ] ||
20761                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20762         rm -f $DIR/$tfile*
20763 }
20764 run_test 238 "Verify linkea consistency"
20765
20766 test_239A() { # was test_239
20767         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20768                 skip "Need MDS version at least 2.5.60"
20769
20770         local list=$(comma_list $(mdts_nodes))
20771
20772         mkdir -p $DIR/$tdir
20773         createmany -o $DIR/$tdir/f- 5000
20774         unlinkmany $DIR/$tdir/f- 5000
20775         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20776                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20777         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20778                         osp.*MDT*.sync_in_flight" | calc_sum)
20779         [ "$changes" -eq 0 ] || error "$changes not synced"
20780 }
20781 run_test 239A "osp_sync test"
20782
20783 test_239a() { #LU-5297
20784         remote_mds_nodsh && skip "remote MDS with nodsh"
20785
20786         touch $DIR/$tfile
20787         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20788         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20789         chgrp $RUNAS_GID $DIR/$tfile
20790         wait_delete_completed
20791 }
20792 run_test 239a "process invalid osp sync record correctly"
20793
20794 test_239b() { #LU-5297
20795         remote_mds_nodsh && skip "remote MDS with nodsh"
20796
20797         touch $DIR/$tfile1
20798         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20799         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20800         chgrp $RUNAS_GID $DIR/$tfile1
20801         wait_delete_completed
20802         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20803         touch $DIR/$tfile2
20804         chgrp $RUNAS_GID $DIR/$tfile2
20805         wait_delete_completed
20806 }
20807 run_test 239b "process osp sync record with ENOMEM error correctly"
20808
20809 test_240() {
20810         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20811         remote_mds_nodsh && skip "remote MDS with nodsh"
20812
20813         mkdir -p $DIR/$tdir
20814
20815         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20816                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20817         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20818                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20819
20820         umount_client $MOUNT || error "umount failed"
20821         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20822         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20823         mount_client $MOUNT || error "failed to mount client"
20824
20825         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20826         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20827 }
20828 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20829
20830 test_241_bio() {
20831         local count=$1
20832         local bsize=$2
20833
20834         for LOOP in $(seq $count); do
20835                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20836                 cancel_lru_locks $OSC || true
20837         done
20838 }
20839
20840 test_241_dio() {
20841         local count=$1
20842         local bsize=$2
20843
20844         for LOOP in $(seq $1); do
20845                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20846                         2>/dev/null
20847         done
20848 }
20849
20850 test_241a() { # was test_241
20851         local bsize=$PAGE_SIZE
20852
20853         (( bsize < 40960 )) && bsize=40960
20854         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20855         ls -la $DIR/$tfile
20856         cancel_lru_locks $OSC
20857         test_241_bio 1000 $bsize &
20858         PID=$!
20859         test_241_dio 1000 $bsize
20860         wait $PID
20861 }
20862 run_test 241a "bio vs dio"
20863
20864 test_241b() {
20865         local bsize=$PAGE_SIZE
20866
20867         (( bsize < 40960 )) && bsize=40960
20868         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20869         ls -la $DIR/$tfile
20870         test_241_dio 1000 $bsize &
20871         PID=$!
20872         test_241_dio 1000 $bsize
20873         wait $PID
20874 }
20875 run_test 241b "dio vs dio"
20876
20877 test_242() {
20878         remote_mds_nodsh && skip "remote MDS with nodsh"
20879
20880         mkdir_on_mdt0 $DIR/$tdir
20881         touch $DIR/$tdir/$tfile
20882
20883         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20884         do_facet mds1 lctl set_param fail_loc=0x105
20885         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20886
20887         do_facet mds1 lctl set_param fail_loc=0
20888         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20889 }
20890 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20891
20892 test_243()
20893 {
20894         test_mkdir $DIR/$tdir
20895         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20896 }
20897 run_test 243 "various group lock tests"
20898
20899 test_244a()
20900 {
20901         test_mkdir $DIR/$tdir
20902         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20903         sendfile_grouplock $DIR/$tdir/$tfile || \
20904                 error "sendfile+grouplock failed"
20905         rm -rf $DIR/$tdir
20906 }
20907 run_test 244a "sendfile with group lock tests"
20908
20909 test_244b()
20910 {
20911         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20912
20913         local threads=50
20914         local size=$((1024*1024))
20915
20916         test_mkdir $DIR/$tdir
20917         for i in $(seq 1 $threads); do
20918                 local file=$DIR/$tdir/file_$((i / 10))
20919                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20920                 local pids[$i]=$!
20921         done
20922         for i in $(seq 1 $threads); do
20923                 wait ${pids[$i]}
20924         done
20925 }
20926 run_test 244b "multi-threaded write with group lock"
20927
20928 test_245() {
20929         local flagname="multi_mod_rpcs"
20930         local connect_data_name="max_mod_rpcs"
20931         local out
20932
20933         # check if multiple modify RPCs flag is set
20934         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20935                 grep "connect_flags:")
20936         echo "$out"
20937
20938         echo "$out" | grep -qw $flagname
20939         if [ $? -ne 0 ]; then
20940                 echo "connect flag $flagname is not set"
20941                 return
20942         fi
20943
20944         # check if multiple modify RPCs data is set
20945         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20946         echo "$out"
20947
20948         echo "$out" | grep -qw $connect_data_name ||
20949                 error "import should have connect data $connect_data_name"
20950 }
20951 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20952
20953 cleanup_247() {
20954         local submount=$1
20955
20956         trap 0
20957         umount_client $submount
20958         rmdir $submount
20959 }
20960
20961 test_247a() {
20962         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20963                 grep -q subtree ||
20964                 skip_env "Fileset feature is not supported"
20965
20966         local submount=${MOUNT}_$tdir
20967
20968         mkdir $MOUNT/$tdir
20969         mkdir -p $submount || error "mkdir $submount failed"
20970         FILESET="$FILESET/$tdir" mount_client $submount ||
20971                 error "mount $submount failed"
20972         trap "cleanup_247 $submount" EXIT
20973         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20974         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20975                 error "read $MOUNT/$tdir/$tfile failed"
20976         cleanup_247 $submount
20977 }
20978 run_test 247a "mount subdir as fileset"
20979
20980 test_247b() {
20981         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20982                 skip_env "Fileset feature is not supported"
20983
20984         local submount=${MOUNT}_$tdir
20985
20986         rm -rf $MOUNT/$tdir
20987         mkdir -p $submount || error "mkdir $submount failed"
20988         SKIP_FILESET=1
20989         FILESET="$FILESET/$tdir" mount_client $submount &&
20990                 error "mount $submount should fail"
20991         rmdir $submount
20992 }
20993 run_test 247b "mount subdir that dose not exist"
20994
20995 test_247c() {
20996         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20997                 skip_env "Fileset feature is not supported"
20998
20999         local submount=${MOUNT}_$tdir
21000
21001         mkdir -p $MOUNT/$tdir/dir1
21002         mkdir -p $submount || error "mkdir $submount failed"
21003         trap "cleanup_247 $submount" EXIT
21004         FILESET="$FILESET/$tdir" mount_client $submount ||
21005                 error "mount $submount failed"
21006         local fid=$($LFS path2fid $MOUNT/)
21007         $LFS fid2path $submount $fid && error "fid2path should fail"
21008         cleanup_247 $submount
21009 }
21010 run_test 247c "running fid2path outside subdirectory root"
21011
21012 test_247d() {
21013         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21014                 skip "Fileset feature is not supported"
21015
21016         local submount=${MOUNT}_$tdir
21017
21018         mkdir -p $MOUNT/$tdir/dir1
21019         mkdir -p $submount || error "mkdir $submount failed"
21020         FILESET="$FILESET/$tdir" mount_client $submount ||
21021                 error "mount $submount failed"
21022         trap "cleanup_247 $submount" EXIT
21023
21024         local td=$submount/dir1
21025         local fid=$($LFS path2fid $td)
21026         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21027
21028         # check that we get the same pathname back
21029         local rootpath
21030         local found
21031         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21032                 echo "$rootpath $fid"
21033                 found=$($LFS fid2path $rootpath "$fid")
21034                 [ -n "$found" ] || error "fid2path should succeed"
21035                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21036         done
21037         # check wrong root path format
21038         rootpath=$submount"_wrong"
21039         found=$($LFS fid2path $rootpath "$fid")
21040         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21041
21042         cleanup_247 $submount
21043 }
21044 run_test 247d "running fid2path inside subdirectory root"
21045
21046 # LU-8037
21047 test_247e() {
21048         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21049                 grep -q subtree ||
21050                 skip "Fileset feature is not supported"
21051
21052         local submount=${MOUNT}_$tdir
21053
21054         mkdir $MOUNT/$tdir
21055         mkdir -p $submount || error "mkdir $submount failed"
21056         FILESET="$FILESET/.." mount_client $submount &&
21057                 error "mount $submount should fail"
21058         rmdir $submount
21059 }
21060 run_test 247e "mount .. as fileset"
21061
21062 test_247f() {
21063         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21064         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21065                 skip "Need at least version 2.13.52"
21066         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21067                 skip "Need at least version 2.14.50"
21068         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21069                 grep -q subtree ||
21070                 skip "Fileset feature is not supported"
21071
21072         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21073         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21074                 error "mkdir remote failed"
21075         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21076                 error "mkdir remote/subdir failed"
21077         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21078                 error "mkdir striped failed"
21079         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21080
21081         local submount=${MOUNT}_$tdir
21082
21083         mkdir -p $submount || error "mkdir $submount failed"
21084         stack_trap "rmdir $submount"
21085
21086         local dir
21087         local stat
21088         local fileset=$FILESET
21089         local mdts=$(comma_list $(mdts_nodes))
21090
21091         stat=$(do_facet mds1 $LCTL get_param -n \
21092                 mdt.*MDT0000.enable_remote_subdir_mount)
21093         stack_trap "do_nodes $mdts $LCTL set_param \
21094                 mdt.*.enable_remote_subdir_mount=$stat"
21095
21096         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21097         stack_trap "umount_client $submount"
21098         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21099                 error "mount remote dir $dir should fail"
21100
21101         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21102                 $tdir/striped/. ; do
21103                 FILESET="$fileset/$dir" mount_client $submount ||
21104                         error "mount $dir failed"
21105                 umount_client $submount
21106         done
21107
21108         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21109         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21110                 error "mount $tdir/remote failed"
21111 }
21112 run_test 247f "mount striped or remote directory as fileset"
21113
21114 test_247g() {
21115         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21116         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21117                 skip "Need at least version 2.14.50"
21118
21119         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21120                 error "mkdir $tdir failed"
21121         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21122
21123         local submount=${MOUNT}_$tdir
21124
21125         mkdir -p $submount || error "mkdir $submount failed"
21126         stack_trap "rmdir $submount"
21127
21128         FILESET="$fileset/$tdir" mount_client $submount ||
21129                 error "mount $dir failed"
21130         stack_trap "umount $submount"
21131
21132         local mdts=$(comma_list $(mdts_nodes))
21133
21134         local nrpcs
21135
21136         stat $submount > /dev/null
21137         cancel_lru_locks $MDC
21138         stat $submount > /dev/null
21139         stat $submount/$tfile > /dev/null
21140         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21141         stat $submount/$tfile > /dev/null
21142         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21143                 awk '/getattr/ {sum += $2} END {print sum}')
21144
21145         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21146 }
21147 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21148
21149 test_248a() {
21150         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21151         [ -z "$fast_read_sav" ] && skip "no fast read support"
21152
21153         # create a large file for fast read verification
21154         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21155
21156         # make sure the file is created correctly
21157         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21158                 { rm -f $DIR/$tfile; skip "file creation error"; }
21159
21160         echo "Test 1: verify that fast read is 4 times faster on cache read"
21161
21162         # small read with fast read enabled
21163         $LCTL set_param -n llite.*.fast_read=1
21164         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21165                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21166                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21167         # small read with fast read disabled
21168         $LCTL set_param -n llite.*.fast_read=0
21169         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21170                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21171                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21172
21173         # verify that fast read is 4 times faster for cache read
21174         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21175                 error_not_in_vm "fast read was not 4 times faster: " \
21176                            "$t_fast vs $t_slow"
21177
21178         echo "Test 2: verify the performance between big and small read"
21179         $LCTL set_param -n llite.*.fast_read=1
21180
21181         # 1k non-cache read
21182         cancel_lru_locks osc
21183         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21184                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21185                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21186
21187         # 1M non-cache read
21188         cancel_lru_locks osc
21189         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21190                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21191                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21192
21193         # verify that big IO is not 4 times faster than small IO
21194         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21195                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21196
21197         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21198         rm -f $DIR/$tfile
21199 }
21200 run_test 248a "fast read verification"
21201
21202 test_248b() {
21203         # Default short_io_bytes=16384, try both smaller and larger sizes.
21204         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21205         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21206         echo "bs=53248 count=113 normal buffered write"
21207         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21208                 error "dd of initial data file failed"
21209         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21210
21211         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21212         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21213                 error "dd with sync normal writes failed"
21214         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21215
21216         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21217         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21218                 error "dd with sync small writes failed"
21219         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21220
21221         cancel_lru_locks osc
21222
21223         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21224         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21225         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21226         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21227                 iflag=direct || error "dd with O_DIRECT small read failed"
21228         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21229         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21230                 error "compare $TMP/$tfile.1 failed"
21231
21232         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21233         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21234
21235         # just to see what the maximum tunable value is, and test parsing
21236         echo "test invalid parameter 2MB"
21237         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21238                 error "too-large short_io_bytes allowed"
21239         echo "test maximum parameter 512KB"
21240         # if we can set a larger short_io_bytes, run test regardless of version
21241         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21242                 # older clients may not allow setting it this large, that's OK
21243                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21244                         skip "Need at least client version 2.13.50"
21245                 error "medium short_io_bytes failed"
21246         fi
21247         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21248         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21249
21250         echo "test large parameter 64KB"
21251         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21252         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21253
21254         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21255         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21256                 error "dd with sync large writes failed"
21257         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21258
21259         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21260         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21261         num=$((113 * 4096 / PAGE_SIZE))
21262         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21263         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21264                 error "dd with O_DIRECT large writes failed"
21265         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21266                 error "compare $DIR/$tfile.3 failed"
21267
21268         cancel_lru_locks osc
21269
21270         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21271         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21272                 error "dd with O_DIRECT large read failed"
21273         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21274                 error "compare $TMP/$tfile.2 failed"
21275
21276         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21277         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21278                 error "dd with O_DIRECT large read failed"
21279         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21280                 error "compare $TMP/$tfile.3 failed"
21281 }
21282 run_test 248b "test short_io read and write for both small and large sizes"
21283
21284 test_249() { # LU-7890
21285         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21286                 skip "Need at least version 2.8.54"
21287
21288         rm -f $DIR/$tfile
21289         $LFS setstripe -c 1 $DIR/$tfile
21290         # Offset 2T == 4k * 512M
21291         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21292                 error "dd to 2T offset failed"
21293 }
21294 run_test 249 "Write above 2T file size"
21295
21296 test_250() {
21297         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21298          && skip "no 16TB file size limit on ZFS"
21299
21300         $LFS setstripe -c 1 $DIR/$tfile
21301         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21302         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21303         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21304         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21305                 conv=notrunc,fsync && error "append succeeded"
21306         return 0
21307 }
21308 run_test 250 "Write above 16T limit"
21309
21310 test_251() {
21311         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21312
21313         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21314         #Skip once - writing the first stripe will succeed
21315         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21316         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21317                 error "short write happened"
21318
21319         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21320         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21321                 error "short read happened"
21322
21323         rm -f $DIR/$tfile
21324 }
21325 run_test 251 "Handling short read and write correctly"
21326
21327 test_252() {
21328         remote_mds_nodsh && skip "remote MDS with nodsh"
21329         remote_ost_nodsh && skip "remote OST with nodsh"
21330         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21331                 skip_env "ldiskfs only test"
21332         fi
21333
21334         local tgt
21335         local dev
21336         local out
21337         local uuid
21338         local num
21339         local gen
21340
21341         # check lr_reader on OST0000
21342         tgt=ost1
21343         dev=$(facet_device $tgt)
21344         out=$(do_facet $tgt $LR_READER $dev)
21345         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21346         echo "$out"
21347         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21348         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21349                 error "Invalid uuid returned by $LR_READER on target $tgt"
21350         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21351
21352         # check lr_reader -c on MDT0000
21353         tgt=mds1
21354         dev=$(facet_device $tgt)
21355         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21356                 skip "$LR_READER does not support additional options"
21357         fi
21358         out=$(do_facet $tgt $LR_READER -c $dev)
21359         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21360         echo "$out"
21361         num=$(echo "$out" | grep -c "mdtlov")
21362         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21363                 error "Invalid number of mdtlov clients returned by $LR_READER"
21364         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21365
21366         # check lr_reader -cr on MDT0000
21367         out=$(do_facet $tgt $LR_READER -cr $dev)
21368         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21369         echo "$out"
21370         echo "$out" | grep -q "^reply_data:$" ||
21371                 error "$LR_READER should have returned 'reply_data' section"
21372         num=$(echo "$out" | grep -c "client_generation")
21373         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21374 }
21375 run_test 252 "check lr_reader tool"
21376
21377 test_253() {
21378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21379         remote_mds_nodsh && skip "remote MDS with nodsh"
21380         remote_mgs_nodsh && skip "remote MGS with nodsh"
21381
21382         local ostidx=0
21383         local rc=0
21384         local ost_name=$(ostname_from_index $ostidx)
21385
21386         # on the mdt's osc
21387         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21388         do_facet $SINGLEMDS $LCTL get_param -n \
21389                 osp.$mdtosc_proc1.reserved_mb_high ||
21390                 skip  "remote MDS does not support reserved_mb_high"
21391
21392         rm -rf $DIR/$tdir
21393         wait_mds_ost_sync
21394         wait_delete_completed
21395         mkdir $DIR/$tdir
21396
21397         pool_add $TESTNAME || error "Pool creation failed"
21398         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21399
21400         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21401                 error "Setstripe failed"
21402
21403         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21404
21405         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21406                     grep "watermarks")
21407         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21408
21409         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21410                         osp.$mdtosc_proc1.prealloc_status)
21411         echo "prealloc_status $oa_status"
21412
21413         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21414                 error "File creation should fail"
21415
21416         #object allocation was stopped, but we still able to append files
21417         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21418                 oflag=append || error "Append failed"
21419
21420         rm -f $DIR/$tdir/$tfile.0
21421
21422         # For this test, we want to delete the files we created to go out of
21423         # space but leave the watermark, so we remain nearly out of space
21424         ost_watermarks_enospc_delete_files $tfile $ostidx
21425
21426         wait_delete_completed
21427
21428         sleep_maxage
21429
21430         for i in $(seq 10 12); do
21431                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21432                         2>/dev/null || error "File creation failed after rm"
21433         done
21434
21435         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21436                         osp.$mdtosc_proc1.prealloc_status)
21437         echo "prealloc_status $oa_status"
21438
21439         if (( oa_status != 0 )); then
21440                 error "Object allocation still disable after rm"
21441         fi
21442 }
21443 run_test 253 "Check object allocation limit"
21444
21445 test_254() {
21446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21447         remote_mds_nodsh && skip "remote MDS with nodsh"
21448
21449         local mdt=$(facet_svc $SINGLEMDS)
21450
21451         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21452                 skip "MDS does not support changelog_size"
21453
21454         local cl_user
21455
21456         changelog_register || error "changelog_register failed"
21457
21458         changelog_clear 0 || error "changelog_clear failed"
21459
21460         local size1=$(do_facet $SINGLEMDS \
21461                       $LCTL get_param -n mdd.$mdt.changelog_size)
21462         echo "Changelog size $size1"
21463
21464         rm -rf $DIR/$tdir
21465         $LFS mkdir -i 0 $DIR/$tdir
21466         # change something
21467         mkdir -p $DIR/$tdir/pics/2008/zachy
21468         touch $DIR/$tdir/pics/2008/zachy/timestamp
21469         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21470         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21471         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21472         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21473         rm $DIR/$tdir/pics/desktop.jpg
21474
21475         local size2=$(do_facet $SINGLEMDS \
21476                       $LCTL get_param -n mdd.$mdt.changelog_size)
21477         echo "Changelog size after work $size2"
21478
21479         (( $size2 > $size1 )) ||
21480                 error "new Changelog size=$size2 less than old size=$size1"
21481 }
21482 run_test 254 "Check changelog size"
21483
21484 ladvise_no_type()
21485 {
21486         local type=$1
21487         local file=$2
21488
21489         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21490                 awk -F: '{print $2}' | grep $type > /dev/null
21491         if [ $? -ne 0 ]; then
21492                 return 0
21493         fi
21494         return 1
21495 }
21496
21497 ladvise_no_ioctl()
21498 {
21499         local file=$1
21500
21501         lfs ladvise -a willread $file > /dev/null 2>&1
21502         if [ $? -eq 0 ]; then
21503                 return 1
21504         fi
21505
21506         lfs ladvise -a willread $file 2>&1 |
21507                 grep "Inappropriate ioctl for device" > /dev/null
21508         if [ $? -eq 0 ]; then
21509                 return 0
21510         fi
21511         return 1
21512 }
21513
21514 percent() {
21515         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21516 }
21517
21518 # run a random read IO workload
21519 # usage: random_read_iops <filename> <filesize> <iosize>
21520 random_read_iops() {
21521         local file=$1
21522         local fsize=$2
21523         local iosize=${3:-4096}
21524
21525         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21526                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21527 }
21528
21529 drop_file_oss_cache() {
21530         local file="$1"
21531         local nodes="$2"
21532
21533         $LFS ladvise -a dontneed $file 2>/dev/null ||
21534                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21535 }
21536
21537 ladvise_willread_performance()
21538 {
21539         local repeat=10
21540         local average_origin=0
21541         local average_cache=0
21542         local average_ladvise=0
21543
21544         for ((i = 1; i <= $repeat; i++)); do
21545                 echo "Iter $i/$repeat: reading without willread hint"
21546                 cancel_lru_locks osc
21547                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21548                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21549                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21550                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21551
21552                 cancel_lru_locks osc
21553                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21554                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21555                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21556
21557                 cancel_lru_locks osc
21558                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21559                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21560                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21561                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21562                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21563         done
21564         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21565         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21566         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21567
21568         speedup_cache=$(percent $average_cache $average_origin)
21569         speedup_ladvise=$(percent $average_ladvise $average_origin)
21570
21571         echo "Average uncached read: $average_origin"
21572         echo "Average speedup with OSS cached read: " \
21573                 "$average_cache = +$speedup_cache%"
21574         echo "Average speedup with ladvise willread: " \
21575                 "$average_ladvise = +$speedup_ladvise%"
21576
21577         local lowest_speedup=20
21578         if (( ${average_cache%.*} < $lowest_speedup )); then
21579                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21580                      " got $average_cache%. Skipping ladvise willread check."
21581                 return 0
21582         fi
21583
21584         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21585         # it is still good to run until then to exercise 'ladvise willread'
21586         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21587                 [ "$ost1_FSTYPE" = "zfs" ] &&
21588                 echo "osd-zfs does not support dontneed or drop_caches" &&
21589                 return 0
21590
21591         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21592         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21593                 error_not_in_vm "Speedup with willread is less than " \
21594                         "$lowest_speedup%, got $average_ladvise%"
21595 }
21596
21597 test_255a() {
21598         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21599                 skip "lustre < 2.8.54 does not support ladvise "
21600         remote_ost_nodsh && skip "remote OST with nodsh"
21601
21602         stack_trap "rm -f $DIR/$tfile"
21603         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21604
21605         ladvise_no_type willread $DIR/$tfile &&
21606                 skip "willread ladvise is not supported"
21607
21608         ladvise_no_ioctl $DIR/$tfile &&
21609                 skip "ladvise ioctl is not supported"
21610
21611         local size_mb=100
21612         local size=$((size_mb * 1048576))
21613         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21614                 error "dd to $DIR/$tfile failed"
21615
21616         lfs ladvise -a willread $DIR/$tfile ||
21617                 error "Ladvise failed with no range argument"
21618
21619         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21620                 error "Ladvise failed with no -l or -e argument"
21621
21622         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21623                 error "Ladvise failed with only -e argument"
21624
21625         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21626                 error "Ladvise failed with only -l argument"
21627
21628         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21629                 error "End offset should not be smaller than start offset"
21630
21631         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21632                 error "End offset should not be equal to start offset"
21633
21634         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21635                 error "Ladvise failed with overflowing -s argument"
21636
21637         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21638                 error "Ladvise failed with overflowing -e argument"
21639
21640         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21641                 error "Ladvise failed with overflowing -l argument"
21642
21643         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21644                 error "Ladvise succeeded with conflicting -l and -e arguments"
21645
21646         echo "Synchronous ladvise should wait"
21647         local delay=4
21648 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21649         do_nodes $(comma_list $(osts_nodes)) \
21650                 $LCTL set_param fail_val=$delay fail_loc=0x237
21651
21652         local start_ts=$SECONDS
21653         lfs ladvise -a willread $DIR/$tfile ||
21654                 error "Ladvise failed with no range argument"
21655         local end_ts=$SECONDS
21656         local inteval_ts=$((end_ts - start_ts))
21657
21658         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21659                 error "Synchronous advice didn't wait reply"
21660         fi
21661
21662         echo "Asynchronous ladvise shouldn't wait"
21663         local start_ts=$SECONDS
21664         lfs ladvise -a willread -b $DIR/$tfile ||
21665                 error "Ladvise failed with no range argument"
21666         local end_ts=$SECONDS
21667         local inteval_ts=$((end_ts - start_ts))
21668
21669         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21670                 error "Asynchronous advice blocked"
21671         fi
21672
21673         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21674         ladvise_willread_performance
21675 }
21676 run_test 255a "check 'lfs ladvise -a willread'"
21677
21678 facet_meminfo() {
21679         local facet=$1
21680         local info=$2
21681
21682         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21683 }
21684
21685 test_255b() {
21686         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21687                 skip "lustre < 2.8.54 does not support ladvise "
21688         remote_ost_nodsh && skip "remote OST with nodsh"
21689
21690         stack_trap "rm -f $DIR/$tfile"
21691         lfs setstripe -c 1 -i 0 $DIR/$tfile
21692
21693         ladvise_no_type dontneed $DIR/$tfile &&
21694                 skip "dontneed ladvise is not supported"
21695
21696         ladvise_no_ioctl $DIR/$tfile &&
21697                 skip "ladvise ioctl is not supported"
21698
21699         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21700                 [ "$ost1_FSTYPE" = "zfs" ] &&
21701                 skip "zfs-osd does not support 'ladvise dontneed'"
21702
21703         local size_mb=100
21704         local size=$((size_mb * 1048576))
21705         # In order to prevent disturbance of other processes, only check 3/4
21706         # of the memory usage
21707         local kibibytes=$((size_mb * 1024 * 3 / 4))
21708
21709         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21710                 error "dd to $DIR/$tfile failed"
21711
21712         #force write to complete before dropping OST cache & checking memory
21713         sync
21714
21715         local total=$(facet_meminfo ost1 MemTotal)
21716         echo "Total memory: $total KiB"
21717
21718         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21719         local before_read=$(facet_meminfo ost1 Cached)
21720         echo "Cache used before read: $before_read KiB"
21721
21722         lfs ladvise -a willread $DIR/$tfile ||
21723                 error "Ladvise willread failed"
21724         local after_read=$(facet_meminfo ost1 Cached)
21725         echo "Cache used after read: $after_read KiB"
21726
21727         lfs ladvise -a dontneed $DIR/$tfile ||
21728                 error "Ladvise dontneed again failed"
21729         local no_read=$(facet_meminfo ost1 Cached)
21730         echo "Cache used after dontneed ladvise: $no_read KiB"
21731
21732         if [ $total -lt $((before_read + kibibytes)) ]; then
21733                 echo "Memory is too small, abort checking"
21734                 return 0
21735         fi
21736
21737         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21738                 error "Ladvise willread should use more memory" \
21739                         "than $kibibytes KiB"
21740         fi
21741
21742         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21743                 error "Ladvise dontneed should release more memory" \
21744                         "than $kibibytes KiB"
21745         fi
21746 }
21747 run_test 255b "check 'lfs ladvise -a dontneed'"
21748
21749 test_255c() {
21750         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21751                 skip "lustre < 2.10.50 does not support lockahead"
21752
21753         local ost1_imp=$(get_osc_import_name client ost1)
21754         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21755                          cut -d'.' -f2)
21756         local count
21757         local new_count
21758         local difference
21759         local i
21760         local rc
21761
21762         test_mkdir -p $DIR/$tdir
21763         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21764
21765         #test 10 returns only success/failure
21766         i=10
21767         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21768         rc=$?
21769         if [ $rc -eq 255 ]; then
21770                 error "Ladvise test${i} failed, ${rc}"
21771         fi
21772
21773         #test 11 counts lock enqueue requests, all others count new locks
21774         i=11
21775         count=$(do_facet ost1 \
21776                 $LCTL get_param -n ost.OSS.ost.stats)
21777         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21778
21779         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21780         rc=$?
21781         if [ $rc -eq 255 ]; then
21782                 error "Ladvise test${i} failed, ${rc}"
21783         fi
21784
21785         new_count=$(do_facet ost1 \
21786                 $LCTL get_param -n ost.OSS.ost.stats)
21787         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21788                    awk '{ print $2 }')
21789
21790         difference="$((new_count - count))"
21791         if [ $difference -ne $rc ]; then
21792                 error "Ladvise test${i}, bad enqueue count, returned " \
21793                       "${rc}, actual ${difference}"
21794         fi
21795
21796         for i in $(seq 12 21); do
21797                 # If we do not do this, we run the risk of having too many
21798                 # locks and starting lock cancellation while we are checking
21799                 # lock counts.
21800                 cancel_lru_locks osc
21801
21802                 count=$($LCTL get_param -n \
21803                        ldlm.namespaces.$imp_name.lock_unused_count)
21804
21805                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21806                 rc=$?
21807                 if [ $rc -eq 255 ]; then
21808                         error "Ladvise test ${i} failed, ${rc}"
21809                 fi
21810
21811                 new_count=$($LCTL get_param -n \
21812                        ldlm.namespaces.$imp_name.lock_unused_count)
21813                 difference="$((new_count - count))"
21814
21815                 # Test 15 output is divided by 100 to map down to valid return
21816                 if [ $i -eq 15 ]; then
21817                         rc="$((rc * 100))"
21818                 fi
21819
21820                 if [ $difference -ne $rc ]; then
21821                         error "Ladvise test ${i}, bad lock count, returned " \
21822                               "${rc}, actual ${difference}"
21823                 fi
21824         done
21825
21826         #test 22 returns only success/failure
21827         i=22
21828         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21829         rc=$?
21830         if [ $rc -eq 255 ]; then
21831                 error "Ladvise test${i} failed, ${rc}"
21832         fi
21833 }
21834 run_test 255c "suite of ladvise lockahead tests"
21835
21836 test_256() {
21837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21838         remote_mds_nodsh && skip "remote MDS with nodsh"
21839         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21840         changelog_users $SINGLEMDS | grep "^cl" &&
21841                 skip "active changelog user"
21842
21843         local cl_user
21844         local cat_sl
21845         local mdt_dev
21846
21847         mdt_dev=$(facet_device $SINGLEMDS)
21848         echo $mdt_dev
21849
21850         changelog_register || error "changelog_register failed"
21851
21852         rm -rf $DIR/$tdir
21853         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
21854
21855         changelog_clear 0 || error "changelog_clear failed"
21856
21857         # change something
21858         touch $DIR/$tdir/{1..10}
21859
21860         # stop the MDT
21861         stop $SINGLEMDS || error "Fail to stop MDT"
21862
21863         # remount the MDT
21864         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21865                 error "Fail to start MDT"
21866
21867         #after mount new plainllog is used
21868         touch $DIR/$tdir/{11..19}
21869         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21870         stack_trap "rm -f $tmpfile"
21871         cat_sl=$(do_facet $SINGLEMDS "sync; \
21872                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21873                  llog_reader $tmpfile | grep -c type=1064553b")
21874         do_facet $SINGLEMDS llog_reader $tmpfile
21875
21876         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21877
21878         changelog_clear 0 || error "changelog_clear failed"
21879
21880         cat_sl=$(do_facet $SINGLEMDS "sync; \
21881                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21882                  llog_reader $tmpfile | grep -c type=1064553b")
21883
21884         if (( cat_sl == 2 )); then
21885                 error "Empty plain llog was not deleted from changelog catalog"
21886         elif (( cat_sl != 1 )); then
21887                 error "Active plain llog shouldn't be deleted from catalog"
21888         fi
21889 }
21890 run_test 256 "Check llog delete for empty and not full state"
21891
21892 test_257() {
21893         remote_mds_nodsh && skip "remote MDS with nodsh"
21894         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21895                 skip "Need MDS version at least 2.8.55"
21896
21897         test_mkdir $DIR/$tdir
21898
21899         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21900                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21901         stat $DIR/$tdir
21902
21903 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21904         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21905         local facet=mds$((mdtidx + 1))
21906         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21907         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21908
21909         stop $facet || error "stop MDS failed"
21910         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21911                 error "start MDS fail"
21912         wait_recovery_complete $facet
21913 }
21914 run_test 257 "xattr locks are not lost"
21915
21916 # Verify we take the i_mutex when security requires it
21917 test_258a() {
21918 #define OBD_FAIL_IMUTEX_SEC 0x141c
21919         $LCTL set_param fail_loc=0x141c
21920         touch $DIR/$tfile
21921         chmod u+s $DIR/$tfile
21922         chmod a+rwx $DIR/$tfile
21923         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21924         RC=$?
21925         if [ $RC -ne 0 ]; then
21926                 error "error, failed to take i_mutex, rc=$?"
21927         fi
21928         rm -f $DIR/$tfile
21929 }
21930 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21931
21932 # Verify we do NOT take the i_mutex in the normal case
21933 test_258b() {
21934 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21935         $LCTL set_param fail_loc=0x141d
21936         touch $DIR/$tfile
21937         chmod a+rwx $DIR
21938         chmod a+rw $DIR/$tfile
21939         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21940         RC=$?
21941         if [ $RC -ne 0 ]; then
21942                 error "error, took i_mutex unnecessarily, rc=$?"
21943         fi
21944         rm -f $DIR/$tfile
21945
21946 }
21947 run_test 258b "verify i_mutex security behavior"
21948
21949 test_259() {
21950         local file=$DIR/$tfile
21951         local before
21952         local after
21953
21954         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21955
21956         stack_trap "rm -f $file" EXIT
21957
21958         wait_delete_completed
21959         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21960         echo "before: $before"
21961
21962         $LFS setstripe -i 0 -c 1 $file
21963         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21964         sync_all_data
21965         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21966         echo "after write: $after"
21967
21968 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21969         do_facet ost1 $LCTL set_param fail_loc=0x2301
21970         $TRUNCATE $file 0
21971         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21972         echo "after truncate: $after"
21973
21974         stop ost1
21975         do_facet ost1 $LCTL set_param fail_loc=0
21976         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21977         sleep 2
21978         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21979         echo "after restart: $after"
21980         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21981                 error "missing truncate?"
21982
21983         return 0
21984 }
21985 run_test 259 "crash at delayed truncate"
21986
21987 test_260() {
21988 #define OBD_FAIL_MDC_CLOSE               0x806
21989         $LCTL set_param fail_loc=0x80000806
21990         touch $DIR/$tfile
21991
21992 }
21993 run_test 260 "Check mdc_close fail"
21994
21995 ### Data-on-MDT sanity tests ###
21996 test_270a() {
21997         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21998                 skip "Need MDS version at least 2.10.55 for DoM"
21999
22000         # create DoM file
22001         local dom=$DIR/$tdir/dom_file
22002         local tmp=$DIR/$tdir/tmp_file
22003
22004         mkdir_on_mdt0 $DIR/$tdir
22005
22006         # basic checks for DoM component creation
22007         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22008                 error "Can set MDT layout to non-first entry"
22009
22010         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22011                 error "Can define multiple entries as MDT layout"
22012
22013         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22014
22015         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22016         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22017         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22018
22019         local mdtidx=$($LFS getstripe -m $dom)
22020         local mdtname=MDT$(printf %04x $mdtidx)
22021         local facet=mds$((mdtidx + 1))
22022         local space_check=1
22023
22024         # Skip free space checks with ZFS
22025         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22026
22027         # write
22028         sync
22029         local size_tmp=$((65536 * 3))
22030         local mdtfree1=$(do_facet $facet \
22031                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22032
22033         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22034         # check also direct IO along write
22035         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22036         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22037         sync
22038         cmp $tmp $dom || error "file data is different"
22039         [ $(stat -c%s $dom) == $size_tmp ] ||
22040                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22041         if [ $space_check == 1 ]; then
22042                 local mdtfree2=$(do_facet $facet \
22043                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22044
22045                 # increase in usage from by $size_tmp
22046                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22047                         error "MDT free space wrong after write: " \
22048                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22049         fi
22050
22051         # truncate
22052         local size_dom=10000
22053
22054         $TRUNCATE $dom $size_dom
22055         [ $(stat -c%s $dom) == $size_dom ] ||
22056                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22057         if [ $space_check == 1 ]; then
22058                 mdtfree1=$(do_facet $facet \
22059                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22060                 # decrease in usage from $size_tmp to new $size_dom
22061                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22062                   $(((size_tmp - size_dom) / 1024)) ] ||
22063                         error "MDT free space is wrong after truncate: " \
22064                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22065         fi
22066
22067         # append
22068         cat $tmp >> $dom
22069         sync
22070         size_dom=$((size_dom + size_tmp))
22071         [ $(stat -c%s $dom) == $size_dom ] ||
22072                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22073         if [ $space_check == 1 ]; then
22074                 mdtfree2=$(do_facet $facet \
22075                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22076                 # increase in usage by $size_tmp from previous
22077                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22078                         error "MDT free space is wrong after append: " \
22079                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22080         fi
22081
22082         # delete
22083         rm $dom
22084         if [ $space_check == 1 ]; then
22085                 mdtfree1=$(do_facet $facet \
22086                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22087                 # decrease in usage by $size_dom from previous
22088                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22089                         error "MDT free space is wrong after removal: " \
22090                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22091         fi
22092
22093         # combined striping
22094         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22095                 error "Can't create DoM + OST striping"
22096
22097         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22098         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22099         # check also direct IO along write
22100         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22101         sync
22102         cmp $tmp $dom || error "file data is different"
22103         [ $(stat -c%s $dom) == $size_tmp ] ||
22104                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22105         rm $dom $tmp
22106
22107         return 0
22108 }
22109 run_test 270a "DoM: basic functionality tests"
22110
22111 test_270b() {
22112         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22113                 skip "Need MDS version at least 2.10.55"
22114
22115         local dom=$DIR/$tdir/dom_file
22116         local max_size=1048576
22117
22118         mkdir -p $DIR/$tdir
22119         $LFS setstripe -E $max_size -L mdt $dom
22120
22121         # truncate over the limit
22122         $TRUNCATE $dom $(($max_size + 1)) &&
22123                 error "successful truncate over the maximum size"
22124         # write over the limit
22125         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22126                 error "successful write over the maximum size"
22127         # append over the limit
22128         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22129         echo "12345" >> $dom && error "successful append over the maximum size"
22130         rm $dom
22131
22132         return 0
22133 }
22134 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22135
22136 test_270c() {
22137         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22138                 skip "Need MDS version at least 2.10.55"
22139
22140         mkdir -p $DIR/$tdir
22141         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22142
22143         # check files inherit DoM EA
22144         touch $DIR/$tdir/first
22145         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22146                 error "bad pattern"
22147         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22148                 error "bad stripe count"
22149         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22150                 error "bad stripe size"
22151
22152         # check directory inherits DoM EA and uses it as default
22153         mkdir $DIR/$tdir/subdir
22154         touch $DIR/$tdir/subdir/second
22155         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22156                 error "bad pattern in sub-directory"
22157         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22158                 error "bad stripe count in sub-directory"
22159         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22160                 error "bad stripe size in sub-directory"
22161         return 0
22162 }
22163 run_test 270c "DoM: DoM EA inheritance tests"
22164
22165 test_270d() {
22166         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22167                 skip "Need MDS version at least 2.10.55"
22168
22169         mkdir -p $DIR/$tdir
22170         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22171
22172         # inherit default DoM striping
22173         mkdir $DIR/$tdir/subdir
22174         touch $DIR/$tdir/subdir/f1
22175
22176         # change default directory striping
22177         $LFS setstripe -c 1 $DIR/$tdir/subdir
22178         touch $DIR/$tdir/subdir/f2
22179         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22180                 error "wrong default striping in file 2"
22181         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22182                 error "bad pattern in file 2"
22183         return 0
22184 }
22185 run_test 270d "DoM: change striping from DoM to RAID0"
22186
22187 test_270e() {
22188         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22189                 skip "Need MDS version at least 2.10.55"
22190
22191         mkdir -p $DIR/$tdir/dom
22192         mkdir -p $DIR/$tdir/norm
22193         DOMFILES=20
22194         NORMFILES=10
22195         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22196         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22197
22198         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22199         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22200
22201         # find DoM files by layout
22202         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22203         [ $NUM -eq  $DOMFILES ] ||
22204                 error "lfs find -L: found $NUM, expected $DOMFILES"
22205         echo "Test 1: lfs find 20 DOM files by layout: OK"
22206
22207         # there should be 1 dir with default DOM striping
22208         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22209         [ $NUM -eq  1 ] ||
22210                 error "lfs find -L: found $NUM, expected 1 dir"
22211         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22212
22213         # find DoM files by stripe size
22214         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22215         [ $NUM -eq  $DOMFILES ] ||
22216                 error "lfs find -S: found $NUM, expected $DOMFILES"
22217         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22218
22219         # find files by stripe offset except DoM files
22220         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22221         [ $NUM -eq  $NORMFILES ] ||
22222                 error "lfs find -i: found $NUM, expected $NORMFILES"
22223         echo "Test 5: lfs find no DOM files by stripe index: OK"
22224         return 0
22225 }
22226 run_test 270e "DoM: lfs find with DoM files test"
22227
22228 test_270f() {
22229         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22230                 skip "Need MDS version at least 2.10.55"
22231
22232         local mdtname=${FSNAME}-MDT0000-mdtlov
22233         local dom=$DIR/$tdir/dom_file
22234         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22235                                                 lod.$mdtname.dom_stripesize)
22236         local dom_limit=131072
22237
22238         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22239         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22240                                                 lod.$mdtname.dom_stripesize)
22241         [ ${dom_limit} -eq ${dom_current} ] ||
22242                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22243
22244         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22245         $LFS setstripe -d $DIR/$tdir
22246         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22247                 error "Can't set directory default striping"
22248
22249         # exceed maximum stripe size
22250         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22251                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22252         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22253                 error "Able to create DoM component size more than LOD limit"
22254
22255         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22256         dom_current=$(do_facet mds1 $LCTL get_param -n \
22257                                                 lod.$mdtname.dom_stripesize)
22258         [ 0 -eq ${dom_current} ] ||
22259                 error "Can't set zero DoM stripe limit"
22260         rm $dom
22261
22262         # attempt to create DoM file on server with disabled DoM should
22263         # remove DoM entry from layout and be succeed
22264         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22265                 error "Can't create DoM file (DoM is disabled)"
22266         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22267                 error "File has DoM component while DoM is disabled"
22268         rm $dom
22269
22270         # attempt to create DoM file with only DoM stripe should return error
22271         $LFS setstripe -E $dom_limit -L mdt $dom &&
22272                 error "Able to create DoM-only file while DoM is disabled"
22273
22274         # too low values to be aligned with smallest stripe size 64K
22275         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22276         dom_current=$(do_facet mds1 $LCTL get_param -n \
22277                                                 lod.$mdtname.dom_stripesize)
22278         [ 30000 -eq ${dom_current} ] &&
22279                 error "Can set too small DoM stripe limit"
22280
22281         # 64K is a minimal stripe size in Lustre, expect limit of that size
22282         [ 65536 -eq ${dom_current} ] ||
22283                 error "Limit is not set to 64K but ${dom_current}"
22284
22285         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22286         dom_current=$(do_facet mds1 $LCTL get_param -n \
22287                                                 lod.$mdtname.dom_stripesize)
22288         echo $dom_current
22289         [ 2147483648 -eq ${dom_current} ] &&
22290                 error "Can set too large DoM stripe limit"
22291
22292         do_facet mds1 $LCTL set_param -n \
22293                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22294         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22295                 error "Can't create DoM component size after limit change"
22296         do_facet mds1 $LCTL set_param -n \
22297                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22298         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22299                 error "Can't create DoM file after limit decrease"
22300         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22301                 error "Can create big DoM component after limit decrease"
22302         touch ${dom}_def ||
22303                 error "Can't create file with old default layout"
22304
22305         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22306         return 0
22307 }
22308 run_test 270f "DoM: maximum DoM stripe size checks"
22309
22310 test_270g() {
22311         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22312                 skip "Need MDS version at least 2.13.52"
22313         local dom=$DIR/$tdir/$tfile
22314
22315         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22316         local lodname=${FSNAME}-MDT0000-mdtlov
22317
22318         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22319         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22320         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22321         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22322
22323         local dom_limit=1024
22324         local dom_threshold="50%"
22325
22326         $LFS setstripe -d $DIR/$tdir
22327         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22328                 error "Can't set directory default striping"
22329
22330         do_facet mds1 $LCTL set_param -n \
22331                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22332         # set 0 threshold and create DOM file to change tunable stripesize
22333         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22334         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22335                 error "Failed to create $dom file"
22336         # now tunable dom_cur_stripesize should reach maximum
22337         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22338                                         lod.${lodname}.dom_stripesize_cur_kb)
22339         [[ $dom_current == $dom_limit ]] ||
22340                 error "Current DOM stripesize is not maximum"
22341         rm $dom
22342
22343         # set threshold for further tests
22344         do_facet mds1 $LCTL set_param -n \
22345                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22346         echo "DOM threshold is $dom_threshold free space"
22347         local dom_def
22348         local dom_set
22349         # Spoof bfree to exceed threshold
22350         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22351         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22352         for spfree in 40 20 0 15 30 55; do
22353                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22354                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22355                         error "Failed to create $dom file"
22356                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22357                                         lod.${lodname}.dom_stripesize_cur_kb)
22358                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22359                 [[ $dom_def != $dom_current ]] ||
22360                         error "Default stripe size was not changed"
22361                 if (( spfree > 0 )) ; then
22362                         dom_set=$($LFS getstripe -S $dom)
22363                         (( dom_set == dom_def * 1024 )) ||
22364                                 error "DOM component size is still old"
22365                 else
22366                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22367                                 error "DoM component is set with no free space"
22368                 fi
22369                 rm $dom
22370                 dom_current=$dom_def
22371         done
22372 }
22373 run_test 270g "DoM: default DoM stripe size depends on free space"
22374
22375 test_270h() {
22376         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22377                 skip "Need MDS version at least 2.13.53"
22378
22379         local mdtname=${FSNAME}-MDT0000-mdtlov
22380         local dom=$DIR/$tdir/$tfile
22381         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22382
22383         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22384         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22385
22386         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22387         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22388                 error "can't create OST file"
22389         # mirrored file with DOM entry in the second mirror
22390         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22391                 error "can't create mirror with DoM component"
22392
22393         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22394
22395         # DOM component in the middle and has other enries in the same mirror,
22396         # should succeed but lost DoM component
22397         $LFS setstripe --copy=${dom}_1 $dom ||
22398                 error "Can't create file from OST|DOM mirror layout"
22399         # check new file has no DoM layout after all
22400         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22401                 error "File has DoM component while DoM is disabled"
22402 }
22403 run_test 270h "DoM: DoM stripe removal when disabled on server"
22404
22405 test_270i() {
22406         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22407                 skip "Need MDS version at least 2.14.54"
22408
22409         mkdir $DIR/$tdir
22410         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22411                 error "setstripe should fail" || true
22412 }
22413 run_test 270i "DoM: setting invalid DoM striping should fail"
22414
22415 test_271a() {
22416         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22417                 skip "Need MDS version at least 2.10.55"
22418
22419         local dom=$DIR/$tdir/dom
22420
22421         mkdir -p $DIR/$tdir
22422
22423         $LFS setstripe -E 1024K -L mdt $dom
22424
22425         lctl set_param -n mdc.*.stats=clear
22426         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22427         cat $dom > /dev/null
22428         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22429         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22430         ls $dom
22431         rm -f $dom
22432 }
22433 run_test 271a "DoM: data is cached for read after write"
22434
22435 test_271b() {
22436         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22437                 skip "Need MDS version at least 2.10.55"
22438
22439         local dom=$DIR/$tdir/dom
22440
22441         mkdir -p $DIR/$tdir
22442
22443         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22444
22445         lctl set_param -n mdc.*.stats=clear
22446         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22447         cancel_lru_locks mdc
22448         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22449         # second stat to check size is cached on client
22450         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22451         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22452         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22453         rm -f $dom
22454 }
22455 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22456
22457 test_271ba() {
22458         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22459                 skip "Need MDS version at least 2.10.55"
22460
22461         local dom=$DIR/$tdir/dom
22462
22463         mkdir -p $DIR/$tdir
22464
22465         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22466
22467         lctl set_param -n mdc.*.stats=clear
22468         lctl set_param -n osc.*.stats=clear
22469         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22470         cancel_lru_locks mdc
22471         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22472         # second stat to check size is cached on client
22473         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22474         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22475         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22476         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22477         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22478         rm -f $dom
22479 }
22480 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22481
22482
22483 get_mdc_stats() {
22484         local mdtidx=$1
22485         local param=$2
22486         local mdt=MDT$(printf %04x $mdtidx)
22487
22488         if [ -z $param ]; then
22489                 lctl get_param -n mdc.*$mdt*.stats
22490         else
22491                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22492         fi
22493 }
22494
22495 test_271c() {
22496         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22497                 skip "Need MDS version at least 2.10.55"
22498
22499         local dom=$DIR/$tdir/dom
22500
22501         mkdir -p $DIR/$tdir
22502
22503         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22504
22505         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22506         local facet=mds$((mdtidx + 1))
22507
22508         cancel_lru_locks mdc
22509         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22510         createmany -o $dom 1000
22511         lctl set_param -n mdc.*.stats=clear
22512         smalliomany -w $dom 1000 200
22513         get_mdc_stats $mdtidx
22514         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22515         # Each file has 1 open, 1 IO enqueues, total 2000
22516         # but now we have also +1 getxattr for security.capability, total 3000
22517         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22518         unlinkmany $dom 1000
22519
22520         cancel_lru_locks mdc
22521         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22522         createmany -o $dom 1000
22523         lctl set_param -n mdc.*.stats=clear
22524         smalliomany -w $dom 1000 200
22525         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22526         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22527         # for OPEN and IO lock.
22528         [ $((enq - enq_2)) -ge 1000 ] ||
22529                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22530         unlinkmany $dom 1000
22531         return 0
22532 }
22533 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22534
22535 cleanup_271def_tests() {
22536         trap 0
22537         rm -f $1
22538 }
22539
22540 test_271d() {
22541         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22542                 skip "Need MDS version at least 2.10.57"
22543
22544         local dom=$DIR/$tdir/dom
22545         local tmp=$TMP/$tfile
22546         trap "cleanup_271def_tests $tmp" EXIT
22547
22548         mkdir -p $DIR/$tdir
22549
22550         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22551
22552         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22553
22554         cancel_lru_locks mdc
22555         dd if=/dev/urandom of=$tmp bs=1000 count=1
22556         dd if=$tmp of=$dom bs=1000 count=1
22557         cancel_lru_locks mdc
22558
22559         cat /etc/hosts >> $tmp
22560         lctl set_param -n mdc.*.stats=clear
22561
22562         # append data to the same file it should update local page
22563         echo "Append to the same page"
22564         cat /etc/hosts >> $dom
22565         local num=$(get_mdc_stats $mdtidx ost_read)
22566         local ra=$(get_mdc_stats $mdtidx req_active)
22567         local rw=$(get_mdc_stats $mdtidx req_waittime)
22568
22569         [ -z $num ] || error "$num READ RPC occured"
22570         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22571         echo "... DONE"
22572
22573         # compare content
22574         cmp $tmp $dom || error "file miscompare"
22575
22576         cancel_lru_locks mdc
22577         lctl set_param -n mdc.*.stats=clear
22578
22579         echo "Open and read file"
22580         cat $dom > /dev/null
22581         local num=$(get_mdc_stats $mdtidx ost_read)
22582         local ra=$(get_mdc_stats $mdtidx req_active)
22583         local rw=$(get_mdc_stats $mdtidx req_waittime)
22584
22585         [ -z $num ] || error "$num READ RPC occured"
22586         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22587         echo "... DONE"
22588
22589         # compare content
22590         cmp $tmp $dom || error "file miscompare"
22591
22592         return 0
22593 }
22594 run_test 271d "DoM: read on open (1K file in reply buffer)"
22595
22596 test_271f() {
22597         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22598                 skip "Need MDS version at least 2.10.57"
22599
22600         local dom=$DIR/$tdir/dom
22601         local tmp=$TMP/$tfile
22602         trap "cleanup_271def_tests $tmp" EXIT
22603
22604         mkdir -p $DIR/$tdir
22605
22606         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22607
22608         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22609
22610         cancel_lru_locks mdc
22611         dd if=/dev/urandom of=$tmp bs=265000 count=1
22612         dd if=$tmp of=$dom bs=265000 count=1
22613         cancel_lru_locks mdc
22614         cat /etc/hosts >> $tmp
22615         lctl set_param -n mdc.*.stats=clear
22616
22617         echo "Append to the same page"
22618         cat /etc/hosts >> $dom
22619         local num=$(get_mdc_stats $mdtidx ost_read)
22620         local ra=$(get_mdc_stats $mdtidx req_active)
22621         local rw=$(get_mdc_stats $mdtidx req_waittime)
22622
22623         [ -z $num ] || error "$num READ RPC occured"
22624         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22625         echo "... DONE"
22626
22627         # compare content
22628         cmp $tmp $dom || error "file miscompare"
22629
22630         cancel_lru_locks mdc
22631         lctl set_param -n mdc.*.stats=clear
22632
22633         echo "Open and read file"
22634         cat $dom > /dev/null
22635         local num=$(get_mdc_stats $mdtidx ost_read)
22636         local ra=$(get_mdc_stats $mdtidx req_active)
22637         local rw=$(get_mdc_stats $mdtidx req_waittime)
22638
22639         [ -z $num ] && num=0
22640         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22641         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22642         echo "... DONE"
22643
22644         # compare content
22645         cmp $tmp $dom || error "file miscompare"
22646
22647         return 0
22648 }
22649 run_test 271f "DoM: read on open (200K file and read tail)"
22650
22651 test_271g() {
22652         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22653                 skip "Skipping due to old client or server version"
22654
22655         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22656         # to get layout
22657         $CHECKSTAT -t file $DIR1/$tfile
22658
22659         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22660         MULTIOP_PID=$!
22661         sleep 1
22662         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22663         $LCTL set_param fail_loc=0x80000314
22664         rm $DIR1/$tfile || error "Unlink fails"
22665         RC=$?
22666         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22667         [ $RC -eq 0 ] || error "Failed write to stale object"
22668 }
22669 run_test 271g "Discard DoM data vs client flush race"
22670
22671 test_272a() {
22672         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22673                 skip "Need MDS version at least 2.11.50"
22674
22675         local dom=$DIR/$tdir/dom
22676         mkdir -p $DIR/$tdir
22677
22678         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22679         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22680                 error "failed to write data into $dom"
22681         local old_md5=$(md5sum $dom)
22682
22683         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22684                 error "failed to migrate to the same DoM component"
22685
22686         local new_md5=$(md5sum $dom)
22687
22688         [ "$old_md5" == "$new_md5" ] ||
22689                 error "md5sum differ: $old_md5, $new_md5"
22690
22691         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22692                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22693 }
22694 run_test 272a "DoM migration: new layout with the same DOM component"
22695
22696 test_272b() {
22697         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22698                 skip "Need MDS version at least 2.11.50"
22699
22700         local dom=$DIR/$tdir/dom
22701         mkdir -p $DIR/$tdir
22702         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22703
22704         local mdtidx=$($LFS getstripe -m $dom)
22705         local mdtname=MDT$(printf %04x $mdtidx)
22706         local facet=mds$((mdtidx + 1))
22707
22708         local mdtfree1=$(do_facet $facet \
22709                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22710         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22711                 error "failed to write data into $dom"
22712         local old_md5=$(md5sum $dom)
22713         cancel_lru_locks mdc
22714         local mdtfree1=$(do_facet $facet \
22715                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22716
22717         $LFS migrate -c2 $dom ||
22718                 error "failed to migrate to the new composite layout"
22719         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22720                 error "MDT stripe was not removed"
22721
22722         cancel_lru_locks mdc
22723         local new_md5=$(md5sum $dom)
22724         [ "$old_md5" == "$new_md5" ] ||
22725                 error "$old_md5 != $new_md5"
22726
22727         # Skip free space checks with ZFS
22728         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22729                 local mdtfree2=$(do_facet $facet \
22730                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22731                 [ $mdtfree2 -gt $mdtfree1 ] ||
22732                         error "MDT space is not freed after migration"
22733         fi
22734         return 0
22735 }
22736 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22737
22738 test_272c() {
22739         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22740                 skip "Need MDS version at least 2.11.50"
22741
22742         local dom=$DIR/$tdir/$tfile
22743         mkdir -p $DIR/$tdir
22744         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22745
22746         local mdtidx=$($LFS getstripe -m $dom)
22747         local mdtname=MDT$(printf %04x $mdtidx)
22748         local facet=mds$((mdtidx + 1))
22749
22750         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22751                 error "failed to write data into $dom"
22752         local old_md5=$(md5sum $dom)
22753         cancel_lru_locks mdc
22754         local mdtfree1=$(do_facet $facet \
22755                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22756
22757         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22758                 error "failed to migrate to the new composite layout"
22759         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22760                 error "MDT stripe was not removed"
22761
22762         cancel_lru_locks mdc
22763         local new_md5=$(md5sum $dom)
22764         [ "$old_md5" == "$new_md5" ] ||
22765                 error "$old_md5 != $new_md5"
22766
22767         # Skip free space checks with ZFS
22768         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22769                 local mdtfree2=$(do_facet $facet \
22770                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22771                 [ $mdtfree2 -gt $mdtfree1 ] ||
22772                         error "MDS space is not freed after migration"
22773         fi
22774         return 0
22775 }
22776 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22777
22778 test_272d() {
22779         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22780                 skip "Need MDS version at least 2.12.55"
22781
22782         local dom=$DIR/$tdir/$tfile
22783         mkdir -p $DIR/$tdir
22784         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22785
22786         local mdtidx=$($LFS getstripe -m $dom)
22787         local mdtname=MDT$(printf %04x $mdtidx)
22788         local facet=mds$((mdtidx + 1))
22789
22790         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22791                 error "failed to write data into $dom"
22792         local old_md5=$(md5sum $dom)
22793         cancel_lru_locks mdc
22794         local mdtfree1=$(do_facet $facet \
22795                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22796
22797         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22798                 error "failed mirroring to the new composite layout"
22799         $LFS mirror resync $dom ||
22800                 error "failed mirror resync"
22801         $LFS mirror split --mirror-id 1 -d $dom ||
22802                 error "failed mirror split"
22803
22804         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22805                 error "MDT stripe was not removed"
22806
22807         cancel_lru_locks mdc
22808         local new_md5=$(md5sum $dom)
22809         [ "$old_md5" == "$new_md5" ] ||
22810                 error "$old_md5 != $new_md5"
22811
22812         # Skip free space checks with ZFS
22813         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22814                 local mdtfree2=$(do_facet $facet \
22815                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22816                 [ $mdtfree2 -gt $mdtfree1 ] ||
22817                         error "MDS space is not freed after DOM mirror deletion"
22818         fi
22819         return 0
22820 }
22821 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22822
22823 test_272e() {
22824         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22825                 skip "Need MDS version at least 2.12.55"
22826
22827         local dom=$DIR/$tdir/$tfile
22828         mkdir -p $DIR/$tdir
22829         $LFS setstripe -c 2 $dom
22830
22831         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22832                 error "failed to write data into $dom"
22833         local old_md5=$(md5sum $dom)
22834         cancel_lru_locks
22835
22836         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22837                 error "failed mirroring to the DOM layout"
22838         $LFS mirror resync $dom ||
22839                 error "failed mirror resync"
22840         $LFS mirror split --mirror-id 1 -d $dom ||
22841                 error "failed mirror split"
22842
22843         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22844                 error "MDT stripe wasn't set"
22845
22846         cancel_lru_locks
22847         local new_md5=$(md5sum $dom)
22848         [ "$old_md5" == "$new_md5" ] ||
22849                 error "$old_md5 != $new_md5"
22850
22851         return 0
22852 }
22853 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22854
22855 test_272f() {
22856         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22857                 skip "Need MDS version at least 2.12.55"
22858
22859         local dom=$DIR/$tdir/$tfile
22860         mkdir -p $DIR/$tdir
22861         $LFS setstripe -c 2 $dom
22862
22863         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22864                 error "failed to write data into $dom"
22865         local old_md5=$(md5sum $dom)
22866         cancel_lru_locks
22867
22868         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22869                 error "failed migrating to the DOM file"
22870
22871         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22872                 error "MDT stripe wasn't set"
22873
22874         cancel_lru_locks
22875         local new_md5=$(md5sum $dom)
22876         [ "$old_md5" != "$new_md5" ] &&
22877                 error "$old_md5 != $new_md5"
22878
22879         return 0
22880 }
22881 run_test 272f "DoM migration: OST-striped file to DOM file"
22882
22883 test_273a() {
22884         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22885                 skip "Need MDS version at least 2.11.50"
22886
22887         # Layout swap cannot be done if either file has DOM component,
22888         # this will never be supported, migration should be used instead
22889
22890         local dom=$DIR/$tdir/$tfile
22891         mkdir -p $DIR/$tdir
22892
22893         $LFS setstripe -c2 ${dom}_plain
22894         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22895         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22896                 error "can swap layout with DoM component"
22897         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22898                 error "can swap layout with DoM component"
22899
22900         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22901         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22902                 error "can swap layout with DoM component"
22903         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22904                 error "can swap layout with DoM component"
22905         return 0
22906 }
22907 run_test 273a "DoM: layout swapping should fail with DOM"
22908
22909 test_273b() {
22910         mkdir -p $DIR/$tdir
22911         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22912
22913 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22914         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22915
22916         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22917 }
22918 run_test 273b "DoM: race writeback and object destroy"
22919
22920 test_275() {
22921         remote_ost_nodsh && skip "remote OST with nodsh"
22922         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22923                 skip "Need OST version >= 2.10.57"
22924
22925         local file=$DIR/$tfile
22926         local oss
22927
22928         oss=$(comma_list $(osts_nodes))
22929
22930         dd if=/dev/urandom of=$file bs=1M count=2 ||
22931                 error "failed to create a file"
22932         cancel_lru_locks osc
22933
22934         #lock 1
22935         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22936                 error "failed to read a file"
22937
22938 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22939         $LCTL set_param fail_loc=0x8000031f
22940
22941         cancel_lru_locks osc &
22942         sleep 1
22943
22944 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22945         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22946         #IO takes another lock, but matches the PENDING one
22947         #and places it to the IO RPC
22948         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22949                 error "failed to read a file with PENDING lock"
22950 }
22951 run_test 275 "Read on a canceled duplicate lock"
22952
22953 test_276() {
22954         remote_ost_nodsh && skip "remote OST with nodsh"
22955         local pid
22956
22957         do_facet ost1 "(while true; do \
22958                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22959                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22960         pid=$!
22961
22962         for LOOP in $(seq 20); do
22963                 stop ost1
22964                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22965         done
22966         kill -9 $pid
22967         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22968                 rm $TMP/sanity_276_pid"
22969 }
22970 run_test 276 "Race between mount and obd_statfs"
22971
22972 test_277() {
22973         $LCTL set_param ldlm.namespaces.*.lru_size=0
22974         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22975         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22976                         grep ^used_mb | awk '{print $2}')
22977         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22978         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22979                 oflag=direct conv=notrunc
22980         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22981                         grep ^used_mb | awk '{print $2}')
22982         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22983 }
22984 run_test 277 "Direct IO shall drop page cache"
22985
22986 test_278() {
22987         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22988         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22989         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22990                 skip "needs the same host for mdt1 mdt2" && return
22991
22992         local pid1
22993         local pid2
22994
22995 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22996         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22997         stop mds2 &
22998         pid2=$!
22999
23000         stop mds1
23001
23002         echo "Starting MDTs"
23003         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23004         wait $pid2
23005 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23006 #will return NULL
23007         do_facet mds2 $LCTL set_param fail_loc=0
23008
23009         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23010         wait_recovery_complete mds2
23011 }
23012 run_test 278 "Race starting MDS between MDTs stop/start"
23013
23014 test_280() {
23015         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23016                 skip "Need MGS version at least 2.13.52"
23017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23018         combined_mgs_mds || skip "needs combined MGS/MDT"
23019
23020         umount_client $MOUNT
23021 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23022         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23023
23024         mount_client $MOUNT &
23025         sleep 1
23026         stop mgs || error "stop mgs failed"
23027         #for a race mgs would crash
23028         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23029         # make sure we unmount client before remounting
23030         wait
23031         umount_client $MOUNT
23032         mount_client $MOUNT || error "mount client failed"
23033 }
23034 run_test 280 "Race between MGS umount and client llog processing"
23035
23036 cleanup_test_300() {
23037         trap 0
23038         umask $SAVE_UMASK
23039 }
23040 test_striped_dir() {
23041         local mdt_index=$1
23042         local stripe_count
23043         local stripe_index
23044
23045         mkdir -p $DIR/$tdir
23046
23047         SAVE_UMASK=$(umask)
23048         trap cleanup_test_300 RETURN EXIT
23049
23050         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23051                                                 $DIR/$tdir/striped_dir ||
23052                 error "set striped dir error"
23053
23054         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23055         [ "$mode" = "755" ] || error "expect 755 got $mode"
23056
23057         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23058                 error "getdirstripe failed"
23059         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23060         if [ "$stripe_count" != "2" ]; then
23061                 error "1:stripe_count is $stripe_count, expect 2"
23062         fi
23063         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23064         if [ "$stripe_count" != "2" ]; then
23065                 error "2:stripe_count is $stripe_count, expect 2"
23066         fi
23067
23068         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23069         if [ "$stripe_index" != "$mdt_index" ]; then
23070                 error "stripe_index is $stripe_index, expect $mdt_index"
23071         fi
23072
23073         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23074                 error "nlink error after create striped dir"
23075
23076         mkdir $DIR/$tdir/striped_dir/a
23077         mkdir $DIR/$tdir/striped_dir/b
23078
23079         stat $DIR/$tdir/striped_dir/a ||
23080                 error "create dir under striped dir failed"
23081         stat $DIR/$tdir/striped_dir/b ||
23082                 error "create dir under striped dir failed"
23083
23084         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23085                 error "nlink error after mkdir"
23086
23087         rmdir $DIR/$tdir/striped_dir/a
23088         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23089                 error "nlink error after rmdir"
23090
23091         rmdir $DIR/$tdir/striped_dir/b
23092         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23093                 error "nlink error after rmdir"
23094
23095         chattr +i $DIR/$tdir/striped_dir
23096         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23097                 error "immutable flags not working under striped dir!"
23098         chattr -i $DIR/$tdir/striped_dir
23099
23100         rmdir $DIR/$tdir/striped_dir ||
23101                 error "rmdir striped dir error"
23102
23103         cleanup_test_300
23104
23105         true
23106 }
23107
23108 test_300a() {
23109         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23110                 skip "skipped for lustre < 2.7.0"
23111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23112         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23113
23114         test_striped_dir 0 || error "failed on striped dir on MDT0"
23115         test_striped_dir 1 || error "failed on striped dir on MDT0"
23116 }
23117 run_test 300a "basic striped dir sanity test"
23118
23119 test_300b() {
23120         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23121                 skip "skipped for lustre < 2.7.0"
23122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23123         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23124
23125         local i
23126         local mtime1
23127         local mtime2
23128         local mtime3
23129
23130         test_mkdir $DIR/$tdir || error "mkdir fail"
23131         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23132                 error "set striped dir error"
23133         for i in {0..9}; do
23134                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23135                 sleep 1
23136                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23137                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23138                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23139                 sleep 1
23140                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23141                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23142                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23143         done
23144         true
23145 }
23146 run_test 300b "check ctime/mtime for striped dir"
23147
23148 test_300c() {
23149         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23150                 skip "skipped for lustre < 2.7.0"
23151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23152         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23153
23154         local file_count
23155
23156         mkdir_on_mdt0 $DIR/$tdir
23157         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23158                 error "set striped dir error"
23159
23160         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23161                 error "chown striped dir failed"
23162
23163         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23164                 error "create 5k files failed"
23165
23166         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23167
23168         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23169
23170         rm -rf $DIR/$tdir
23171 }
23172 run_test 300c "chown && check ls under striped directory"
23173
23174 test_300d() {
23175         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23176                 skip "skipped for lustre < 2.7.0"
23177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23178         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23179
23180         local stripe_count
23181         local file
23182
23183         mkdir -p $DIR/$tdir
23184         $LFS setstripe -c 2 $DIR/$tdir
23185
23186         #local striped directory
23187         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23188                 error "set striped dir error"
23189         #look at the directories for debug purposes
23190         ls -l $DIR/$tdir
23191         $LFS getdirstripe $DIR/$tdir
23192         ls -l $DIR/$tdir/striped_dir
23193         $LFS getdirstripe $DIR/$tdir/striped_dir
23194         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23195                 error "create 10 files failed"
23196
23197         #remote striped directory
23198         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23199                 error "set striped dir error"
23200         #look at the directories for debug purposes
23201         ls -l $DIR/$tdir
23202         $LFS getdirstripe $DIR/$tdir
23203         ls -l $DIR/$tdir/remote_striped_dir
23204         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23205         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23206                 error "create 10 files failed"
23207
23208         for file in $(find $DIR/$tdir); do
23209                 stripe_count=$($LFS getstripe -c $file)
23210                 [ $stripe_count -eq 2 ] ||
23211                         error "wrong stripe $stripe_count for $file"
23212         done
23213
23214         rm -rf $DIR/$tdir
23215 }
23216 run_test 300d "check default stripe under striped directory"
23217
23218 test_300e() {
23219         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23220                 skip "Need MDS version at least 2.7.55"
23221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23222         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23223
23224         local stripe_count
23225         local file
23226
23227         mkdir -p $DIR/$tdir
23228
23229         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23230                 error "set striped dir error"
23231
23232         touch $DIR/$tdir/striped_dir/a
23233         touch $DIR/$tdir/striped_dir/b
23234         touch $DIR/$tdir/striped_dir/c
23235
23236         mkdir $DIR/$tdir/striped_dir/dir_a
23237         mkdir $DIR/$tdir/striped_dir/dir_b
23238         mkdir $DIR/$tdir/striped_dir/dir_c
23239
23240         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23241                 error "set striped adir under striped dir error"
23242
23243         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23244                 error "set striped bdir under striped dir error"
23245
23246         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23247                 error "set striped cdir under striped dir error"
23248
23249         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23250                 error "rename dir under striped dir fails"
23251
23252         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23253                 error "rename dir under different stripes fails"
23254
23255         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23256                 error "rename file under striped dir should succeed"
23257
23258         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23259                 error "rename dir under striped dir should succeed"
23260
23261         rm -rf $DIR/$tdir
23262 }
23263 run_test 300e "check rename under striped directory"
23264
23265 test_300f() {
23266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23267         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23268         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23269                 skip "Need MDS version at least 2.7.55"
23270
23271         local stripe_count
23272         local file
23273
23274         rm -rf $DIR/$tdir
23275         mkdir -p $DIR/$tdir
23276
23277         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23278                 error "set striped dir error"
23279
23280         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23281                 error "set striped dir error"
23282
23283         touch $DIR/$tdir/striped_dir/a
23284         mkdir $DIR/$tdir/striped_dir/dir_a
23285         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23286                 error "create striped dir under striped dir fails"
23287
23288         touch $DIR/$tdir/striped_dir1/b
23289         mkdir $DIR/$tdir/striped_dir1/dir_b
23290         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23291                 error "create striped dir under striped dir fails"
23292
23293         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23294                 error "rename dir under different striped dir should fail"
23295
23296         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23297                 error "rename striped dir under diff striped dir should fail"
23298
23299         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23300                 error "rename file under diff striped dirs fails"
23301
23302         rm -rf $DIR/$tdir
23303 }
23304 run_test 300f "check rename cross striped directory"
23305
23306 test_300_check_default_striped_dir()
23307 {
23308         local dirname=$1
23309         local default_count=$2
23310         local default_index=$3
23311         local stripe_count
23312         local stripe_index
23313         local dir_stripe_index
23314         local dir
23315
23316         echo "checking $dirname $default_count $default_index"
23317         $LFS setdirstripe -D -c $default_count -i $default_index \
23318                                 -H all_char $DIR/$tdir/$dirname ||
23319                 error "set default stripe on striped dir error"
23320         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23321         [ $stripe_count -eq $default_count ] ||
23322                 error "expect $default_count get $stripe_count for $dirname"
23323
23324         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23325         [ $stripe_index -eq $default_index ] ||
23326                 error "expect $default_index get $stripe_index for $dirname"
23327
23328         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23329                                                 error "create dirs failed"
23330
23331         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23332         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23333         for dir in $(find $DIR/$tdir/$dirname/*); do
23334                 stripe_count=$($LFS getdirstripe -c $dir)
23335                 (( $stripe_count == $default_count )) ||
23336                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23337                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23338                 error "stripe count $default_count != $stripe_count for $dir"
23339
23340                 stripe_index=$($LFS getdirstripe -i $dir)
23341                 [ $default_index -eq -1 ] ||
23342                         [ $stripe_index -eq $default_index ] ||
23343                         error "$stripe_index != $default_index for $dir"
23344
23345                 #check default stripe
23346                 stripe_count=$($LFS getdirstripe -D -c $dir)
23347                 [ $stripe_count -eq $default_count ] ||
23348                 error "default count $default_count != $stripe_count for $dir"
23349
23350                 stripe_index=$($LFS getdirstripe -D -i $dir)
23351                 [ $stripe_index -eq $default_index ] ||
23352                 error "default index $default_index != $stripe_index for $dir"
23353         done
23354         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23355 }
23356
23357 test_300g() {
23358         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23359         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23360                 skip "Need MDS version at least 2.7.55"
23361
23362         local dir
23363         local stripe_count
23364         local stripe_index
23365
23366         mkdir_on_mdt0 $DIR/$tdir
23367         mkdir $DIR/$tdir/normal_dir
23368
23369         #Checking when client cache stripe index
23370         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23371         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23372                 error "create striped_dir failed"
23373
23374         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23375                 error "create dir0 fails"
23376         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23377         [ $stripe_index -eq 0 ] ||
23378                 error "dir0 expect index 0 got $stripe_index"
23379
23380         mkdir $DIR/$tdir/striped_dir/dir1 ||
23381                 error "create dir1 fails"
23382         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23383         [ $stripe_index -eq 1 ] ||
23384                 error "dir1 expect index 1 got $stripe_index"
23385
23386         #check default stripe count/stripe index
23387         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23388         test_300_check_default_striped_dir normal_dir 1 0
23389         test_300_check_default_striped_dir normal_dir -1 1
23390         test_300_check_default_striped_dir normal_dir 2 -1
23391
23392         #delete default stripe information
23393         echo "delete default stripeEA"
23394         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23395                 error "set default stripe on striped dir error"
23396
23397         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23398         for dir in $(find $DIR/$tdir/normal_dir/*); do
23399                 stripe_count=$($LFS getdirstripe -c $dir)
23400                 [ $stripe_count -eq 0 ] ||
23401                         error "expect 1 get $stripe_count for $dir"
23402         done
23403 }
23404 run_test 300g "check default striped directory for normal directory"
23405
23406 test_300h() {
23407         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23408         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23409                 skip "Need MDS version at least 2.7.55"
23410
23411         local dir
23412         local stripe_count
23413
23414         mkdir $DIR/$tdir
23415         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23416                 error "set striped dir error"
23417
23418         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23419         test_300_check_default_striped_dir striped_dir 1 0
23420         test_300_check_default_striped_dir striped_dir -1 1
23421         test_300_check_default_striped_dir striped_dir 2 -1
23422
23423         #delete default stripe information
23424         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23425                 error "set default stripe on striped dir error"
23426
23427         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23428         for dir in $(find $DIR/$tdir/striped_dir/*); do
23429                 stripe_count=$($LFS getdirstripe -c $dir)
23430                 [ $stripe_count -eq 0 ] ||
23431                         error "expect 1 get $stripe_count for $dir"
23432         done
23433 }
23434 run_test 300h "check default striped directory for striped directory"
23435
23436 test_300i() {
23437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23438         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23439         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23440                 skip "Need MDS version at least 2.7.55"
23441
23442         local stripe_count
23443         local file
23444
23445         mkdir $DIR/$tdir
23446
23447         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23448                 error "set striped dir error"
23449
23450         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23451                 error "create files under striped dir failed"
23452
23453         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23454                 error "set striped hashdir error"
23455
23456         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23457                 error "create dir0 under hash dir failed"
23458         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23459                 error "create dir1 under hash dir failed"
23460         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23461                 error "create dir2 under hash dir failed"
23462
23463         # unfortunately, we need to umount to clear dir layout cache for now
23464         # once we fully implement dir layout, we can drop this
23465         umount_client $MOUNT || error "umount failed"
23466         mount_client $MOUNT || error "mount failed"
23467
23468         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23469         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23470         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23471
23472         #set the stripe to be unknown hash type
23473         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23474         $LCTL set_param fail_loc=0x1901
23475         for ((i = 0; i < 10; i++)); do
23476                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23477                         error "stat f-$i failed"
23478                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23479         done
23480
23481         touch $DIR/$tdir/striped_dir/f0 &&
23482                 error "create under striped dir with unknown hash should fail"
23483
23484         $LCTL set_param fail_loc=0
23485
23486         umount_client $MOUNT || error "umount failed"
23487         mount_client $MOUNT || error "mount failed"
23488
23489         return 0
23490 }
23491 run_test 300i "client handle unknown hash type striped directory"
23492
23493 test_300j() {
23494         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23496         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23497                 skip "Need MDS version at least 2.7.55"
23498
23499         local stripe_count
23500         local file
23501
23502         mkdir $DIR/$tdir
23503
23504         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23505         $LCTL set_param fail_loc=0x1702
23506         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23507                 error "set striped dir error"
23508
23509         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23510                 error "create files under striped dir failed"
23511
23512         $LCTL set_param fail_loc=0
23513
23514         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23515
23516         return 0
23517 }
23518 run_test 300j "test large update record"
23519
23520 test_300k() {
23521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23522         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23523         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23524                 skip "Need MDS version at least 2.7.55"
23525
23526         # this test needs a huge transaction
23527         local kb
23528         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23529              osd*.$FSNAME-MDT0000.kbytestotal")
23530         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23531
23532         local stripe_count
23533         local file
23534
23535         mkdir $DIR/$tdir
23536
23537         #define OBD_FAIL_LARGE_STRIPE   0x1703
23538         $LCTL set_param fail_loc=0x1703
23539         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23540                 error "set striped dir error"
23541         $LCTL set_param fail_loc=0
23542
23543         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23544                 error "getstripeddir fails"
23545         rm -rf $DIR/$tdir/striped_dir ||
23546                 error "unlink striped dir fails"
23547
23548         return 0
23549 }
23550 run_test 300k "test large striped directory"
23551
23552 test_300l() {
23553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23554         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23555         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23556                 skip "Need MDS version at least 2.7.55"
23557
23558         local stripe_index
23559
23560         test_mkdir -p $DIR/$tdir/striped_dir
23561         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23562                         error "chown $RUNAS_ID failed"
23563         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23564                 error "set default striped dir failed"
23565
23566         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23567         $LCTL set_param fail_loc=0x80000158
23568         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23569
23570         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23571         [ $stripe_index -eq 1 ] ||
23572                 error "expect 1 get $stripe_index for $dir"
23573 }
23574 run_test 300l "non-root user to create dir under striped dir with stale layout"
23575
23576 test_300m() {
23577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23578         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23579         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23580                 skip "Need MDS version at least 2.7.55"
23581
23582         mkdir -p $DIR/$tdir/striped_dir
23583         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23584                 error "set default stripes dir error"
23585
23586         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23587
23588         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23589         [ $stripe_count -eq 0 ] ||
23590                         error "expect 0 get $stripe_count for a"
23591
23592         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23593                 error "set default stripes dir error"
23594
23595         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23596
23597         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23598         [ $stripe_count -eq 0 ] ||
23599                         error "expect 0 get $stripe_count for b"
23600
23601         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23602                 error "set default stripes dir error"
23603
23604         mkdir $DIR/$tdir/striped_dir/c &&
23605                 error "default stripe_index is invalid, mkdir c should fails"
23606
23607         rm -rf $DIR/$tdir || error "rmdir fails"
23608 }
23609 run_test 300m "setstriped directory on single MDT FS"
23610
23611 cleanup_300n() {
23612         local list=$(comma_list $(mdts_nodes))
23613
23614         trap 0
23615         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23616 }
23617
23618 test_300n() {
23619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23620         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23621         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23622                 skip "Need MDS version at least 2.7.55"
23623         remote_mds_nodsh && skip "remote MDS with nodsh"
23624
23625         local stripe_index
23626         local list=$(comma_list $(mdts_nodes))
23627
23628         trap cleanup_300n RETURN EXIT
23629         mkdir -p $DIR/$tdir
23630         chmod 777 $DIR/$tdir
23631         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23632                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23633                 error "create striped dir succeeds with gid=0"
23634
23635         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23636         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23637                 error "create striped dir fails with gid=-1"
23638
23639         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23640         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23641                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23642                 error "set default striped dir succeeds with gid=0"
23643
23644
23645         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23646         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23647                 error "set default striped dir fails with gid=-1"
23648
23649
23650         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23651         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23652                                         error "create test_dir fails"
23653         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23654                                         error "create test_dir1 fails"
23655         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23656                                         error "create test_dir2 fails"
23657         cleanup_300n
23658 }
23659 run_test 300n "non-root user to create dir under striped dir with default EA"
23660
23661 test_300o() {
23662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23663         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23664         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23665                 skip "Need MDS version at least 2.7.55"
23666
23667         local numfree1
23668         local numfree2
23669
23670         mkdir -p $DIR/$tdir
23671
23672         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23673         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23674         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23675                 skip "not enough free inodes $numfree1 $numfree2"
23676         fi
23677
23678         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23679         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23680         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23681                 skip "not enough free space $numfree1 $numfree2"
23682         fi
23683
23684         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23685                 error "setdirstripe fails"
23686
23687         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23688                 error "create dirs fails"
23689
23690         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23691         ls $DIR/$tdir/striped_dir > /dev/null ||
23692                 error "ls striped dir fails"
23693         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23694                 error "unlink big striped dir fails"
23695 }
23696 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23697
23698 test_300p() {
23699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23700         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23701         remote_mds_nodsh && skip "remote MDS with nodsh"
23702
23703         mkdir_on_mdt0 $DIR/$tdir
23704
23705         #define OBD_FAIL_OUT_ENOSPC     0x1704
23706         do_facet mds2 lctl set_param fail_loc=0x80001704
23707         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23708                  && error "create striped directory should fail"
23709
23710         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23711
23712         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23713         true
23714 }
23715 run_test 300p "create striped directory without space"
23716
23717 test_300q() {
23718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23719         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23720
23721         local fd=$(free_fd)
23722         local cmd="exec $fd<$tdir"
23723         cd $DIR
23724         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23725         eval $cmd
23726         cmd="exec $fd<&-"
23727         trap "eval $cmd" EXIT
23728         cd $tdir || error "cd $tdir fails"
23729         rmdir  ../$tdir || error "rmdir $tdir fails"
23730         mkdir local_dir && error "create dir succeeds"
23731         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23732         eval $cmd
23733         return 0
23734 }
23735 run_test 300q "create remote directory under orphan directory"
23736
23737 test_300r() {
23738         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23739                 skip "Need MDS version at least 2.7.55" && return
23740         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23741
23742         mkdir $DIR/$tdir
23743
23744         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23745                 error "set striped dir error"
23746
23747         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23748                 error "getstripeddir fails"
23749
23750         local stripe_count
23751         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23752                       awk '/lmv_stripe_count:/ { print $2 }')
23753
23754         [ $MDSCOUNT -ne $stripe_count ] &&
23755                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23756
23757         rm -rf $DIR/$tdir/striped_dir ||
23758                 error "unlink striped dir fails"
23759 }
23760 run_test 300r "test -1 striped directory"
23761
23762 test_300s_helper() {
23763         local count=$1
23764
23765         local stripe_dir=$DIR/$tdir/striped_dir.$count
23766
23767         $LFS mkdir -c $count $stripe_dir ||
23768                 error "lfs mkdir -c error"
23769
23770         $LFS getdirstripe $stripe_dir ||
23771                 error "lfs getdirstripe fails"
23772
23773         local stripe_count
23774         stripe_count=$($LFS getdirstripe $stripe_dir |
23775                       awk '/lmv_stripe_count:/ { print $2 }')
23776
23777         [ $count -ne $stripe_count ] &&
23778                 error_noexit "bad stripe count $stripe_count expected $count"
23779
23780         local dupe_stripes
23781         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23782                 awk '/0x/ {count[$1] += 1}; END {
23783                         for (idx in count) {
23784                                 if (count[idx]>1) {
23785                                         print "index " idx " count " count[idx]
23786                                 }
23787                         }
23788                 }')
23789
23790         if [[ -n "$dupe_stripes" ]] ; then
23791                 lfs getdirstripe $stripe_dir
23792                 error_noexit "Dupe MDT above: $dupe_stripes "
23793         fi
23794
23795         rm -rf $stripe_dir ||
23796                 error_noexit "unlink $stripe_dir fails"
23797 }
23798
23799 test_300s() {
23800         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23801                 skip "Need MDS version at least 2.7.55" && return
23802         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23803
23804         mkdir $DIR/$tdir
23805         for count in $(seq 2 $MDSCOUNT); do
23806                 test_300s_helper $count
23807         done
23808 }
23809 run_test 300s "test lfs mkdir -c without -i"
23810
23811 test_300t() {
23812         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
23813                 skip "need MDS 2.14.55 or later"
23814         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
23815
23816         local testdir="$DIR/$tdir/striped_dir"
23817         local dir1=$testdir/dir1
23818         local dir2=$testdir/dir2
23819
23820         mkdir -p $testdir
23821
23822         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
23823                 error "failed to set default stripe count for $testdir"
23824
23825         mkdir $dir1
23826         local stripe_count=$($LFS getdirstripe -c $dir1)
23827
23828         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
23829
23830         local max_count=$((MDSCOUNT - 1))
23831         local mdts=$(comma_list $(mdts_nodes))
23832
23833         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
23834         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
23835
23836         mkdir $dir2
23837         stripe_count=$($LFS getdirstripe -c $dir2)
23838
23839         (( $stripe_count == $max_count )) || error "wrong stripe count"
23840 }
23841 run_test 300t "test max_mdt_stripecount"
23842
23843 prepare_remote_file() {
23844         mkdir $DIR/$tdir/src_dir ||
23845                 error "create remote source failed"
23846
23847         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23848                  error "cp to remote source failed"
23849         touch $DIR/$tdir/src_dir/a
23850
23851         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23852                 error "create remote target dir failed"
23853
23854         touch $DIR/$tdir/tgt_dir/b
23855
23856         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23857                 error "rename dir cross MDT failed!"
23858
23859         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23860                 error "src_child still exists after rename"
23861
23862         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23863                 error "missing file(a) after rename"
23864
23865         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23866                 error "diff after rename"
23867 }
23868
23869 test_310a() {
23870         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23872
23873         local remote_file=$DIR/$tdir/tgt_dir/b
23874
23875         mkdir -p $DIR/$tdir
23876
23877         prepare_remote_file || error "prepare remote file failed"
23878
23879         #open-unlink file
23880         $OPENUNLINK $remote_file $remote_file ||
23881                 error "openunlink $remote_file failed"
23882         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23883 }
23884 run_test 310a "open unlink remote file"
23885
23886 test_310b() {
23887         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23889
23890         local remote_file=$DIR/$tdir/tgt_dir/b
23891
23892         mkdir -p $DIR/$tdir
23893
23894         prepare_remote_file || error "prepare remote file failed"
23895
23896         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23897         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23898         $CHECKSTAT -t file $remote_file || error "check file failed"
23899 }
23900 run_test 310b "unlink remote file with multiple links while open"
23901
23902 test_310c() {
23903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23904         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23905
23906         local remote_file=$DIR/$tdir/tgt_dir/b
23907
23908         mkdir -p $DIR/$tdir
23909
23910         prepare_remote_file || error "prepare remote file failed"
23911
23912         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23913         multiop_bg_pause $remote_file O_uc ||
23914                         error "mulitop failed for remote file"
23915         MULTIPID=$!
23916         $MULTIOP $DIR/$tfile Ouc
23917         kill -USR1 $MULTIPID
23918         wait $MULTIPID
23919 }
23920 run_test 310c "open-unlink remote file with multiple links"
23921
23922 #LU-4825
23923 test_311() {
23924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23925         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23926         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23927                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23928         remote_mds_nodsh && skip "remote MDS with nodsh"
23929
23930         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23931         local mdts=$(comma_list $(mdts_nodes))
23932
23933         mkdir -p $DIR/$tdir
23934         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23935         createmany -o $DIR/$tdir/$tfile. 1000
23936
23937         # statfs data is not real time, let's just calculate it
23938         old_iused=$((old_iused + 1000))
23939
23940         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23941                         osp.*OST0000*MDT0000.create_count")
23942         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23943                                 osp.*OST0000*MDT0000.max_create_count")
23944         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23945
23946         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23947         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23948         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23949
23950         unlinkmany $DIR/$tdir/$tfile. 1000
23951
23952         do_nodes $mdts "$LCTL set_param -n \
23953                         osp.*OST0000*.max_create_count=$max_count"
23954         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23955                 do_nodes $mdts "$LCTL set_param -n \
23956                                 osp.*OST0000*.create_count=$count"
23957         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23958                         grep "=0" && error "create_count is zero"
23959
23960         local new_iused
23961         for i in $(seq 120); do
23962                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23963                 # system may be too busy to destroy all objs in time, use
23964                 # a somewhat small value to not fail autotest
23965                 [ $((old_iused - new_iused)) -gt 400 ] && break
23966                 sleep 1
23967         done
23968
23969         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23970         [ $((old_iused - new_iused)) -gt 400 ] ||
23971                 error "objs not destroyed after unlink"
23972 }
23973 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23974
23975 zfs_oid_to_objid()
23976 {
23977         local ost=$1
23978         local objid=$2
23979
23980         local vdevdir=$(dirname $(facet_vdevice $ost))
23981         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23982         local zfs_zapid=$(do_facet $ost $cmd |
23983                           grep -w "/O/0/d$((objid%32))" -C 5 |
23984                           awk '/Object/{getline; print $1}')
23985         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23986                           awk "/$objid = /"'{printf $3}')
23987
23988         echo $zfs_objid
23989 }
23990
23991 zfs_object_blksz() {
23992         local ost=$1
23993         local objid=$2
23994
23995         local vdevdir=$(dirname $(facet_vdevice $ost))
23996         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23997         local blksz=$(do_facet $ost $cmd $objid |
23998                       awk '/dblk/{getline; printf $4}')
23999
24000         case "${blksz: -1}" in
24001                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24002                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24003                 *) ;;
24004         esac
24005
24006         echo $blksz
24007 }
24008
24009 test_312() { # LU-4856
24010         remote_ost_nodsh && skip "remote OST with nodsh"
24011         [ "$ost1_FSTYPE" = "zfs" ] ||
24012                 skip_env "the test only applies to zfs"
24013
24014         local max_blksz=$(do_facet ost1 \
24015                           $ZFS get -p recordsize $(facet_device ost1) |
24016                           awk '!/VALUE/{print $3}')
24017
24018         # to make life a little bit easier
24019         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24020         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24021
24022         local tf=$DIR/$tdir/$tfile
24023         touch $tf
24024         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24025
24026         # Get ZFS object id
24027         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24028         # block size change by sequential overwrite
24029         local bs
24030
24031         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24032                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24033
24034                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24035                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24036         done
24037         rm -f $tf
24038
24039         # block size change by sequential append write
24040         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24041         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24042         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24043         local count
24044
24045         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24046                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24047                         oflag=sync conv=notrunc
24048
24049                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24050                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24051                         error "blksz error, actual $blksz, " \
24052                                 "expected: 2 * $count * $PAGE_SIZE"
24053         done
24054         rm -f $tf
24055
24056         # random write
24057         touch $tf
24058         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24059         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24060
24061         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24062         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24063         [ $blksz -eq $PAGE_SIZE ] ||
24064                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24065
24066         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24067         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24068         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24069
24070         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24071         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24072         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24073 }
24074 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24075
24076 test_313() {
24077         remote_ost_nodsh && skip "remote OST with nodsh"
24078
24079         local file=$DIR/$tfile
24080
24081         rm -f $file
24082         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24083
24084         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24085         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24086         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24087                 error "write should failed"
24088         do_facet ost1 "$LCTL set_param fail_loc=0"
24089         rm -f $file
24090 }
24091 run_test 313 "io should fail after last_rcvd update fail"
24092
24093 test_314() {
24094         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24095
24096         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24097         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24098         rm -f $DIR/$tfile
24099         wait_delete_completed
24100         do_facet ost1 "$LCTL set_param fail_loc=0"
24101 }
24102 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24103
24104 test_315() { # LU-618
24105         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24106
24107         local file=$DIR/$tfile
24108         rm -f $file
24109
24110         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24111                 error "multiop file write failed"
24112         $MULTIOP $file oO_RDONLY:r4063232_c &
24113         PID=$!
24114
24115         sleep 2
24116
24117         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24118         kill -USR1 $PID
24119
24120         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24121         rm -f $file
24122 }
24123 run_test 315 "read should be accounted"
24124
24125 test_316() {
24126         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24127         large_xattr_enabled || skip "ea_inode feature disabled"
24128
24129         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24130         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24131         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24132         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24133
24134         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24135 }
24136 run_test 316 "lfs migrate of file with large_xattr enabled"
24137
24138 test_317() {
24139         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24140                 skip "Need MDS version at least 2.11.53"
24141         if [ "$ost1_FSTYPE" == "zfs" ]; then
24142                 skip "LU-10370: no implementation for ZFS"
24143         fi
24144
24145         local trunc_sz
24146         local grant_blk_size
24147
24148         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24149                         awk '/grant_block_size:/ { print $2; exit; }')
24150         #
24151         # Create File of size 5M. Truncate it to below size's and verify
24152         # blocks count.
24153         #
24154         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24155                 error "Create file $DIR/$tfile failed"
24156         stack_trap "rm -f $DIR/$tfile" EXIT
24157
24158         for trunc_sz in 2097152 4097 4000 509 0; do
24159                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24160                         error "truncate $tfile to $trunc_sz failed"
24161                 local sz=$(stat --format=%s $DIR/$tfile)
24162                 local blk=$(stat --format=%b $DIR/$tfile)
24163                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24164                                      grant_blk_size) * 8))
24165
24166                 if [[ $blk -ne $trunc_blk ]]; then
24167                         $(which stat) $DIR/$tfile
24168                         error "Expected Block $trunc_blk got $blk for $tfile"
24169                 fi
24170
24171                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24172                         error "Expected Size $trunc_sz got $sz for $tfile"
24173         done
24174
24175         #
24176         # sparse file test
24177         # Create file with a hole and write actual 65536 bytes which aligned
24178         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24179         #
24180         local bs=65536
24181         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24182                 error "Create file : $DIR/$tfile"
24183
24184         #
24185         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24186         # blocks. The block count must drop to 8.
24187         #
24188         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24189                 ((bs - grant_blk_size) + 1)))
24190         $TRUNCATE $DIR/$tfile $trunc_sz ||
24191                 error "truncate $tfile to $trunc_sz failed"
24192
24193         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24194         sz=$(stat --format=%s $DIR/$tfile)
24195         blk=$(stat --format=%b $DIR/$tfile)
24196
24197         if [[ $blk -ne $trunc_bsz ]]; then
24198                 $(which stat) $DIR/$tfile
24199                 error "Expected Block $trunc_bsz got $blk for $tfile"
24200         fi
24201
24202         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24203                 error "Expected Size $trunc_sz got $sz for $tfile"
24204 }
24205 run_test 317 "Verify blocks get correctly update after truncate"
24206
24207 test_318() {
24208         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24209         local old_max_active=$($LCTL get_param -n \
24210                             ${llite_name}.max_read_ahead_async_active \
24211                             2>/dev/null)
24212
24213         $LCTL set_param llite.*.max_read_ahead_async_active=256
24214         local max_active=$($LCTL get_param -n \
24215                            ${llite_name}.max_read_ahead_async_active \
24216                            2>/dev/null)
24217         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24218
24219         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24220                 error "set max_read_ahead_async_active should succeed"
24221
24222         $LCTL set_param llite.*.max_read_ahead_async_active=512
24223         max_active=$($LCTL get_param -n \
24224                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24225         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24226
24227         # restore @max_active
24228         [ $old_max_active -ne 0 ] && $LCTL set_param \
24229                 llite.*.max_read_ahead_async_active=$old_max_active
24230
24231         local old_threshold=$($LCTL get_param -n \
24232                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24233         local max_per_file_mb=$($LCTL get_param -n \
24234                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24235
24236         local invalid=$(($max_per_file_mb + 1))
24237         $LCTL set_param \
24238                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24239                         && error "set $invalid should fail"
24240
24241         local valid=$(($invalid - 1))
24242         $LCTL set_param \
24243                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24244                         error "set $valid should succeed"
24245         local threshold=$($LCTL get_param -n \
24246                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24247         [ $threshold -eq $valid ] || error \
24248                 "expect threshold $valid got $threshold"
24249         $LCTL set_param \
24250                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24251 }
24252 run_test 318 "Verify async readahead tunables"
24253
24254 test_319() {
24255         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24256
24257         local before=$(date +%s)
24258         local evict
24259         local mdir=$DIR/$tdir
24260         local file=$mdir/xxx
24261
24262         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24263         touch $file
24264
24265 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24266         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24267         $LFS migrate -m1 $mdir &
24268
24269         sleep 1
24270         dd if=$file of=/dev/null
24271         wait
24272         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24273           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24274
24275         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24276 }
24277 run_test 319 "lost lease lock on migrate error"
24278
24279 test_398a() { # LU-4198
24280         local ost1_imp=$(get_osc_import_name client ost1)
24281         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24282                          cut -d'.' -f2)
24283
24284         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24285         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24286
24287         # request a new lock on client
24288         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24289
24290         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24291         local lock_count=$($LCTL get_param -n \
24292                            ldlm.namespaces.$imp_name.lru_size)
24293         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24294
24295         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24296
24297         # no lock cached, should use lockless DIO and not enqueue new lock
24298         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24299         lock_count=$($LCTL get_param -n \
24300                      ldlm.namespaces.$imp_name.lru_size)
24301         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24302
24303         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24304
24305         # no lock cached, should use locked DIO append
24306         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24307                 conv=notrunc || error "DIO append failed"
24308         lock_count=$($LCTL get_param -n \
24309                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24310         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24311 }
24312 run_test 398a "direct IO should cancel lock otherwise lockless"
24313
24314 test_398b() { # LU-4198
24315         which fio || skip_env "no fio installed"
24316         $LFS setstripe -c -1 $DIR/$tfile
24317
24318         local size=12
24319         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24320
24321         local njobs=4
24322         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
24323         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24324                 --numjobs=$njobs --fallocate=none \
24325                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24326                 --filename=$DIR/$tfile &
24327         bg_pid=$!
24328
24329         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
24330         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
24331                 --numjobs=$njobs --fallocate=none \
24332                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24333                 --filename=$DIR/$tfile || true
24334         wait $bg_pid
24335
24336         rm -f $DIR/$tfile
24337 }
24338 run_test 398b "DIO and buffer IO race"
24339
24340 test_398c() { # LU-4198
24341         local ost1_imp=$(get_osc_import_name client ost1)
24342         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24343                          cut -d'.' -f2)
24344
24345         which fio || skip_env "no fio installed"
24346
24347         saved_debug=$($LCTL get_param -n debug)
24348         $LCTL set_param debug=0
24349
24350         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24351         ((size /= 1024)) # by megabytes
24352         ((size /= 2)) # write half of the OST at most
24353         [ $size -gt 40 ] && size=40 #reduce test time anyway
24354
24355         $LFS setstripe -c 1 $DIR/$tfile
24356
24357         # it seems like ldiskfs reserves more space than necessary if the
24358         # writing blocks are not mapped, so it extends the file firstly
24359         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24360         cancel_lru_locks osc
24361
24362         # clear and verify rpc_stats later
24363         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24364
24365         local njobs=4
24366         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24367         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24368                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24369                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24370                 --filename=$DIR/$tfile
24371         [ $? -eq 0 ] || error "fio write error"
24372
24373         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24374                 error "Locks were requested while doing AIO"
24375
24376         # get the percentage of 1-page I/O
24377         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24378                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24379                 awk '{print $7}')
24380         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24381
24382         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24383         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24384                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24385                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24386                 --filename=$DIR/$tfile
24387         [ $? -eq 0 ] || error "fio mixed read write error"
24388
24389         echo "AIO with large block size ${size}M"
24390         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24391                 --numjobs=1 --fallocate=none --ioengine=libaio \
24392                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24393                 --filename=$DIR/$tfile
24394         [ $? -eq 0 ] || error "fio large block size failed"
24395
24396         rm -f $DIR/$tfile
24397         $LCTL set_param debug="$saved_debug"
24398 }
24399 run_test 398c "run fio to test AIO"
24400
24401 test_398d() { #  LU-13846
24402         which aiocp || skip_env "no aiocp installed"
24403         local aio_file=$DIR/$tfile.aio
24404
24405         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24406
24407         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24408         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24409         stack_trap "rm -f $DIR/$tfile $aio_file"
24410
24411         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24412
24413         # make sure we don't crash and fail properly
24414         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24415                 error "aio not aligned with PAGE SIZE should fail"
24416
24417         rm -f $DIR/$tfile $aio_file
24418 }
24419 run_test 398d "run aiocp to verify block size > stripe size"
24420
24421 test_398e() {
24422         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24423         touch $DIR/$tfile.new
24424         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24425 }
24426 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24427
24428 test_398f() { #  LU-14687
24429         which aiocp || skip_env "no aiocp installed"
24430         local aio_file=$DIR/$tfile.aio
24431
24432         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24433
24434         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24435         stack_trap "rm -f $DIR/$tfile $aio_file"
24436
24437         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24438         $LCTL set_param fail_loc=0x1418
24439         # make sure we don't crash and fail properly
24440         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24441                 error "aio with page allocation failure succeeded"
24442         $LCTL set_param fail_loc=0
24443         diff $DIR/$tfile $aio_file
24444         [[ $? != 0 ]] || error "no diff after failed aiocp"
24445 }
24446 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24447
24448 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24449 # stripe and i/o size must be > stripe size
24450 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24451 # single RPC in flight.  This test shows async DIO submission is working by
24452 # showing multiple RPCs in flight.
24453 test_398g() { #  LU-13798
24454         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24455
24456         # We need to do some i/o first to acquire enough grant to put our RPCs
24457         # in flight; otherwise a new connection may not have enough grant
24458         # available
24459         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24460                 error "parallel dio failed"
24461         stack_trap "rm -f $DIR/$tfile"
24462
24463         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24464         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24465         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24466         stack_trap "$LCTL set_param -n $pages_per_rpc"
24467
24468         # Recreate file so it's empty
24469         rm -f $DIR/$tfile
24470         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24471         #Pause rpc completion to guarantee we see multiple rpcs in flight
24472         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24473         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24474         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24475
24476         # Clear rpc stats
24477         $LCTL set_param osc.*.rpc_stats=c
24478
24479         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24480                 error "parallel dio failed"
24481         stack_trap "rm -f $DIR/$tfile"
24482
24483         $LCTL get_param osc.*-OST0000-*.rpc_stats
24484         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24485                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24486                 grep "8:" | awk '{print $8}')
24487         # We look at the "8 rpcs in flight" field, and verify A) it is present
24488         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24489         # as expected for an 8M DIO to a file with 1M stripes.
24490         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24491
24492         # Verify turning off parallel dio works as expected
24493         # Clear rpc stats
24494         $LCTL set_param osc.*.rpc_stats=c
24495         $LCTL set_param llite.*.parallel_dio=0
24496         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24497
24498         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24499                 error "dio with parallel dio disabled failed"
24500
24501         # Ideally, we would see only one RPC in flight here, but there is an
24502         # unavoidable race between i/o completion and RPC in flight counting,
24503         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24504         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24505         # So instead we just verify it's always < 8.
24506         $LCTL get_param osc.*-OST0000-*.rpc_stats
24507         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24508                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24509                 grep '^$' -B1 | grep . | awk '{print $1}')
24510         [ $ret != "8:" ] ||
24511                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24512 }
24513 run_test 398g "verify parallel dio async RPC submission"
24514
24515 test_398h() { #  LU-13798
24516         local dio_file=$DIR/$tfile.dio
24517
24518         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24519
24520         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24521         stack_trap "rm -f $DIR/$tfile $dio_file"
24522
24523         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24524                 error "parallel dio failed"
24525         diff $DIR/$tfile $dio_file
24526         [[ $? == 0 ]] || error "file diff after aiocp"
24527 }
24528 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24529
24530 test_398i() { #  LU-13798
24531         local dio_file=$DIR/$tfile.dio
24532
24533         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24534
24535         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24536         stack_trap "rm -f $DIR/$tfile $dio_file"
24537
24538         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24539         $LCTL set_param fail_loc=0x1418
24540         # make sure we don't crash and fail properly
24541         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24542                 error "parallel dio page allocation failure succeeded"
24543         diff $DIR/$tfile $dio_file
24544         [[ $? != 0 ]] || error "no diff after failed aiocp"
24545 }
24546 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24547
24548 test_398j() { #  LU-13798
24549         # Stripe size > RPC size but less than i/o size tests split across
24550         # stripes and RPCs for individual i/o op
24551         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24552
24553         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24554         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24555         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24556         stack_trap "$LCTL set_param -n $pages_per_rpc"
24557
24558         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24559                 error "parallel dio write failed"
24560         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24561
24562         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24563                 error "parallel dio read failed"
24564         diff $DIR/$tfile $DIR/$tfile.2
24565         [[ $? == 0 ]] || error "file diff after parallel dio read"
24566 }
24567 run_test 398j "test parallel dio where stripe size > rpc_size"
24568
24569 test_398k() { #  LU-13798
24570         wait_delete_completed
24571         wait_mds_ost_sync
24572
24573         # 4 stripe file; we will cause out of space on OST0
24574         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24575
24576         # Fill OST0 (if it's not too large)
24577         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24578                    head -n1)
24579         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24580                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24581         fi
24582         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24583         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24584                 error "dd should fill OST0"
24585         stack_trap "rm -f $DIR/$tfile.1"
24586
24587         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24588         err=$?
24589
24590         ls -la $DIR/$tfile
24591         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24592                 error "file is not 0 bytes in size"
24593
24594         # dd above should not succeed, but don't error until here so we can
24595         # get debug info above
24596         [[ $err != 0 ]] ||
24597                 error "parallel dio write with enospc succeeded"
24598         stack_trap "rm -f $DIR/$tfile"
24599 }
24600 run_test 398k "test enospc on first stripe"
24601
24602 test_398l() { #  LU-13798
24603         wait_delete_completed
24604         wait_mds_ost_sync
24605
24606         # 4 stripe file; we will cause out of space on OST0
24607         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24608         # happens on the second i/o chunk we issue
24609         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24610
24611         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24612         stack_trap "rm -f $DIR/$tfile"
24613
24614         # Fill OST0 (if it's not too large)
24615         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24616                    head -n1)
24617         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24618                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24619         fi
24620         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24621         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24622                 error "dd should fill OST0"
24623         stack_trap "rm -f $DIR/$tfile.1"
24624
24625         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24626         err=$?
24627         stack_trap "rm -f $DIR/$tfile.2"
24628
24629         # Check that short write completed as expected
24630         ls -la $DIR/$tfile.2
24631         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24632                 error "file is not 1M in size"
24633
24634         # dd above should not succeed, but don't error until here so we can
24635         # get debug info above
24636         [[ $err != 0 ]] ||
24637                 error "parallel dio write with enospc succeeded"
24638
24639         # Truncate source file to same length as output file and diff them
24640         $TRUNCATE $DIR/$tfile 1048576
24641         diff $DIR/$tfile $DIR/$tfile.2
24642         [[ $? == 0 ]] || error "data incorrect after short write"
24643 }
24644 run_test 398l "test enospc on intermediate stripe/RPC"
24645
24646 test_398m() { #  LU-13798
24647         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24648
24649         # Set up failure on OST0, the first stripe:
24650         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24651         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24652         # So this fail_val specifies OST0
24653         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24654         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24655
24656         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24657                 error "parallel dio write with failure on first stripe succeeded"
24658         stack_trap "rm -f $DIR/$tfile"
24659         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24660
24661         # Place data in file for read
24662         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24663                 error "parallel dio write failed"
24664
24665         # Fail read on OST0, first stripe
24666         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24667         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24668         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24669                 error "parallel dio read with error on first stripe succeeded"
24670         rm -f $DIR/$tfile.2
24671         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24672
24673         # Switch to testing on OST1, second stripe
24674         # Clear file contents, maintain striping
24675         echo > $DIR/$tfile
24676         # Set up failure on OST1, second stripe:
24677         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24678         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24679
24680         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24681                 error "parallel dio write with failure on first stripe succeeded"
24682         stack_trap "rm -f $DIR/$tfile"
24683         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24684
24685         # Place data in file for read
24686         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24687                 error "parallel dio write failed"
24688
24689         # Fail read on OST1, second stripe
24690         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24691         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24692         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24693                 error "parallel dio read with error on first stripe succeeded"
24694         rm -f $DIR/$tfile.2
24695         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24696 }
24697 run_test 398m "test RPC failures with parallel dio"
24698
24699 # Parallel submission of DIO should not cause problems for append, but it's
24700 # important to verify.
24701 test_398n() { #  LU-13798
24702         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24703
24704         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24705                 error "dd to create source file failed"
24706         stack_trap "rm -f $DIR/$tfile"
24707
24708         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24709                 error "parallel dio write with failure on second stripe succeeded"
24710         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24711         diff $DIR/$tfile $DIR/$tfile.1
24712         [[ $? == 0 ]] || error "data incorrect after append"
24713
24714 }
24715 run_test 398n "test append with parallel DIO"
24716
24717 test_fake_rw() {
24718         local read_write=$1
24719         if [ "$read_write" = "write" ]; then
24720                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24721         elif [ "$read_write" = "read" ]; then
24722                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24723         else
24724                 error "argument error"
24725         fi
24726
24727         # turn off debug for performance testing
24728         local saved_debug=$($LCTL get_param -n debug)
24729         $LCTL set_param debug=0
24730
24731         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24732
24733         # get ost1 size - $FSNAME-OST0000
24734         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24735         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24736         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24737
24738         if [ "$read_write" = "read" ]; then
24739                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24740         fi
24741
24742         local start_time=$(date +%s.%N)
24743         $dd_cmd bs=1M count=$blocks oflag=sync ||
24744                 error "real dd $read_write error"
24745         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24746
24747         if [ "$read_write" = "write" ]; then
24748                 rm -f $DIR/$tfile
24749         fi
24750
24751         # define OBD_FAIL_OST_FAKE_RW           0x238
24752         do_facet ost1 $LCTL set_param fail_loc=0x238
24753
24754         local start_time=$(date +%s.%N)
24755         $dd_cmd bs=1M count=$blocks oflag=sync ||
24756                 error "fake dd $read_write error"
24757         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24758
24759         if [ "$read_write" = "write" ]; then
24760                 # verify file size
24761                 cancel_lru_locks osc
24762                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24763                         error "$tfile size not $blocks MB"
24764         fi
24765         do_facet ost1 $LCTL set_param fail_loc=0
24766
24767         echo "fake $read_write $duration_fake vs. normal $read_write" \
24768                 "$duration in seconds"
24769         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24770                 error_not_in_vm "fake write is slower"
24771
24772         $LCTL set_param -n debug="$saved_debug"
24773         rm -f $DIR/$tfile
24774 }
24775 test_399a() { # LU-7655 for OST fake write
24776         remote_ost_nodsh && skip "remote OST with nodsh"
24777
24778         test_fake_rw write
24779 }
24780 run_test 399a "fake write should not be slower than normal write"
24781
24782 test_399b() { # LU-8726 for OST fake read
24783         remote_ost_nodsh && skip "remote OST with nodsh"
24784         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24785                 skip_env "ldiskfs only test"
24786         fi
24787
24788         test_fake_rw read
24789 }
24790 run_test 399b "fake read should not be slower than normal read"
24791
24792 test_400a() { # LU-1606, was conf-sanity test_74
24793         if ! which $CC > /dev/null 2>&1; then
24794                 skip_env "$CC is not installed"
24795         fi
24796
24797         local extra_flags=''
24798         local out=$TMP/$tfile
24799         local prefix=/usr/include/lustre
24800         local prog
24801
24802         # Oleg removes c files in his test rig so test if any c files exist
24803         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24804                 skip_env "Needed c test files are missing"
24805
24806         if ! [[ -d $prefix ]]; then
24807                 # Assume we're running in tree and fixup the include path.
24808                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24809                 extra_flags+=" -L$LUSTRE/utils/.lib"
24810         fi
24811
24812         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24813                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24814                         error "client api broken"
24815         done
24816         rm -f $out
24817 }
24818 run_test 400a "Lustre client api program can compile and link"
24819
24820 test_400b() { # LU-1606, LU-5011
24821         local header
24822         local out=$TMP/$tfile
24823         local prefix=/usr/include/linux/lustre
24824
24825         # We use a hard coded prefix so that this test will not fail
24826         # when run in tree. There are headers in lustre/include/lustre/
24827         # that are not packaged (like lustre_idl.h) and have more
24828         # complicated include dependencies (like config.h and lnet/types.h).
24829         # Since this test about correct packaging we just skip them when
24830         # they don't exist (see below) rather than try to fixup cppflags.
24831
24832         if ! which $CC > /dev/null 2>&1; then
24833                 skip_env "$CC is not installed"
24834         fi
24835
24836         for header in $prefix/*.h; do
24837                 if ! [[ -f "$header" ]]; then
24838                         continue
24839                 fi
24840
24841                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24842                         continue # lustre_ioctl.h is internal header
24843                 fi
24844
24845                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24846                         error "cannot compile '$header'"
24847         done
24848         rm -f $out
24849 }
24850 run_test 400b "packaged headers can be compiled"
24851
24852 test_401a() { #LU-7437
24853         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24854         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24855
24856         #count the number of parameters by "list_param -R"
24857         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24858         #count the number of parameters by listing proc files
24859         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24860         echo "proc_dirs='$proc_dirs'"
24861         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24862         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24863                       sort -u | wc -l)
24864
24865         [ $params -eq $procs ] ||
24866                 error "found $params parameters vs. $procs proc files"
24867
24868         # test the list_param -D option only returns directories
24869         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24870         #count the number of parameters by listing proc directories
24871         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24872                 sort -u | wc -l)
24873
24874         [ $params -eq $procs ] ||
24875                 error "found $params parameters vs. $procs proc files"
24876 }
24877 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24878
24879 test_401b() {
24880         # jobid_var may not allow arbitrary values, so use jobid_name
24881         # if available
24882         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24883                 local testname=jobid_name tmp='testing%p'
24884         else
24885                 local testname=jobid_var tmp=testing
24886         fi
24887
24888         local save=$($LCTL get_param -n $testname)
24889
24890         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24891                 error "no error returned when setting bad parameters"
24892
24893         local jobid_new=$($LCTL get_param -n foe $testname baz)
24894         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24895
24896         $LCTL set_param -n fog=bam $testname=$save bat=fog
24897         local jobid_old=$($LCTL get_param -n foe $testname bag)
24898         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24899 }
24900 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24901
24902 test_401c() {
24903         # jobid_var may not allow arbitrary values, so use jobid_name
24904         # if available
24905         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24906                 local testname=jobid_name
24907         else
24908                 local testname=jobid_var
24909         fi
24910
24911         local jobid_var_old=$($LCTL get_param -n $testname)
24912         local jobid_var_new
24913
24914         $LCTL set_param $testname= &&
24915                 error "no error returned for 'set_param a='"
24916
24917         jobid_var_new=$($LCTL get_param -n $testname)
24918         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24919                 error "$testname was changed by setting without value"
24920
24921         $LCTL set_param $testname &&
24922                 error "no error returned for 'set_param a'"
24923
24924         jobid_var_new=$($LCTL get_param -n $testname)
24925         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24926                 error "$testname was changed by setting without value"
24927 }
24928 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24929
24930 test_401d() {
24931         # jobid_var may not allow arbitrary values, so use jobid_name
24932         # if available
24933         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24934                 local testname=jobid_name new_value='foo=bar%p'
24935         else
24936                 local testname=jobid_var new_valuie=foo=bar
24937         fi
24938
24939         local jobid_var_old=$($LCTL get_param -n $testname)
24940         local jobid_var_new
24941
24942         $LCTL set_param $testname=$new_value ||
24943                 error "'set_param a=b' did not accept a value containing '='"
24944
24945         jobid_var_new=$($LCTL get_param -n $testname)
24946         [[ "$jobid_var_new" == "$new_value" ]] ||
24947                 error "'set_param a=b' failed on a value containing '='"
24948
24949         # Reset the $testname to test the other format
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         $LCTL set_param $testname $new_value ||
24956                 error "'set_param a b' did not accept a value containing '='"
24957
24958         jobid_var_new=$($LCTL get_param -n $testname)
24959         [[ "$jobid_var_new" == "$new_value" ]] ||
24960                 error "'set_param a b' failed on a value containing '='"
24961
24962         $LCTL set_param $testname $jobid_var_old
24963         jobid_var_new=$($LCTL get_param -n $testname)
24964         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24965                 error "failed to reset $testname"
24966 }
24967 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24968
24969 test_401e() { # LU-14779
24970         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24971                 error "lctl list_param MGC* failed"
24972         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24973         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24974                 error "lctl get_param lru_size failed"
24975 }
24976 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24977
24978 test_402() {
24979         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24980         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24981                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24982         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24983                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24984                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24985         remote_mds_nodsh && skip "remote MDS with nodsh"
24986
24987         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24988 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24989         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24990         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24991                 echo "Touch failed - OK"
24992 }
24993 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24994
24995 test_403() {
24996         local file1=$DIR/$tfile.1
24997         local file2=$DIR/$tfile.2
24998         local tfile=$TMP/$tfile
24999
25000         rm -f $file1 $file2 $tfile
25001
25002         touch $file1
25003         ln $file1 $file2
25004
25005         # 30 sec OBD_TIMEOUT in ll_getattr()
25006         # right before populating st_nlink
25007         $LCTL set_param fail_loc=0x80001409
25008         stat -c %h $file1 > $tfile &
25009
25010         # create an alias, drop all locks and reclaim the dentry
25011         < $file2
25012         cancel_lru_locks mdc
25013         cancel_lru_locks osc
25014         sysctl -w vm.drop_caches=2
25015
25016         wait
25017
25018         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25019
25020         rm -f $tfile $file1 $file2
25021 }
25022 run_test 403 "i_nlink should not drop to zero due to aliasing"
25023
25024 test_404() { # LU-6601
25025         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25026                 skip "Need server version newer than 2.8.52"
25027         remote_mds_nodsh && skip "remote MDS with nodsh"
25028
25029         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25030                 awk '/osp .*-osc-MDT/ { print $4}')
25031
25032         local osp
25033         for osp in $mosps; do
25034                 echo "Deactivate: " $osp
25035                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25036                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25037                         awk -vp=$osp '$4 == p { print $2 }')
25038                 [ $stat = IN ] || {
25039                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25040                         error "deactivate error"
25041                 }
25042                 echo "Activate: " $osp
25043                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25044                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25045                         awk -vp=$osp '$4 == p { print $2 }')
25046                 [ $stat = UP ] || {
25047                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25048                         error "activate error"
25049                 }
25050         done
25051 }
25052 run_test 404 "validate manual {de}activated works properly for OSPs"
25053
25054 test_405() {
25055         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25056         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25057                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25058                         skip "Layout swap lock is not supported"
25059
25060         check_swap_layouts_support
25061         check_swap_layout_no_dom $DIR
25062
25063         test_mkdir $DIR/$tdir
25064         swap_lock_test -d $DIR/$tdir ||
25065                 error "One layout swap locked test failed"
25066 }
25067 run_test 405 "Various layout swap lock tests"
25068
25069 test_406() {
25070         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25071         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25072         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25074         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25075                 skip "Need MDS version at least 2.8.50"
25076
25077         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25078         local test_pool=$TESTNAME
25079
25080         pool_add $test_pool || error "pool_add failed"
25081         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25082                 error "pool_add_targets failed"
25083
25084         save_layout_restore_at_exit $MOUNT
25085
25086         # parent set default stripe count only, child will stripe from both
25087         # parent and fs default
25088         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25089                 error "setstripe $MOUNT failed"
25090         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25091         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25092         for i in $(seq 10); do
25093                 local f=$DIR/$tdir/$tfile.$i
25094                 touch $f || error "touch failed"
25095                 local count=$($LFS getstripe -c $f)
25096                 [ $count -eq $OSTCOUNT ] ||
25097                         error "$f stripe count $count != $OSTCOUNT"
25098                 local offset=$($LFS getstripe -i $f)
25099                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25100                 local size=$($LFS getstripe -S $f)
25101                 [ $size -eq $((def_stripe_size * 2)) ] ||
25102                         error "$f stripe size $size != $((def_stripe_size * 2))"
25103                 local pool=$($LFS getstripe -p $f)
25104                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25105         done
25106
25107         # change fs default striping, delete parent default striping, now child
25108         # will stripe from new fs default striping only
25109         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25110                 error "change $MOUNT default stripe failed"
25111         $LFS setstripe -c 0 $DIR/$tdir ||
25112                 error "delete $tdir default stripe failed"
25113         for i in $(seq 11 20); do
25114                 local f=$DIR/$tdir/$tfile.$i
25115                 touch $f || error "touch $f failed"
25116                 local count=$($LFS getstripe -c $f)
25117                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25118                 local offset=$($LFS getstripe -i $f)
25119                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25120                 local size=$($LFS getstripe -S $f)
25121                 [ $size -eq $def_stripe_size ] ||
25122                         error "$f stripe size $size != $def_stripe_size"
25123                 local pool=$($LFS getstripe -p $f)
25124                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25125         done
25126
25127         unlinkmany $DIR/$tdir/$tfile. 1 20
25128
25129         local f=$DIR/$tdir/$tfile
25130         pool_remove_all_targets $test_pool $f
25131         pool_remove $test_pool $f
25132 }
25133 run_test 406 "DNE support fs default striping"
25134
25135 test_407() {
25136         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25137         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25138                 skip "Need MDS version at least 2.8.55"
25139         remote_mds_nodsh && skip "remote MDS with nodsh"
25140
25141         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25142                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25143         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25144                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25145         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25146
25147         #define OBD_FAIL_DT_TXN_STOP    0x2019
25148         for idx in $(seq $MDSCOUNT); do
25149                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25150         done
25151         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25152         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25153                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25154         true
25155 }
25156 run_test 407 "transaction fail should cause operation fail"
25157
25158 test_408() {
25159         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25160
25161         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25162         lctl set_param fail_loc=0x8000040a
25163         # let ll_prepare_partial_page() fail
25164         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25165
25166         rm -f $DIR/$tfile
25167
25168         # create at least 100 unused inodes so that
25169         # shrink_icache_memory(0) should not return 0
25170         touch $DIR/$tfile-{0..100}
25171         rm -f $DIR/$tfile-{0..100}
25172         sync
25173
25174         echo 2 > /proc/sys/vm/drop_caches
25175 }
25176 run_test 408 "drop_caches should not hang due to page leaks"
25177
25178 test_409()
25179 {
25180         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25181
25182         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25183         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25184         touch $DIR/$tdir/guard || error "(2) Fail to create"
25185
25186         local PREFIX=$(str_repeat 'A' 128)
25187         echo "Create 1K hard links start at $(date)"
25188         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25189                 error "(3) Fail to hard link"
25190
25191         echo "Links count should be right although linkEA overflow"
25192         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25193         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25194         [ $linkcount -eq 1001 ] ||
25195                 error "(5) Unexpected hard links count: $linkcount"
25196
25197         echo "List all links start at $(date)"
25198         ls -l $DIR/$tdir/foo > /dev/null ||
25199                 error "(6) Fail to list $DIR/$tdir/foo"
25200
25201         echo "Unlink hard links start at $(date)"
25202         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25203                 error "(7) Fail to unlink"
25204         echo "Unlink hard links finished at $(date)"
25205 }
25206 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25207
25208 test_410()
25209 {
25210         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25211                 skip "Need client version at least 2.9.59"
25212         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25213                 skip "Need MODULES build"
25214
25215         # Create a file, and stat it from the kernel
25216         local testfile=$DIR/$tfile
25217         touch $testfile
25218
25219         local run_id=$RANDOM
25220         local my_ino=$(stat --format "%i" $testfile)
25221
25222         # Try to insert the module. This will always fail as the
25223         # module is designed to not be inserted.
25224         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25225             &> /dev/null
25226
25227         # Anything but success is a test failure
25228         dmesg | grep -q \
25229             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25230             error "no inode match"
25231 }
25232 run_test 410 "Test inode number returned from kernel thread"
25233
25234 cleanup_test411_cgroup() {
25235         trap 0
25236         rmdir "$1"
25237 }
25238
25239 test_411() {
25240         local cg_basedir=/sys/fs/cgroup/memory
25241         # LU-9966
25242         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25243                 skip "no setup for cgroup"
25244
25245         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25246                 error "test file creation failed"
25247         cancel_lru_locks osc
25248
25249         # Create a very small memory cgroup to force a slab allocation error
25250         local cgdir=$cg_basedir/osc_slab_alloc
25251         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25252         trap "cleanup_test411_cgroup $cgdir" EXIT
25253         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25254         echo 1M > $cgdir/memory.limit_in_bytes
25255
25256         # Should not LBUG, just be killed by oom-killer
25257         # dd will return 0 even allocation failure in some environment.
25258         # So don't check return value
25259         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25260         cleanup_test411_cgroup $cgdir
25261
25262         return 0
25263 }
25264 run_test 411 "Slab allocation error with cgroup does not LBUG"
25265
25266 test_412() {
25267         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25268         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25269                 skip "Need server version at least 2.10.55"
25270
25271         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25272                 error "mkdir failed"
25273         $LFS getdirstripe $DIR/$tdir
25274         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25275         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25276                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25277         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25278         [ $stripe_count -eq 2 ] ||
25279                 error "expect 2 get $stripe_count"
25280
25281         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25282
25283         local index
25284         local index2
25285
25286         # subdirs should be on the same MDT as parent
25287         for i in $(seq 0 $((MDSCOUNT - 1))); do
25288                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25289                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25290                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25291                 (( index == i )) || error "mdt$i/sub on MDT$index"
25292         done
25293
25294         # stripe offset -1, ditto
25295         for i in {1..10}; do
25296                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25297                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25298                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25299                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25300                 (( index == index2 )) ||
25301                         error "qos$i on MDT$index, sub on MDT$index2"
25302         done
25303
25304         local testdir=$DIR/$tdir/inherit
25305
25306         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25307         # inherit 2 levels
25308         for i in 1 2; do
25309                 testdir=$testdir/s$i
25310                 mkdir $testdir || error "mkdir $testdir failed"
25311                 index=$($LFS getstripe -m $testdir)
25312                 (( index == 1 )) ||
25313                         error "$testdir on MDT$index"
25314         done
25315
25316         # not inherit any more
25317         testdir=$testdir/s3
25318         mkdir $testdir || error "mkdir $testdir failed"
25319         getfattr -d -m dmv $testdir | grep dmv &&
25320                 error "default LMV set on $testdir" || true
25321 }
25322 run_test 412 "mkdir on specific MDTs"
25323
25324 generate_uneven_mdts() {
25325         local threshold=$1
25326         local lmv_qos_maxage
25327         local lod_qos_maxage
25328         local ffree
25329         local bavail
25330         local max
25331         local min
25332         local max_index
25333         local min_index
25334         local tmp
25335         local i
25336
25337         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25338         $LCTL set_param lmv.*.qos_maxage=1
25339         stack_trap "$LCTL set_param \
25340                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25341         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25342                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25343         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25344                 lod.*.mdt_qos_maxage=1
25345         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25346                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25347
25348         echo
25349         echo "Check for uneven MDTs: "
25350
25351         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25352         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25353         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25354
25355         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25356         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25357         max_index=0
25358         min_index=0
25359         for ((i = 1; i < ${#ffree[@]}; i++)); do
25360                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25361                 if [ $tmp -gt $max ]; then
25362                         max=$tmp
25363                         max_index=$i
25364                 fi
25365                 if [ $tmp -lt $min ]; then
25366                         min=$tmp
25367                         min_index=$i
25368                 fi
25369         done
25370
25371         (( ${ffree[min_index]} > 0 )) ||
25372                 skip "no free files in MDT$min_index"
25373         (( ${ffree[min_index]} < 10000000 )) ||
25374                 skip "too many free files in MDT$min_index"
25375
25376         # Check if we need to generate uneven MDTs
25377         local diff=$(((max - min) * 100 / min))
25378         local testdir=$DIR/$tdir-fillmdt
25379         local start
25380
25381         mkdir -p $testdir
25382
25383         i=0
25384         while (( diff < threshold )); do
25385                 # generate uneven MDTs, create till $threshold% diff
25386                 echo -n "weight diff=$diff% must be > $threshold% ..."
25387                 echo "Fill MDT$min_index with 1000 files: loop $i"
25388                 testdir=$DIR/$tdir-fillmdt/$i
25389                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25390                         error "mkdir $testdir failed"
25391                 $LFS setstripe -E 1M -L mdt $testdir ||
25392                         error "setstripe $testdir failed"
25393                 start=$SECONDS
25394                 for F in f.{0..999}; do
25395                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25396                                 /dev/null 2>&1 || error "dd $F failed"
25397                 done
25398
25399                 # wait for QOS to update
25400                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25401
25402                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25403                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25404                 max=$(((${ffree[max_index]} >> 8) *
25405                         (${bavail[max_index]} * bsize >> 16)))
25406                 min=$(((${ffree[min_index]} >> 8) *
25407                         (${bavail[min_index]} * bsize >> 16)))
25408                 diff=$(((max - min) * 100 / min))
25409                 i=$((i + 1))
25410         done
25411
25412         echo "MDT filesfree available: ${ffree[*]}"
25413         echo "MDT blocks available: ${bavail[*]}"
25414         echo "weight diff=$diff%"
25415 }
25416
25417 test_qos_mkdir() {
25418         local mkdir_cmd=$1
25419         local stripe_count=$2
25420         local mdts=$(comma_list $(mdts_nodes))
25421
25422         local testdir
25423         local lmv_qos_prio_free
25424         local lmv_qos_threshold_rr
25425         local lmv_qos_maxage
25426         local lod_qos_prio_free
25427         local lod_qos_threshold_rr
25428         local lod_qos_maxage
25429         local count
25430         local i
25431
25432         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25433         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25434         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25435                 head -n1)
25436         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25437         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25438         stack_trap "$LCTL set_param \
25439                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25440         stack_trap "$LCTL set_param \
25441                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25442         stack_trap "$LCTL set_param \
25443                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25444
25445         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25446                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25447         lod_qos_prio_free=${lod_qos_prio_free%%%}
25448         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25449                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25450         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25451         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25452                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25453         stack_trap "do_nodes $mdts $LCTL set_param \
25454                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25455         stack_trap "do_nodes $mdts $LCTL set_param \
25456                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25457         stack_trap "do_nodes $mdts $LCTL set_param \
25458                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25459
25460         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25461         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25462
25463         testdir=$DIR/$tdir-s$stripe_count/rr
25464
25465         local stripe_index=$($LFS getstripe -m $testdir)
25466         local test_mkdir_rr=true
25467
25468         getfattr -d -m dmv -e hex $testdir | grep dmv
25469         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25470                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25471                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25472                         test_mkdir_rr=false
25473         fi
25474
25475         echo
25476         $test_mkdir_rr &&
25477                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25478                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25479
25480         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25481         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25482                 eval $mkdir_cmd $testdir/subdir$i ||
25483                         error "$mkdir_cmd subdir$i failed"
25484         done
25485
25486         for (( i = 0; i < $MDSCOUNT; i++ )); do
25487                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25488                 echo "$count directories created on MDT$i"
25489                 if $test_mkdir_rr; then
25490                         (( $count == 100 )) ||
25491                                 error "subdirs are not evenly distributed"
25492                 elif (( $i == $stripe_index )); then
25493                         (( $count == 100 * MDSCOUNT )) ||
25494                                 error "$count subdirs created on MDT$i"
25495                 else
25496                         (( $count == 0 )) ||
25497                                 error "$count subdirs created on MDT$i"
25498                 fi
25499
25500                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25501                         count=$($LFS getdirstripe $testdir/* |
25502                                 grep -c -P "^\s+$i\t")
25503                         echo "$count stripes created on MDT$i"
25504                         # deviation should < 5% of average
25505                         (( $count >= 95 * stripe_count &&
25506                            $count <= 105 * stripe_count)) ||
25507                                 error "stripes are not evenly distributed"
25508                 fi
25509         done
25510
25511         echo
25512         echo "Check for uneven MDTs: "
25513
25514         local ffree
25515         local bavail
25516         local max
25517         local min
25518         local max_index
25519         local min_index
25520         local tmp
25521
25522         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25523         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25524         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25525
25526         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25527         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25528         max_index=0
25529         min_index=0
25530         for ((i = 1; i < ${#ffree[@]}; i++)); do
25531                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25532                 if [ $tmp -gt $max ]; then
25533                         max=$tmp
25534                         max_index=$i
25535                 fi
25536                 if [ $tmp -lt $min ]; then
25537                         min=$tmp
25538                         min_index=$i
25539                 fi
25540         done
25541
25542         (( ${ffree[min_index]} > 0 )) ||
25543                 skip "no free files in MDT$min_index"
25544         (( ${ffree[min_index]} < 10000000 )) ||
25545                 skip "too many free files in MDT$min_index"
25546
25547         echo "MDT filesfree available: ${ffree[*]}"
25548         echo "MDT blocks available: ${bavail[*]}"
25549         echo "weight diff=$(((max - min) * 100 / min))%"
25550         echo
25551         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25552
25553         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25554         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25555         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25556         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25557         # decrease statfs age, so that it can be updated in time
25558         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25559         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25560
25561         sleep 1
25562
25563         testdir=$DIR/$tdir-s$stripe_count/qos
25564         local num=200
25565
25566         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25567         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25568                 eval $mkdir_cmd $testdir/subdir$i ||
25569                         error "$mkdir_cmd subdir$i failed"
25570         done
25571
25572         max=0
25573         for (( i = 0; i < $MDSCOUNT; i++ )); do
25574                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25575                 (( count > max )) && max=$count
25576                 echo "$count directories created on MDT$i"
25577         done
25578
25579         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25580
25581         # D-value should > 10% of averge
25582         (( max - min > num / 10 )) ||
25583                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25584
25585         # ditto for stripes
25586         if (( stripe_count > 1 )); then
25587                 max=0
25588                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25589                         count=$($LFS getdirstripe $testdir/* |
25590                                 grep -c -P "^\s+$i\t")
25591                         (( count > max )) && max=$count
25592                         echo "$count stripes created on MDT$i"
25593                 done
25594
25595                 min=$($LFS getdirstripe $testdir/* |
25596                         grep -c -P "^\s+$min_index\t")
25597                 (( max - min > num * stripe_count / 10 )) ||
25598                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25599         fi
25600 }
25601
25602 most_full_mdt() {
25603         local ffree
25604         local bavail
25605         local bsize
25606         local min
25607         local min_index
25608         local tmp
25609
25610         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25611         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25612         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25613
25614         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25615         min_index=0
25616         for ((i = 1; i < ${#ffree[@]}; i++)); do
25617                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25618                 (( tmp < min )) && min=$tmp && min_index=$i
25619         done
25620
25621         echo -n $min_index
25622 }
25623
25624 test_413a() {
25625         [ $MDSCOUNT -lt 2 ] &&
25626                 skip "We need at least 2 MDTs for this test"
25627
25628         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25629                 skip "Need server version at least 2.12.52"
25630
25631         local stripe_count
25632
25633         generate_uneven_mdts 100
25634         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25635                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25636                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25637                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25638                         error "mkdir failed"
25639                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25640         done
25641 }
25642 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25643
25644 test_413b() {
25645         [ $MDSCOUNT -lt 2 ] &&
25646                 skip "We need at least 2 MDTs for this test"
25647
25648         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25649                 skip "Need server version at least 2.12.52"
25650
25651         local testdir
25652         local stripe_count
25653
25654         generate_uneven_mdts 100
25655         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25656                 testdir=$DIR/$tdir-s$stripe_count
25657                 mkdir $testdir || error "mkdir $testdir failed"
25658                 mkdir $testdir/rr || error "mkdir rr failed"
25659                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25660                         error "mkdir qos failed"
25661                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25662                         $testdir/rr || error "setdirstripe rr failed"
25663                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25664                         error "setdirstripe failed"
25665                 test_qos_mkdir "mkdir" $stripe_count
25666         done
25667 }
25668 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25669
25670 test_413c() {
25671         (( $MDSCOUNT >= 2 )) ||
25672                 skip "We need at least 2 MDTs for this test"
25673
25674         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25675                 skip "Need server version at least 2.14.51"
25676
25677         local testdir
25678         local inherit
25679         local inherit_rr
25680
25681         testdir=$DIR/${tdir}-s1
25682         mkdir $testdir || error "mkdir $testdir failed"
25683         mkdir $testdir/rr || error "mkdir rr failed"
25684         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25685         # default max_inherit is -1, default max_inherit_rr is 0
25686         $LFS setdirstripe -D -c 1 $testdir/rr ||
25687                 error "setdirstripe rr failed"
25688         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25689                 error "setdirstripe qos failed"
25690         test_qos_mkdir "mkdir" 1
25691
25692         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25693         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25694         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25695         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25696         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25697
25698         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25699         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25700         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25701         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25702         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25703         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25704         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25705                 error "level2 shouldn't have default LMV" || true
25706 }
25707 run_test 413c "mkdir with default LMV max inherit rr"
25708
25709 test_413d() {
25710         (( MDSCOUNT >= 2 )) ||
25711                 skip "We need at least 2 MDTs for this test"
25712
25713         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25714                 skip "Need server version at least 2.14.51"
25715
25716         local lmv_qos_threshold_rr
25717
25718         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25719                 head -n1)
25720         stack_trap "$LCTL set_param \
25721                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25722
25723         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25724         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25725         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25726                 error "$tdir shouldn't have default LMV"
25727         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25728                 error "mkdir sub failed"
25729
25730         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25731
25732         (( count == 100 )) || error "$count subdirs on MDT0"
25733 }
25734 run_test 413d "inherit ROOT default LMV"
25735
25736 test_413e() {
25737         (( MDSCOUNT >= 2 )) ||
25738                 skip "We need at least 2 MDTs for this test"
25739         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25740                 skip "Need server version at least 2.14.55"
25741
25742         local testdir=$DIR/$tdir
25743         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25744         local max_inherit
25745         local sub_max_inherit
25746
25747         mkdir -p $testdir || error "failed to create $testdir"
25748
25749         # set default max-inherit to -1 if stripe count is 0 or 1
25750         $LFS setdirstripe -D -c 1 $testdir ||
25751                 error "failed to set default LMV"
25752         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25753         (( max_inherit == -1 )) ||
25754                 error "wrong max_inherit value $max_inherit"
25755
25756         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25757         $LFS setdirstripe -D -c -1 $testdir ||
25758                 error "failed to set default LMV"
25759         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25760         (( max_inherit > 0 )) ||
25761                 error "wrong max_inherit value $max_inherit"
25762
25763         # and the subdir will decrease the max_inherit by 1
25764         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25765         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
25766         (( sub_max_inherit == max_inherit - 1)) ||
25767                 error "wrong max-inherit of subdir $sub_max_inherit"
25768
25769         # check specified --max-inherit and warning message
25770         stack_trap "rm -f $tmpfile"
25771         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
25772                 error "failed to set default LMV"
25773         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25774         (( max_inherit == -1 )) ||
25775                 error "wrong max_inherit value $max_inherit"
25776
25777         # check the warning messages
25778         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
25779                 error "failed to detect warning string"
25780         fi
25781 }
25782 run_test 413e "check default max-inherit value"
25783
25784 test_413f() {
25785         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
25786
25787         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25788                 skip "Need server version at least 2.14.55"
25789
25790         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
25791                 error "dump $DIR default LMV failed"
25792         stack_trap "setfattr --restore=$TMP/dmv.ea"
25793
25794         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
25795                 error "set $DIR default LMV failed"
25796
25797         local testdir=$DIR/$tdir
25798
25799         local count
25800         local inherit
25801         local inherit_rr
25802
25803         for i in $(seq 3); do
25804                 mkdir $testdir || error "mkdir $testdir failed"
25805                 count=$($LFS getdirstripe -D -c $testdir)
25806                 (( count == 1 )) ||
25807                         error "$testdir default LMV count mismatch $count != 1"
25808                 inherit=$($LFS getdirstripe -D -X $testdir)
25809                 (( inherit == 3 - i )) ||
25810                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
25811                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
25812                 (( inherit_rr == 3 - i )) ||
25813                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
25814                 testdir=$testdir/sub
25815         done
25816
25817         mkdir $testdir || error "mkdir $testdir failed"
25818         count=$($LFS getdirstripe -D -c $testdir)
25819         (( count == 0 )) ||
25820                 error "$testdir default LMV count not zero: $count"
25821 }
25822 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
25823
25824 test_413z() {
25825         local pids=""
25826         local subdir
25827         local pid
25828
25829         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25830                 unlinkmany $subdir/f. 1000 &
25831                 pids="$pids $!"
25832         done
25833
25834         for pid in $pids; do
25835                 wait $pid
25836         done
25837 }
25838 run_test 413z "413 test cleanup"
25839
25840 test_414() {
25841 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25842         $LCTL set_param fail_loc=0x80000521
25843         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25844         rm -f $DIR/$tfile
25845 }
25846 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25847
25848 test_415() {
25849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25850         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25851                 skip "Need server version at least 2.11.52"
25852
25853         # LU-11102
25854         local total
25855         local setattr_pid
25856         local start_time
25857         local end_time
25858         local duration
25859
25860         total=500
25861         # this test may be slow on ZFS
25862         [ "$mds1_FSTYPE" == "zfs" ] && total=50
25863
25864         # though this test is designed for striped directory, let's test normal
25865         # directory too since lock is always saved as CoS lock.
25866         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25867         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25868
25869         (
25870                 while true; do
25871                         touch $DIR/$tdir
25872                 done
25873         ) &
25874         setattr_pid=$!
25875
25876         start_time=$(date +%s)
25877         for i in $(seq $total); do
25878                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25879                         > /dev/null
25880         done
25881         end_time=$(date +%s)
25882         duration=$((end_time - start_time))
25883
25884         kill -9 $setattr_pid
25885
25886         echo "rename $total files took $duration sec"
25887         [ $duration -lt 100 ] || error "rename took $duration sec"
25888 }
25889 run_test 415 "lock revoke is not missing"
25890
25891 test_416() {
25892         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25893                 skip "Need server version at least 2.11.55"
25894
25895         # define OBD_FAIL_OSD_TXN_START    0x19a
25896         do_facet mds1 lctl set_param fail_loc=0x19a
25897
25898         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25899
25900         true
25901 }
25902 run_test 416 "transaction start failure won't cause system hung"
25903
25904 cleanup_417() {
25905         trap 0
25906         do_nodes $(comma_list $(mdts_nodes)) \
25907                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25908         do_nodes $(comma_list $(mdts_nodes)) \
25909                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25910         do_nodes $(comma_list $(mdts_nodes)) \
25911                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25912 }
25913
25914 test_417() {
25915         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25916         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25917                 skip "Need MDS version at least 2.11.56"
25918
25919         trap cleanup_417 RETURN EXIT
25920
25921         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25922         do_nodes $(comma_list $(mdts_nodes)) \
25923                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25924         $LFS migrate -m 0 $DIR/$tdir.1 &&
25925                 error "migrate dir $tdir.1 should fail"
25926
25927         do_nodes $(comma_list $(mdts_nodes)) \
25928                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25929         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25930                 error "create remote dir $tdir.2 should fail"
25931
25932         do_nodes $(comma_list $(mdts_nodes)) \
25933                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25934         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25935                 error "create striped dir $tdir.3 should fail"
25936         true
25937 }
25938 run_test 417 "disable remote dir, striped dir and dir migration"
25939
25940 # Checks that the outputs of df [-i] and lfs df [-i] match
25941 #
25942 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25943 check_lfs_df() {
25944         local dir=$2
25945         local inodes
25946         local df_out
25947         local lfs_df_out
25948         local count
25949         local passed=false
25950
25951         # blocks or inodes
25952         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25953
25954         for count in {1..100}; do
25955                 do_nodes "$CLIENTS" \
25956                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25957                 sync; sleep 0.2
25958
25959                 # read the lines of interest
25960                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25961                         error "df $inodes $dir | tail -n +2 failed"
25962                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25963                         error "lfs df $inodes $dir | grep summary: failed"
25964
25965                 # skip first substrings of each output as they are different
25966                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25967                 # compare the two outputs
25968                 passed=true
25969                 #  skip "available" on MDT until LU-13997 is fixed.
25970                 #for i in {1..5}; do
25971                 for i in 1 2 4 5; do
25972                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25973                 done
25974                 $passed && break
25975         done
25976
25977         if ! $passed; then
25978                 df -P $inodes $dir
25979                 echo
25980                 lfs df $inodes $dir
25981                 error "df and lfs df $1 output mismatch: "      \
25982                       "df ${inodes}: ${df_out[*]}, "            \
25983                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25984         fi
25985 }
25986
25987 test_418() {
25988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25989
25990         local dir=$DIR/$tdir
25991         local numfiles=$((RANDOM % 4096 + 2))
25992         local numblocks=$((RANDOM % 256 + 1))
25993
25994         wait_delete_completed
25995         test_mkdir $dir
25996
25997         # check block output
25998         check_lfs_df blocks $dir
25999         # check inode output
26000         check_lfs_df inodes $dir
26001
26002         # create a single file and retest
26003         echo "Creating a single file and testing"
26004         createmany -o $dir/$tfile- 1 &>/dev/null ||
26005                 error "creating 1 file in $dir failed"
26006         check_lfs_df blocks $dir
26007         check_lfs_df inodes $dir
26008
26009         # create a random number of files
26010         echo "Creating $((numfiles - 1)) files and testing"
26011         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26012                 error "creating $((numfiles - 1)) files in $dir failed"
26013
26014         # write a random number of blocks to the first test file
26015         echo "Writing $numblocks 4K blocks and testing"
26016         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26017                 count=$numblocks &>/dev/null ||
26018                 error "dd to $dir/${tfile}-0 failed"
26019
26020         # retest
26021         check_lfs_df blocks $dir
26022         check_lfs_df inodes $dir
26023
26024         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26025                 error "unlinking $numfiles files in $dir failed"
26026 }
26027 run_test 418 "df and lfs df outputs match"
26028
26029 test_419()
26030 {
26031         local dir=$DIR/$tdir
26032
26033         mkdir -p $dir
26034         touch $dir/file
26035
26036         cancel_lru_locks mdc
26037
26038         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26039         $LCTL set_param fail_loc=0x1410
26040         cat $dir/file
26041         $LCTL set_param fail_loc=0
26042         rm -rf $dir
26043 }
26044 run_test 419 "Verify open file by name doesn't crash kernel"
26045
26046 test_420()
26047 {
26048         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26049                 skip "Need MDS version at least 2.12.53"
26050
26051         local SAVE_UMASK=$(umask)
26052         local dir=$DIR/$tdir
26053         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26054
26055         mkdir -p $dir
26056         umask 0000
26057         mkdir -m03777 $dir/testdir
26058         ls -dn $dir/testdir
26059         # Need to remove trailing '.' when SELinux is enabled
26060         local dirperms=$(ls -dn $dir/testdir |
26061                          awk '{ sub(/\.$/, "", $1); print $1}')
26062         [ $dirperms == "drwxrwsrwt" ] ||
26063                 error "incorrect perms on $dir/testdir"
26064
26065         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26066                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26067         ls -n $dir/testdir/testfile
26068         local fileperms=$(ls -n $dir/testdir/testfile |
26069                           awk '{ sub(/\.$/, "", $1); print $1}')
26070         [ $fileperms == "-rwxr-xr-x" ] ||
26071                 error "incorrect perms on $dir/testdir/testfile"
26072
26073         umask $SAVE_UMASK
26074 }
26075 run_test 420 "clear SGID bit on non-directories for non-members"
26076
26077 test_421a() {
26078         local cnt
26079         local fid1
26080         local fid2
26081
26082         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26083                 skip "Need MDS version at least 2.12.54"
26084
26085         test_mkdir $DIR/$tdir
26086         createmany -o $DIR/$tdir/f 3
26087         cnt=$(ls -1 $DIR/$tdir | wc -l)
26088         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26089
26090         fid1=$(lfs path2fid $DIR/$tdir/f1)
26091         fid2=$(lfs path2fid $DIR/$tdir/f2)
26092         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26093
26094         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26095         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26096
26097         cnt=$(ls -1 $DIR/$tdir | wc -l)
26098         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26099
26100         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26101         createmany -o $DIR/$tdir/f 3
26102         cnt=$(ls -1 $DIR/$tdir | wc -l)
26103         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26104
26105         fid1=$(lfs path2fid $DIR/$tdir/f1)
26106         fid2=$(lfs path2fid $DIR/$tdir/f2)
26107         echo "remove using fsname $FSNAME"
26108         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26109
26110         cnt=$(ls -1 $DIR/$tdir | wc -l)
26111         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26112 }
26113 run_test 421a "simple rm by fid"
26114
26115 test_421b() {
26116         local cnt
26117         local FID1
26118         local FID2
26119
26120         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26121                 skip "Need MDS version at least 2.12.54"
26122
26123         test_mkdir $DIR/$tdir
26124         createmany -o $DIR/$tdir/f 3
26125         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26126         MULTIPID=$!
26127
26128         FID1=$(lfs path2fid $DIR/$tdir/f1)
26129         FID2=$(lfs path2fid $DIR/$tdir/f2)
26130         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26131
26132         kill -USR1 $MULTIPID
26133         wait
26134
26135         cnt=$(ls $DIR/$tdir | wc -l)
26136         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26137 }
26138 run_test 421b "rm by fid on open file"
26139
26140 test_421c() {
26141         local cnt
26142         local FIDS
26143
26144         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26145                 skip "Need MDS version at least 2.12.54"
26146
26147         test_mkdir $DIR/$tdir
26148         createmany -o $DIR/$tdir/f 3
26149         touch $DIR/$tdir/$tfile
26150         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26151         cnt=$(ls -1 $DIR/$tdir | wc -l)
26152         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26153
26154         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26155         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26156
26157         cnt=$(ls $DIR/$tdir | wc -l)
26158         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26159 }
26160 run_test 421c "rm by fid against hardlinked files"
26161
26162 test_421d() {
26163         local cnt
26164         local FIDS
26165
26166         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26167                 skip "Need MDS version at least 2.12.54"
26168
26169         test_mkdir $DIR/$tdir
26170         createmany -o $DIR/$tdir/f 4097
26171         cnt=$(ls -1 $DIR/$tdir | wc -l)
26172         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26173
26174         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26175         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26176
26177         cnt=$(ls $DIR/$tdir | wc -l)
26178         rm -rf $DIR/$tdir
26179         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26180 }
26181 run_test 421d "rmfid en masse"
26182
26183 test_421e() {
26184         local cnt
26185         local FID
26186
26187         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26188         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26189                 skip "Need MDS version at least 2.12.54"
26190
26191         mkdir -p $DIR/$tdir
26192         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26193         createmany -o $DIR/$tdir/striped_dir/f 512
26194         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26195         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26196
26197         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26198                 sed "s/[/][^:]*://g")
26199         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26200
26201         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26202         rm -rf $DIR/$tdir
26203         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26204 }
26205 run_test 421e "rmfid in DNE"
26206
26207 test_421f() {
26208         local cnt
26209         local FID
26210
26211         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26212                 skip "Need MDS version at least 2.12.54"
26213
26214         test_mkdir $DIR/$tdir
26215         touch $DIR/$tdir/f
26216         cnt=$(ls -1 $DIR/$tdir | wc -l)
26217         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26218
26219         FID=$(lfs path2fid $DIR/$tdir/f)
26220         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26221         # rmfid should fail
26222         cnt=$(ls -1 $DIR/$tdir | wc -l)
26223         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26224
26225         chmod a+rw $DIR/$tdir
26226         ls -la $DIR/$tdir
26227         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26228         # rmfid should fail
26229         cnt=$(ls -1 $DIR/$tdir | wc -l)
26230         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26231
26232         rm -f $DIR/$tdir/f
26233         $RUNAS touch $DIR/$tdir/f
26234         FID=$(lfs path2fid $DIR/$tdir/f)
26235         echo "rmfid as root"
26236         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26237         cnt=$(ls -1 $DIR/$tdir | wc -l)
26238         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26239
26240         rm -f $DIR/$tdir/f
26241         $RUNAS touch $DIR/$tdir/f
26242         cnt=$(ls -1 $DIR/$tdir | wc -l)
26243         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26244         FID=$(lfs path2fid $DIR/$tdir/f)
26245         # rmfid w/o user_fid2path mount option should fail
26246         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26247         cnt=$(ls -1 $DIR/$tdir | wc -l)
26248         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26249
26250         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26251         stack_trap "rmdir $tmpdir"
26252         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26253                 error "failed to mount client'"
26254         stack_trap "umount_client $tmpdir"
26255
26256         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26257         # rmfid should succeed
26258         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26259         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26260
26261         # rmfid shouldn't allow to remove files due to dir's permission
26262         chmod a+rwx $tmpdir/$tdir
26263         touch $tmpdir/$tdir/f
26264         ls -la $tmpdir/$tdir
26265         FID=$(lfs path2fid $tmpdir/$tdir/f)
26266         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26267         return 0
26268 }
26269 run_test 421f "rmfid checks permissions"
26270
26271 test_421g() {
26272         local cnt
26273         local FIDS
26274
26275         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26276         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26277                 skip "Need MDS version at least 2.12.54"
26278
26279         mkdir -p $DIR/$tdir
26280         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26281         createmany -o $DIR/$tdir/striped_dir/f 512
26282         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26283         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26284
26285         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26286                 sed "s/[/][^:]*://g")
26287
26288         rm -f $DIR/$tdir/striped_dir/f1*
26289         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26290         removed=$((512 - cnt))
26291
26292         # few files have been just removed, so we expect
26293         # rmfid to fail on their fids
26294         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26295         [ $removed != $errors ] && error "$errors != $removed"
26296
26297         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26298         rm -rf $DIR/$tdir
26299         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26300 }
26301 run_test 421g "rmfid to return errors properly"
26302
26303 test_422() {
26304         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26305         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26306         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26307         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26308         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26309
26310         local amc=$(at_max_get client)
26311         local amo=$(at_max_get mds1)
26312         local timeout=`lctl get_param -n timeout`
26313
26314         at_max_set 0 client
26315         at_max_set 0 mds1
26316
26317 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26318         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26319                         fail_val=$(((2*timeout + 10)*1000))
26320         touch $DIR/$tdir/d3/file &
26321         sleep 2
26322 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26323         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26324                         fail_val=$((2*timeout + 5))
26325         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26326         local pid=$!
26327         sleep 1
26328         kill -9 $pid
26329         sleep $((2 * timeout))
26330         echo kill $pid
26331         kill -9 $pid
26332         lctl mark touch
26333         touch $DIR/$tdir/d2/file3
26334         touch $DIR/$tdir/d2/file4
26335         touch $DIR/$tdir/d2/file5
26336
26337         wait
26338         at_max_set $amc client
26339         at_max_set $amo mds1
26340
26341         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26342         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26343                 error "Watchdog is always throttled"
26344 }
26345 run_test 422 "kill a process with RPC in progress"
26346
26347 stat_test() {
26348     df -h $MOUNT &
26349     df -h $MOUNT &
26350     df -h $MOUNT &
26351     df -h $MOUNT &
26352     df -h $MOUNT &
26353     df -h $MOUNT &
26354 }
26355
26356 test_423() {
26357     local _stats
26358     # ensure statfs cache is expired
26359     sleep 2;
26360
26361     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26362     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26363
26364     return 0
26365 }
26366 run_test 423 "statfs should return a right data"
26367
26368 test_424() {
26369 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26370         $LCTL set_param fail_loc=0x80000522
26371         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26372         rm -f $DIR/$tfile
26373 }
26374 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26375
26376 test_425() {
26377         test_mkdir -c -1 $DIR/$tdir
26378         $LFS setstripe -c -1 $DIR/$tdir
26379
26380         lru_resize_disable "" 100
26381         stack_trap "lru_resize_enable" EXIT
26382
26383         sleep 5
26384
26385         for i in $(seq $((MDSCOUNT * 125))); do
26386                 local t=$DIR/$tdir/$tfile_$i
26387
26388                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26389                         error_noexit "Create file $t"
26390         done
26391         stack_trap "rm -rf $DIR/$tdir" EXIT
26392
26393         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26394                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26395                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26396
26397                 [ $lock_count -le $lru_size ] ||
26398                         error "osc lock count $lock_count > lru size $lru_size"
26399         done
26400
26401         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26402                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26403                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26404
26405                 [ $lock_count -le $lru_size ] ||
26406                         error "mdc lock count $lock_count > lru size $lru_size"
26407         done
26408 }
26409 run_test 425 "lock count should not exceed lru size"
26410
26411 test_426() {
26412         splice-test -r $DIR/$tfile
26413         splice-test -rd $DIR/$tfile
26414         splice-test $DIR/$tfile
26415         splice-test -d $DIR/$tfile
26416 }
26417 run_test 426 "splice test on Lustre"
26418
26419 test_427() {
26420         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26421         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26422                 skip "Need MDS version at least 2.12.4"
26423         local log
26424
26425         mkdir $DIR/$tdir
26426         mkdir $DIR/$tdir/1
26427         mkdir $DIR/$tdir/2
26428         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26429         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26430
26431         $LFS getdirstripe $DIR/$tdir/1/dir
26432
26433         #first setfattr for creating updatelog
26434         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26435
26436 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26437         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26438         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26439         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26440
26441         sleep 2
26442         fail mds2
26443         wait_recovery_complete mds2 $((2*TIMEOUT))
26444
26445         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26446         echo $log | grep "get update log failed" &&
26447                 error "update log corruption is detected" || true
26448 }
26449 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26450
26451 test_428() {
26452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26453         local cache_limit=$CACHE_MAX
26454
26455         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26456         $LCTL set_param -n llite.*.max_cached_mb=64
26457
26458         mkdir $DIR/$tdir
26459         $LFS setstripe -c 1 $DIR/$tdir
26460         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26461         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26462         #test write
26463         for f in $(seq 4); do
26464                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26465         done
26466         wait
26467
26468         cancel_lru_locks osc
26469         # Test read
26470         for f in $(seq 4); do
26471                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26472         done
26473         wait
26474 }
26475 run_test 428 "large block size IO should not hang"
26476
26477 test_429() { # LU-7915 / LU-10948
26478         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26479         local testfile=$DIR/$tfile
26480         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26481         local new_flag=1
26482         local first_rpc
26483         local second_rpc
26484         local third_rpc
26485
26486         $LCTL get_param $ll_opencache_threshold_count ||
26487                 skip "client does not have opencache parameter"
26488
26489         set_opencache $new_flag
26490         stack_trap "restore_opencache"
26491         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26492                 error "enable opencache failed"
26493         touch $testfile
26494         # drop MDC DLM locks
26495         cancel_lru_locks mdc
26496         # clear MDC RPC stats counters
26497         $LCTL set_param $mdc_rpcstats=clear
26498
26499         # According to the current implementation, we need to run 3 times
26500         # open & close file to verify if opencache is enabled correctly.
26501         # 1st, RPCs are sent for lookup/open and open handle is released on
26502         #      close finally.
26503         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26504         #      so open handle won't be released thereafter.
26505         # 3rd, No RPC is sent out.
26506         $MULTIOP $testfile oc || error "multiop failed"
26507         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26508         echo "1st: $first_rpc RPCs in flight"
26509
26510         $MULTIOP $testfile oc || error "multiop failed"
26511         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26512         echo "2nd: $second_rpc RPCs in flight"
26513
26514         $MULTIOP $testfile oc || error "multiop failed"
26515         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26516         echo "3rd: $third_rpc RPCs in flight"
26517
26518         #verify no MDC RPC is sent
26519         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26520 }
26521 run_test 429 "verify if opencache flag on client side does work"
26522
26523 lseek_test_430() {
26524         local offset
26525         local file=$1
26526
26527         # data at [200K, 400K)
26528         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26529                 error "256K->512K dd fails"
26530         # data at [2M, 3M)
26531         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26532                 error "2M->3M dd fails"
26533         # data at [4M, 5M)
26534         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26535                 error "4M->5M dd fails"
26536         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26537         # start at first component hole #1
26538         printf "Seeking hole from 1000 ... "
26539         offset=$(lseek_test -l 1000 $file)
26540         echo $offset
26541         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26542         printf "Seeking data from 1000 ... "
26543         offset=$(lseek_test -d 1000 $file)
26544         echo $offset
26545         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26546
26547         # start at first component data block
26548         printf "Seeking hole from 300000 ... "
26549         offset=$(lseek_test -l 300000 $file)
26550         echo $offset
26551         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26552         printf "Seeking data from 300000 ... "
26553         offset=$(lseek_test -d 300000 $file)
26554         echo $offset
26555         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26556
26557         # start at the first component but beyond end of object size
26558         printf "Seeking hole from 1000000 ... "
26559         offset=$(lseek_test -l 1000000 $file)
26560         echo $offset
26561         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26562         printf "Seeking data from 1000000 ... "
26563         offset=$(lseek_test -d 1000000 $file)
26564         echo $offset
26565         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26566
26567         # start at second component stripe 2 (empty file)
26568         printf "Seeking hole from 1500000 ... "
26569         offset=$(lseek_test -l 1500000 $file)
26570         echo $offset
26571         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26572         printf "Seeking data from 1500000 ... "
26573         offset=$(lseek_test -d 1500000 $file)
26574         echo $offset
26575         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26576
26577         # start at second component stripe 1 (all data)
26578         printf "Seeking hole from 3000000 ... "
26579         offset=$(lseek_test -l 3000000 $file)
26580         echo $offset
26581         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26582         printf "Seeking data from 3000000 ... "
26583         offset=$(lseek_test -d 3000000 $file)
26584         echo $offset
26585         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26586
26587         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26588                 error "2nd dd fails"
26589         echo "Add data block at 640K...1280K"
26590
26591         # start at before new data block, in hole
26592         printf "Seeking hole from 600000 ... "
26593         offset=$(lseek_test -l 600000 $file)
26594         echo $offset
26595         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26596         printf "Seeking data from 600000 ... "
26597         offset=$(lseek_test -d 600000 $file)
26598         echo $offset
26599         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26600
26601         # start at the first component new data block
26602         printf "Seeking hole from 1000000 ... "
26603         offset=$(lseek_test -l 1000000 $file)
26604         echo $offset
26605         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26606         printf "Seeking data from 1000000 ... "
26607         offset=$(lseek_test -d 1000000 $file)
26608         echo $offset
26609         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26610
26611         # start at second component stripe 2, new data
26612         printf "Seeking hole from 1200000 ... "
26613         offset=$(lseek_test -l 1200000 $file)
26614         echo $offset
26615         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26616         printf "Seeking data from 1200000 ... "
26617         offset=$(lseek_test -d 1200000 $file)
26618         echo $offset
26619         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26620
26621         # start beyond file end
26622         printf "Using offset > filesize ... "
26623         lseek_test -l 4000000 $file && error "lseek should fail"
26624         printf "Using offset > filesize ... "
26625         lseek_test -d 4000000 $file && error "lseek should fail"
26626
26627         printf "Done\n\n"
26628 }
26629
26630 test_430a() {
26631         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26632                 skip "MDT does not support SEEK_HOLE"
26633
26634         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26635                 skip "OST does not support SEEK_HOLE"
26636
26637         local file=$DIR/$tdir/$tfile
26638
26639         mkdir -p $DIR/$tdir
26640
26641         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26642         # OST stripe #1 will have continuous data at [1M, 3M)
26643         # OST stripe #2 is empty
26644         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26645         lseek_test_430 $file
26646         rm $file
26647         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26648         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26649         lseek_test_430 $file
26650         rm $file
26651         $LFS setstripe -c2 -S 512K $file
26652         echo "Two stripes, stripe size 512K"
26653         lseek_test_430 $file
26654         rm $file
26655         # FLR with stale mirror
26656         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26657                        -N -c2 -S 1M $file
26658         echo "Mirrored file:"
26659         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26660         echo "Plain 2 stripes 1M"
26661         lseek_test_430 $file
26662         rm $file
26663 }
26664 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26665
26666 test_430b() {
26667         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26668                 skip "OST does not support SEEK_HOLE"
26669
26670         local offset
26671         local file=$DIR/$tdir/$tfile
26672
26673         mkdir -p $DIR/$tdir
26674         # Empty layout lseek should fail
26675         $MCREATE $file
26676         # seek from 0
26677         printf "Seeking hole from 0 ... "
26678         lseek_test -l 0 $file && error "lseek should fail"
26679         printf "Seeking data from 0 ... "
26680         lseek_test -d 0 $file && error "lseek should fail"
26681         rm $file
26682
26683         # 1M-hole file
26684         $LFS setstripe -E 1M -c2 -E eof $file
26685         $TRUNCATE $file 1048576
26686         printf "Seeking hole from 1000000 ... "
26687         offset=$(lseek_test -l 1000000 $file)
26688         echo $offset
26689         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26690         printf "Seeking data from 1000000 ... "
26691         lseek_test -d 1000000 $file && error "lseek should fail"
26692         rm $file
26693
26694         # full component followed by non-inited one
26695         $LFS setstripe -E 1M -c2 -E eof $file
26696         dd if=/dev/urandom of=$file bs=1M count=1
26697         printf "Seeking hole from 1000000 ... "
26698         offset=$(lseek_test -l 1000000 $file)
26699         echo $offset
26700         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26701         printf "Seeking hole from 1048576 ... "
26702         lseek_test -l 1048576 $file && error "lseek should fail"
26703         # init second component and truncate back
26704         echo "123" >> $file
26705         $TRUNCATE $file 1048576
26706         printf "Seeking hole from 1000000 ... "
26707         offset=$(lseek_test -l 1000000 $file)
26708         echo $offset
26709         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26710         printf "Seeking hole from 1048576 ... "
26711         lseek_test -l 1048576 $file && error "lseek should fail"
26712         # boundary checks for big values
26713         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26714         offset=$(lseek_test -d 0 $file.10g)
26715         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26716         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26717         offset=$(lseek_test -d 0 $file.100g)
26718         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26719         return 0
26720 }
26721 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26722
26723 test_430c() {
26724         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26725                 skip "OST does not support SEEK_HOLE"
26726
26727         local file=$DIR/$tdir/$tfile
26728         local start
26729
26730         mkdir -p $DIR/$tdir
26731         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26732
26733         # cp version 8.33+ prefers lseek over fiemap
26734         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26735                 start=$SECONDS
26736                 time cp $file /dev/null
26737                 (( SECONDS - start < 5 )) ||
26738                         error "cp: too long runtime $((SECONDS - start))"
26739
26740         fi
26741         # tar version 1.29+ supports SEEK_HOLE/DATA
26742         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26743                 start=$SECONDS
26744                 time tar cS $file - | cat > /dev/null
26745                 (( SECONDS - start < 5 )) ||
26746                         error "tar: too long runtime $((SECONDS - start))"
26747         fi
26748 }
26749 run_test 430c "lseek: external tools check"
26750
26751 test_431() { # LU-14187
26752         local file=$DIR/$tdir/$tfile
26753
26754         mkdir -p $DIR/$tdir
26755         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26756         dd if=/dev/urandom of=$file bs=4k count=1
26757         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26758         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26759         #define OBD_FAIL_OST_RESTART_IO 0x251
26760         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26761         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26762         cp $file $file.0
26763         cancel_lru_locks
26764         sync_all_data
26765         echo 3 > /proc/sys/vm/drop_caches
26766         diff  $file $file.0 || error "data diff"
26767 }
26768 run_test 431 "Restart transaction for IO"
26769
26770 cleanup_test_432() {
26771         do_facet mgs $LCTL nodemap_activate 0
26772         wait_nm_sync active
26773 }
26774
26775 test_432() {
26776         local tmpdir=$TMP/dir432
26777
26778         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26779                 skip "Need MDS version at least 2.14.52"
26780
26781         stack_trap cleanup_test_432 EXIT
26782         mkdir $DIR/$tdir
26783         mkdir $tmpdir
26784
26785         do_facet mgs $LCTL nodemap_activate 1
26786         wait_nm_sync active
26787         do_facet mgs $LCTL nodemap_modify --name default \
26788                 --property admin --value 1
26789         do_facet mgs $LCTL nodemap_modify --name default \
26790                 --property trusted --value 1
26791         cancel_lru_locks mdc
26792         wait_nm_sync default admin_nodemap
26793         wait_nm_sync default trusted_nodemap
26794
26795         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26796                grep -ci "Operation not permitted") -ne 0 ]; then
26797                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26798         fi
26799 }
26800 run_test 432 "mv dir from outside Lustre"
26801
26802 prep_801() {
26803         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26804         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26805                 skip "Need server version at least 2.9.55"
26806
26807         start_full_debug_logging
26808 }
26809
26810 post_801() {
26811         stop_full_debug_logging
26812 }
26813
26814 barrier_stat() {
26815         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26816                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26817                            awk '/The barrier for/ { print $7 }')
26818                 echo $st
26819         else
26820                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26821                 echo \'$st\'
26822         fi
26823 }
26824
26825 barrier_expired() {
26826         local expired
26827
26828         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26829                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26830                           awk '/will be expired/ { print $7 }')
26831         else
26832                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26833         fi
26834
26835         echo $expired
26836 }
26837
26838 test_801a() {
26839         prep_801
26840
26841         echo "Start barrier_freeze at: $(date)"
26842         #define OBD_FAIL_BARRIER_DELAY          0x2202
26843         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26844         # Do not reduce barrier time - See LU-11873
26845         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26846
26847         sleep 2
26848         local b_status=$(barrier_stat)
26849         echo "Got barrier status at: $(date)"
26850         [ "$b_status" = "'freezing_p1'" ] ||
26851                 error "(1) unexpected barrier status $b_status"
26852
26853         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26854         wait
26855         b_status=$(barrier_stat)
26856         [ "$b_status" = "'frozen'" ] ||
26857                 error "(2) unexpected barrier status $b_status"
26858
26859         local expired=$(barrier_expired)
26860         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26861         sleep $((expired + 3))
26862
26863         b_status=$(barrier_stat)
26864         [ "$b_status" = "'expired'" ] ||
26865                 error "(3) unexpected barrier status $b_status"
26866
26867         # Do not reduce barrier time - See LU-11873
26868         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26869                 error "(4) fail to freeze barrier"
26870
26871         b_status=$(barrier_stat)
26872         [ "$b_status" = "'frozen'" ] ||
26873                 error "(5) unexpected barrier status $b_status"
26874
26875         echo "Start barrier_thaw at: $(date)"
26876         #define OBD_FAIL_BARRIER_DELAY          0x2202
26877         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26878         do_facet mgs $LCTL barrier_thaw $FSNAME &
26879
26880         sleep 2
26881         b_status=$(barrier_stat)
26882         echo "Got barrier status at: $(date)"
26883         [ "$b_status" = "'thawing'" ] ||
26884                 error "(6) unexpected barrier status $b_status"
26885
26886         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26887         wait
26888         b_status=$(barrier_stat)
26889         [ "$b_status" = "'thawed'" ] ||
26890                 error "(7) unexpected barrier status $b_status"
26891
26892         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26893         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26894         do_facet mgs $LCTL barrier_freeze $FSNAME
26895
26896         b_status=$(barrier_stat)
26897         [ "$b_status" = "'failed'" ] ||
26898                 error "(8) unexpected barrier status $b_status"
26899
26900         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26901         do_facet mgs $LCTL barrier_thaw $FSNAME
26902
26903         post_801
26904 }
26905 run_test 801a "write barrier user interfaces and stat machine"
26906
26907 test_801b() {
26908         prep_801
26909
26910         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26911         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
26912         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26913         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26914         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26915
26916         cancel_lru_locks mdc
26917
26918         # 180 seconds should be long enough
26919         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26920
26921         local b_status=$(barrier_stat)
26922         [ "$b_status" = "'frozen'" ] ||
26923                 error "(6) unexpected barrier status $b_status"
26924
26925         mkdir $DIR/$tdir/d0/d10 &
26926         mkdir_pid=$!
26927
26928         touch $DIR/$tdir/d1/f13 &
26929         touch_pid=$!
26930
26931         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26932         ln_pid=$!
26933
26934         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26935         mv_pid=$!
26936
26937         rm -f $DIR/$tdir/d4/f12 &
26938         rm_pid=$!
26939
26940         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26941
26942         # To guarantee taht the 'stat' is not blocked
26943         b_status=$(barrier_stat)
26944         [ "$b_status" = "'frozen'" ] ||
26945                 error "(8) unexpected barrier status $b_status"
26946
26947         # let above commands to run at background
26948         sleep 5
26949
26950         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26951         ps -p $touch_pid || error "(10) touch should be blocked"
26952         ps -p $ln_pid || error "(11) link should be blocked"
26953         ps -p $mv_pid || error "(12) rename should be blocked"
26954         ps -p $rm_pid || error "(13) unlink should be blocked"
26955
26956         b_status=$(barrier_stat)
26957         [ "$b_status" = "'frozen'" ] ||
26958                 error "(14) unexpected barrier status $b_status"
26959
26960         do_facet mgs $LCTL barrier_thaw $FSNAME
26961         b_status=$(barrier_stat)
26962         [ "$b_status" = "'thawed'" ] ||
26963                 error "(15) unexpected barrier status $b_status"
26964
26965         wait $mkdir_pid || error "(16) mkdir should succeed"
26966         wait $touch_pid || error "(17) touch should succeed"
26967         wait $ln_pid || error "(18) link should succeed"
26968         wait $mv_pid || error "(19) rename should succeed"
26969         wait $rm_pid || error "(20) unlink should succeed"
26970
26971         post_801
26972 }
26973 run_test 801b "modification will be blocked by write barrier"
26974
26975 test_801c() {
26976         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26977
26978         prep_801
26979
26980         stop mds2 || error "(1) Fail to stop mds2"
26981
26982         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26983
26984         local b_status=$(barrier_stat)
26985         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26986                 do_facet mgs $LCTL barrier_thaw $FSNAME
26987                 error "(2) unexpected barrier status $b_status"
26988         }
26989
26990         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26991                 error "(3) Fail to rescan barrier bitmap"
26992
26993         # Do not reduce barrier time - See LU-11873
26994         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26995
26996         b_status=$(barrier_stat)
26997         [ "$b_status" = "'frozen'" ] ||
26998                 error "(4) unexpected barrier status $b_status"
26999
27000         do_facet mgs $LCTL barrier_thaw $FSNAME
27001         b_status=$(barrier_stat)
27002         [ "$b_status" = "'thawed'" ] ||
27003                 error "(5) unexpected barrier status $b_status"
27004
27005         local devname=$(mdsdevname 2)
27006
27007         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27008
27009         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27010                 error "(7) Fail to rescan barrier bitmap"
27011
27012         post_801
27013 }
27014 run_test 801c "rescan barrier bitmap"
27015
27016 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27017 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27018 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27019 saved_MOUNT_OPTS=$MOUNT_OPTS
27020
27021 cleanup_802a() {
27022         trap 0
27023
27024         stopall
27025         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27026         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27027         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27028         MOUNT_OPTS=$saved_MOUNT_OPTS
27029         setupall
27030 }
27031
27032 test_802a() {
27033         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27034         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27035         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27036                 skip "Need server version at least 2.9.55"
27037
27038         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27039
27040         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27041
27042         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27043                 error "(2) Fail to copy"
27044
27045         trap cleanup_802a EXIT
27046
27047         # sync by force before remount as readonly
27048         sync; sync_all_data; sleep 3; sync_all_data
27049
27050         stopall
27051
27052         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27053         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27054         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27055
27056         echo "Mount the server as read only"
27057         setupall server_only || error "(3) Fail to start servers"
27058
27059         echo "Mount client without ro should fail"
27060         mount_client $MOUNT &&
27061                 error "(4) Mount client without 'ro' should fail"
27062
27063         echo "Mount client with ro should succeed"
27064         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27065         mount_client $MOUNT ||
27066                 error "(5) Mount client with 'ro' should succeed"
27067
27068         echo "Modify should be refused"
27069         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27070
27071         echo "Read should be allowed"
27072         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27073                 error "(7) Read should succeed under ro mode"
27074
27075         cleanup_802a
27076 }
27077 run_test 802a "simulate readonly device"
27078
27079 test_802b() {
27080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27081         remote_mds_nodsh && skip "remote MDS with nodsh"
27082
27083         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27084                 skip "readonly option not available"
27085
27086         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27087
27088         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27089                 error "(2) Fail to copy"
27090
27091         # write back all cached data before setting MDT to readonly
27092         cancel_lru_locks
27093         sync_all_data
27094
27095         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27096         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27097
27098         echo "Modify should be refused"
27099         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27100
27101         echo "Read should be allowed"
27102         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27103                 error "(7) Read should succeed under ro mode"
27104
27105         # disable readonly
27106         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27107 }
27108 run_test 802b "be able to set MDTs to readonly"
27109
27110 test_803a() {
27111         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27112         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27113                 skip "MDS needs to be newer than 2.10.54"
27114
27115         mkdir_on_mdt0 $DIR/$tdir
27116         # Create some objects on all MDTs to trigger related logs objects
27117         for idx in $(seq $MDSCOUNT); do
27118                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27119                         $DIR/$tdir/dir${idx} ||
27120                         error "Fail to create $DIR/$tdir/dir${idx}"
27121         done
27122
27123         sync; sleep 3
27124         wait_delete_completed # ensure old test cleanups are finished
27125         echo "before create:"
27126         $LFS df -i $MOUNT
27127         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27128
27129         for i in {1..10}; do
27130                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27131                         error "Fail to create $DIR/$tdir/foo$i"
27132         done
27133
27134         sync; sleep 3
27135         echo "after create:"
27136         $LFS df -i $MOUNT
27137         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27138
27139         # allow for an llog to be cleaned up during the test
27140         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27141                 error "before ($before_used) + 10 > after ($after_used)"
27142
27143         for i in {1..10}; do
27144                 rm -rf $DIR/$tdir/foo$i ||
27145                         error "Fail to remove $DIR/$tdir/foo$i"
27146         done
27147
27148         sleep 3 # avoid MDT return cached statfs
27149         wait_delete_completed
27150         echo "after unlink:"
27151         $LFS df -i $MOUNT
27152         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27153
27154         # allow for an llog to be created during the test
27155         [ $after_used -le $((before_used + 1)) ] ||
27156                 error "after ($after_used) > before ($before_used) + 1"
27157 }
27158 run_test 803a "verify agent object for remote object"
27159
27160 test_803b() {
27161         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27162         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27163                 skip "MDS needs to be newer than 2.13.56"
27164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27165
27166         for i in $(seq 0 $((MDSCOUNT - 1))); do
27167                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27168         done
27169
27170         local before=0
27171         local after=0
27172
27173         local tmp
27174
27175         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27176         for i in $(seq 0 $((MDSCOUNT - 1))); do
27177                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27178                         awk '/getattr/ { print $2 }')
27179                 before=$((before + tmp))
27180         done
27181         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27182         for i in $(seq 0 $((MDSCOUNT - 1))); do
27183                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27184                         awk '/getattr/ { print $2 }')
27185                 after=$((after + tmp))
27186         done
27187
27188         [ $before -eq $after ] || error "getattr count $before != $after"
27189 }
27190 run_test 803b "remote object can getattr from cache"
27191
27192 test_804() {
27193         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27194         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27195                 skip "MDS needs to be newer than 2.10.54"
27196         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27197
27198         mkdir -p $DIR/$tdir
27199         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27200                 error "Fail to create $DIR/$tdir/dir0"
27201
27202         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27203         local dev=$(mdsdevname 2)
27204
27205         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27206                 grep ${fid} || error "NOT found agent entry for dir0"
27207
27208         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27209                 error "Fail to create $DIR/$tdir/dir1"
27210
27211         touch $DIR/$tdir/dir1/foo0 ||
27212                 error "Fail to create $DIR/$tdir/dir1/foo0"
27213         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27214         local rc=0
27215
27216         for idx in $(seq $MDSCOUNT); do
27217                 dev=$(mdsdevname $idx)
27218                 do_facet mds${idx} \
27219                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27220                         grep ${fid} && rc=$idx
27221         done
27222
27223         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27224                 error "Fail to rename foo0 to foo1"
27225         if [ $rc -eq 0 ]; then
27226                 for idx in $(seq $MDSCOUNT); do
27227                         dev=$(mdsdevname $idx)
27228                         do_facet mds${idx} \
27229                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27230                         grep ${fid} && rc=$idx
27231                 done
27232         fi
27233
27234         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27235                 error "Fail to rename foo1 to foo2"
27236         if [ $rc -eq 0 ]; then
27237                 for idx in $(seq $MDSCOUNT); do
27238                         dev=$(mdsdevname $idx)
27239                         do_facet mds${idx} \
27240                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27241                         grep ${fid} && rc=$idx
27242                 done
27243         fi
27244
27245         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27246
27247         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27248                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27249         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27250                 error "Fail to rename foo2 to foo0"
27251         unlink $DIR/$tdir/dir1/foo0 ||
27252                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27253         rm -rf $DIR/$tdir/dir0 ||
27254                 error "Fail to rm $DIR/$tdir/dir0"
27255
27256         for idx in $(seq $MDSCOUNT); do
27257                 rc=0
27258
27259                 stop mds${idx}
27260                 dev=$(mdsdevname $idx)
27261                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27262                         rc=$?
27263                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27264                         error "mount mds$idx failed"
27265                 df $MOUNT > /dev/null 2>&1
27266
27267                 # e2fsck should not return error
27268                 [ $rc -eq 0 ] ||
27269                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27270         done
27271 }
27272 run_test 804 "verify agent entry for remote entry"
27273
27274 cleanup_805() {
27275         do_facet $SINGLEMDS zfs set quota=$old $fsset
27276         unlinkmany $DIR/$tdir/f- 1000000
27277         trap 0
27278 }
27279
27280 test_805() {
27281         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27282         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27283         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27284                 skip "netfree not implemented before 0.7"
27285         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27286                 skip "Need MDS version at least 2.10.57"
27287
27288         local fsset
27289         local freekb
27290         local usedkb
27291         local old
27292         local quota
27293         local pref="osd-zfs.$FSNAME-MDT0000."
27294
27295         # limit available space on MDS dataset to meet nospace issue
27296         # quickly. then ZFS 0.7.2 can use reserved space if asked
27297         # properly (using netfree flag in osd_declare_destroy()
27298         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27299         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27300                 gawk '{print $3}')
27301         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27302         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27303         let "usedkb=usedkb-freekb"
27304         let "freekb=freekb/2"
27305         if let "freekb > 5000"; then
27306                 let "freekb=5000"
27307         fi
27308         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27309         trap cleanup_805 EXIT
27310         mkdir_on_mdt0 $DIR/$tdir
27311         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27312                 error "Can't set PFL layout"
27313         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27314         rm -rf $DIR/$tdir || error "not able to remove"
27315         do_facet $SINGLEMDS zfs set quota=$old $fsset
27316         trap 0
27317 }
27318 run_test 805 "ZFS can remove from full fs"
27319
27320 # Size-on-MDS test
27321 check_lsom_data()
27322 {
27323         local file=$1
27324         local expect=$(stat -c %s $file)
27325
27326         check_lsom_size $1 $expect
27327
27328         local blocks=$($LFS getsom -b $file)
27329         expect=$(stat -c %b $file)
27330         [[ $blocks == $expect ]] ||
27331                 error "$file expected blocks: $expect, got: $blocks"
27332 }
27333
27334 check_lsom_size()
27335 {
27336         local size
27337         local expect=$2
27338
27339         cancel_lru_locks mdc
27340
27341         size=$($LFS getsom -s $1)
27342         [[ $size == $expect ]] ||
27343                 error "$file expected size: $expect, got: $size"
27344 }
27345
27346 test_806() {
27347         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27348                 skip "Need MDS version at least 2.11.52"
27349
27350         local bs=1048576
27351
27352         touch $DIR/$tfile || error "touch $tfile failed"
27353
27354         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27355         save_lustre_params client "llite.*.xattr_cache" > $save
27356         lctl set_param llite.*.xattr_cache=0
27357         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27358
27359         # single-threaded write
27360         echo "Test SOM for single-threaded write"
27361         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27362                 error "write $tfile failed"
27363         check_lsom_size $DIR/$tfile $bs
27364
27365         local num=32
27366         local size=$(($num * $bs))
27367         local offset=0
27368         local i
27369
27370         echo "Test SOM for single client multi-threaded($num) write"
27371         $TRUNCATE $DIR/$tfile 0
27372         for ((i = 0; i < $num; i++)); do
27373                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27374                 local pids[$i]=$!
27375                 offset=$((offset + $bs))
27376         done
27377         for (( i=0; i < $num; i++ )); do
27378                 wait ${pids[$i]}
27379         done
27380         check_lsom_size $DIR/$tfile $size
27381
27382         $TRUNCATE $DIR/$tfile 0
27383         for ((i = 0; i < $num; i++)); do
27384                 offset=$((offset - $bs))
27385                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27386                 local pids[$i]=$!
27387         done
27388         for (( i=0; i < $num; i++ )); do
27389                 wait ${pids[$i]}
27390         done
27391         check_lsom_size $DIR/$tfile $size
27392
27393         # multi-client writes
27394         num=$(get_node_count ${CLIENTS//,/ })
27395         size=$(($num * $bs))
27396         offset=0
27397         i=0
27398
27399         echo "Test SOM for multi-client ($num) writes"
27400         $TRUNCATE $DIR/$tfile 0
27401         for client in ${CLIENTS//,/ }; do
27402                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27403                 local pids[$i]=$!
27404                 i=$((i + 1))
27405                 offset=$((offset + $bs))
27406         done
27407         for (( i=0; i < $num; i++ )); do
27408                 wait ${pids[$i]}
27409         done
27410         check_lsom_size $DIR/$tfile $offset
27411
27412         i=0
27413         $TRUNCATE $DIR/$tfile 0
27414         for client in ${CLIENTS//,/ }; do
27415                 offset=$((offset - $bs))
27416                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27417                 local pids[$i]=$!
27418                 i=$((i + 1))
27419         done
27420         for (( i=0; i < $num; i++ )); do
27421                 wait ${pids[$i]}
27422         done
27423         check_lsom_size $DIR/$tfile $size
27424
27425         # verify truncate
27426         echo "Test SOM for truncate"
27427         $TRUNCATE $DIR/$tfile 1048576
27428         check_lsom_size $DIR/$tfile 1048576
27429         $TRUNCATE $DIR/$tfile 1234
27430         check_lsom_size $DIR/$tfile 1234
27431
27432         # verify SOM blocks count
27433         echo "Verify SOM block count"
27434         $TRUNCATE $DIR/$tfile 0
27435         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27436                 error "failed to write file $tfile"
27437         check_lsom_data $DIR/$tfile
27438 }
27439 run_test 806 "Verify Lazy Size on MDS"
27440
27441 test_807() {
27442         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27443         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27444                 skip "Need MDS version at least 2.11.52"
27445
27446         # Registration step
27447         changelog_register || error "changelog_register failed"
27448         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27449         changelog_users $SINGLEMDS | grep -q $cl_user ||
27450                 error "User $cl_user not found in changelog_users"
27451
27452         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27453         save_lustre_params client "llite.*.xattr_cache" > $save
27454         lctl set_param llite.*.xattr_cache=0
27455         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27456
27457         rm -rf $DIR/$tdir || error "rm $tdir failed"
27458         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27459         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27460         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27461         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27462                 error "truncate $tdir/trunc failed"
27463
27464         local bs=1048576
27465         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27466                 error "write $tfile failed"
27467
27468         # multi-client wirtes
27469         local num=$(get_node_count ${CLIENTS//,/ })
27470         local offset=0
27471         local i=0
27472
27473         echo "Test SOM for multi-client ($num) writes"
27474         touch $DIR/$tfile || error "touch $tfile failed"
27475         $TRUNCATE $DIR/$tfile 0
27476         for client in ${CLIENTS//,/ }; do
27477                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27478                 local pids[$i]=$!
27479                 i=$((i + 1))
27480                 offset=$((offset + $bs))
27481         done
27482         for (( i=0; i < $num; i++ )); do
27483                 wait ${pids[$i]}
27484         done
27485
27486         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27487         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27488         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27489         check_lsom_data $DIR/$tdir/trunc
27490         check_lsom_data $DIR/$tdir/single_dd
27491         check_lsom_data $DIR/$tfile
27492
27493         rm -rf $DIR/$tdir
27494         # Deregistration step
27495         changelog_deregister || error "changelog_deregister failed"
27496 }
27497 run_test 807 "verify LSOM syncing tool"
27498
27499 check_som_nologged()
27500 {
27501         local lines=$($LFS changelog $FSNAME-MDT0000 |
27502                 grep 'x=trusted.som' | wc -l)
27503         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27504 }
27505
27506 test_808() {
27507         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27508                 skip "Need MDS version at least 2.11.55"
27509
27510         # Registration step
27511         changelog_register || error "changelog_register failed"
27512
27513         touch $DIR/$tfile || error "touch $tfile failed"
27514         check_som_nologged
27515
27516         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27517                 error "write $tfile failed"
27518         check_som_nologged
27519
27520         $TRUNCATE $DIR/$tfile 1234
27521         check_som_nologged
27522
27523         $TRUNCATE $DIR/$tfile 1048576
27524         check_som_nologged
27525
27526         # Deregistration step
27527         changelog_deregister || error "changelog_deregister failed"
27528 }
27529 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27530
27531 check_som_nodata()
27532 {
27533         $LFS getsom $1
27534         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27535 }
27536
27537 test_809() {
27538         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27539                 skip "Need MDS version at least 2.11.56"
27540
27541         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27542                 error "failed to create DoM-only file $DIR/$tfile"
27543         touch $DIR/$tfile || error "touch $tfile failed"
27544         check_som_nodata $DIR/$tfile
27545
27546         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27547                 error "write $tfile failed"
27548         check_som_nodata $DIR/$tfile
27549
27550         $TRUNCATE $DIR/$tfile 1234
27551         check_som_nodata $DIR/$tfile
27552
27553         $TRUNCATE $DIR/$tfile 4097
27554         check_som_nodata $DIR/$file
27555 }
27556 run_test 809 "Verify no SOM xattr store for DoM-only files"
27557
27558 test_810() {
27559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27560         $GSS && skip_env "could not run with gss"
27561         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27562                 skip "OST < 2.12.58 doesn't align checksum"
27563
27564         set_checksums 1
27565         stack_trap "set_checksums $ORIG_CSUM" EXIT
27566         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27567
27568         local csum
27569         local before
27570         local after
27571         for csum in $CKSUM_TYPES; do
27572                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27573                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27574                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27575                         eval set -- $i
27576                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27577                         before=$(md5sum $DIR/$tfile)
27578                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27579                         after=$(md5sum $DIR/$tfile)
27580                         [ "$before" == "$after" ] ||
27581                                 error "$csum: $before != $after bs=$1 seek=$2"
27582                 done
27583         done
27584 }
27585 run_test 810 "partial page writes on ZFS (LU-11663)"
27586
27587 test_812a() {
27588         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27589                 skip "OST < 2.12.51 doesn't support this fail_loc"
27590
27591         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27592         # ensure ost1 is connected
27593         stat $DIR/$tfile >/dev/null || error "can't stat"
27594         wait_osc_import_state client ost1 FULL
27595         # no locks, no reqs to let the connection idle
27596         cancel_lru_locks osc
27597
27598         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27599 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27600         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27601         wait_osc_import_state client ost1 CONNECTING
27602         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27603
27604         stat $DIR/$tfile >/dev/null || error "can't stat file"
27605 }
27606 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27607
27608 test_812b() { # LU-12378
27609         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27610                 skip "OST < 2.12.51 doesn't support this fail_loc"
27611
27612         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27613         # ensure ost1 is connected
27614         stat $DIR/$tfile >/dev/null || error "can't stat"
27615         wait_osc_import_state client ost1 FULL
27616         # no locks, no reqs to let the connection idle
27617         cancel_lru_locks osc
27618
27619         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27620 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27621         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27622         wait_osc_import_state client ost1 CONNECTING
27623         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27624
27625         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27626         wait_osc_import_state client ost1 IDLE
27627 }
27628 run_test 812b "do not drop no resend request for idle connect"
27629
27630 test_812c() {
27631         local old
27632
27633         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27634
27635         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27636         $LFS getstripe $DIR/$tfile
27637         $LCTL set_param osc.*.idle_timeout=10
27638         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27639         # ensure ost1 is connected
27640         stat $DIR/$tfile >/dev/null || error "can't stat"
27641         wait_osc_import_state client ost1 FULL
27642         # no locks, no reqs to let the connection idle
27643         cancel_lru_locks osc
27644
27645 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27646         $LCTL set_param fail_loc=0x80000533
27647         sleep 15
27648         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27649 }
27650 run_test 812c "idle import vs lock enqueue race"
27651
27652 test_813() {
27653         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27654         [ -z "$file_heat_sav" ] && skip "no file heat support"
27655
27656         local readsample
27657         local writesample
27658         local readbyte
27659         local writebyte
27660         local readsample1
27661         local writesample1
27662         local readbyte1
27663         local writebyte1
27664
27665         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27666         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27667
27668         $LCTL set_param -n llite.*.file_heat=1
27669         echo "Turn on file heat"
27670         echo "Period second: $period_second, Decay percentage: $decay_pct"
27671
27672         echo "QQQQ" > $DIR/$tfile
27673         echo "QQQQ" > $DIR/$tfile
27674         echo "QQQQ" > $DIR/$tfile
27675         cat $DIR/$tfile > /dev/null
27676         cat $DIR/$tfile > /dev/null
27677         cat $DIR/$tfile > /dev/null
27678         cat $DIR/$tfile > /dev/null
27679
27680         local out=$($LFS heat_get $DIR/$tfile)
27681
27682         $LFS heat_get $DIR/$tfile
27683         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27684         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27685         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27686         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27687
27688         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27689         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27690         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27691         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27692
27693         sleep $((period_second + 3))
27694         echo "Sleep $((period_second + 3)) seconds..."
27695         # The recursion formula to calculate the heat of the file f is as
27696         # follow:
27697         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27698         # Where Hi is the heat value in the period between time points i*I and
27699         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27700         # to the weight of Ci.
27701         out=$($LFS heat_get $DIR/$tfile)
27702         $LFS heat_get $DIR/$tfile
27703         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27704         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27705         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27706         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27707
27708         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27709                 error "read sample ($readsample) is wrong"
27710         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27711                 error "write sample ($writesample) is wrong"
27712         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27713                 error "read bytes ($readbyte) is wrong"
27714         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27715                 error "write bytes ($writebyte) is wrong"
27716
27717         echo "QQQQ" > $DIR/$tfile
27718         echo "QQQQ" > $DIR/$tfile
27719         echo "QQQQ" > $DIR/$tfile
27720         cat $DIR/$tfile > /dev/null
27721         cat $DIR/$tfile > /dev/null
27722         cat $DIR/$tfile > /dev/null
27723         cat $DIR/$tfile > /dev/null
27724
27725         sleep $((period_second + 3))
27726         echo "Sleep $((period_second + 3)) seconds..."
27727
27728         out=$($LFS heat_get $DIR/$tfile)
27729         $LFS heat_get $DIR/$tfile
27730         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27731         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27732         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27733         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27734
27735         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27736                 4 * $decay_pct) / 100") -eq 1 ] ||
27737                 error "read sample ($readsample1) is wrong"
27738         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27739                 3 * $decay_pct) / 100") -eq 1 ] ||
27740                 error "write sample ($writesample1) is wrong"
27741         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27742                 20 * $decay_pct) / 100") -eq 1 ] ||
27743                 error "read bytes ($readbyte1) is wrong"
27744         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27745                 15 * $decay_pct) / 100") -eq 1 ] ||
27746                 error "write bytes ($writebyte1) is wrong"
27747
27748         echo "Turn off file heat for the file $DIR/$tfile"
27749         $LFS heat_set -o $DIR/$tfile
27750
27751         echo "QQQQ" > $DIR/$tfile
27752         echo "QQQQ" > $DIR/$tfile
27753         echo "QQQQ" > $DIR/$tfile
27754         cat $DIR/$tfile > /dev/null
27755         cat $DIR/$tfile > /dev/null
27756         cat $DIR/$tfile > /dev/null
27757         cat $DIR/$tfile > /dev/null
27758
27759         out=$($LFS heat_get $DIR/$tfile)
27760         $LFS heat_get $DIR/$tfile
27761         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27762         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27763         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27764         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27765
27766         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27767         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27768         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27769         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27770
27771         echo "Trun on file heat for the file $DIR/$tfile"
27772         $LFS heat_set -O $DIR/$tfile
27773
27774         echo "QQQQ" > $DIR/$tfile
27775         echo "QQQQ" > $DIR/$tfile
27776         echo "QQQQ" > $DIR/$tfile
27777         cat $DIR/$tfile > /dev/null
27778         cat $DIR/$tfile > /dev/null
27779         cat $DIR/$tfile > /dev/null
27780         cat $DIR/$tfile > /dev/null
27781
27782         out=$($LFS heat_get $DIR/$tfile)
27783         $LFS heat_get $DIR/$tfile
27784         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27785         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27786         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27787         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27788
27789         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27790         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27791         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27792         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27793
27794         $LFS heat_set -c $DIR/$tfile
27795         $LCTL set_param -n llite.*.file_heat=0
27796         echo "Turn off file heat support for the Lustre filesystem"
27797
27798         echo "QQQQ" > $DIR/$tfile
27799         echo "QQQQ" > $DIR/$tfile
27800         echo "QQQQ" > $DIR/$tfile
27801         cat $DIR/$tfile > /dev/null
27802         cat $DIR/$tfile > /dev/null
27803         cat $DIR/$tfile > /dev/null
27804         cat $DIR/$tfile > /dev/null
27805
27806         out=$($LFS heat_get $DIR/$tfile)
27807         $LFS heat_get $DIR/$tfile
27808         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27809         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27810         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27811         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27812
27813         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27814         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27815         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27816         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27817
27818         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27819         rm -f $DIR/$tfile
27820 }
27821 run_test 813 "File heat verfication"
27822
27823 test_814()
27824 {
27825         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27826         echo -n y >> $DIR/$tfile
27827         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27828         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27829 }
27830 run_test 814 "sparse cp works as expected (LU-12361)"
27831
27832 test_815()
27833 {
27834         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27835         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27836 }
27837 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27838
27839 test_816() {
27840         local ost1_imp=$(get_osc_import_name client ost1)
27841         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27842                          cut -d'.' -f2)
27843
27844         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27845         # ensure ost1 is connected
27846
27847         stat $DIR/$tfile >/dev/null || error "can't stat"
27848         wait_osc_import_state client ost1 FULL
27849         # no locks, no reqs to let the connection idle
27850         cancel_lru_locks osc
27851         lru_resize_disable osc
27852         local before
27853         local now
27854         before=$($LCTL get_param -n \
27855                  ldlm.namespaces.$imp_name.lru_size)
27856
27857         wait_osc_import_state client ost1 IDLE
27858         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27859         now=$($LCTL get_param -n \
27860               ldlm.namespaces.$imp_name.lru_size)
27861         [ $before == $now ] || error "lru_size changed $before != $now"
27862 }
27863 run_test 816 "do not reset lru_resize on idle reconnect"
27864
27865 cleanup_817() {
27866         umount $tmpdir
27867         exportfs -u localhost:$DIR/nfsexp
27868         rm -rf $DIR/nfsexp
27869 }
27870
27871 test_817() {
27872         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27873
27874         mkdir -p $DIR/nfsexp
27875         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27876                 error "failed to export nfs"
27877
27878         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27879         stack_trap cleanup_817 EXIT
27880
27881         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27882                 error "failed to mount nfs to $tmpdir"
27883
27884         cp /bin/true $tmpdir
27885         $DIR/nfsexp/true || error "failed to execute 'true' command"
27886 }
27887 run_test 817 "nfsd won't cache write lock for exec file"
27888
27889 test_818() {
27890         test_mkdir -i0 -c1 $DIR/$tdir
27891         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
27892         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
27893         stop $SINGLEMDS
27894
27895         # restore osp-syn threads
27896         stack_trap "fail $SINGLEMDS"
27897
27898         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27899         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27900         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27901                 error "start $SINGLEMDS failed"
27902         rm -rf $DIR/$tdir
27903
27904         local testid=$(echo $TESTNAME | tr '_' ' ')
27905
27906         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
27907                 grep "run LFSCK" || error "run LFSCK is not suggested"
27908 }
27909 run_test 818 "unlink with failed llog"
27910
27911 test_819a() {
27912         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27913         cancel_lru_locks osc
27914         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27915         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27916         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27917         rm -f $TDIR/$tfile
27918 }
27919 run_test 819a "too big niobuf in read"
27920
27921 test_819b() {
27922         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27923         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27924         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27925         cancel_lru_locks osc
27926         sleep 1
27927         rm -f $TDIR/$tfile
27928 }
27929 run_test 819b "too big niobuf in write"
27930
27931
27932 function test_820_start_ost() {
27933         sleep 5
27934
27935         for num in $(seq $OSTCOUNT); do
27936                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27937         done
27938 }
27939
27940 test_820() {
27941         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27942
27943         mkdir $DIR/$tdir
27944         umount_client $MOUNT || error "umount failed"
27945         for num in $(seq $OSTCOUNT); do
27946                 stop ost$num
27947         done
27948
27949         # mount client with no active OSTs
27950         # so that the client can't initialize max LOV EA size
27951         # from OSC notifications
27952         mount_client $MOUNT || error "mount failed"
27953         # delay OST starting to keep this 0 max EA size for a while
27954         test_820_start_ost &
27955
27956         # create a directory on MDS2
27957         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27958                 error "Failed to create directory"
27959         # open intent should update default EA size
27960         # see mdc_update_max_ea_from_body()
27961         # notice this is the very first RPC to MDS2
27962         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27963         ret=$?
27964         echo $out
27965         # With SSK, this situation can lead to -EPERM being returned.
27966         # In that case, simply retry.
27967         if [ $ret -ne 0 ] && $SHARED_KEY; then
27968                 if echo "$out" | grep -q "not permitted"; then
27969                         cp /etc/services $DIR/$tdir/mds2
27970                         ret=$?
27971                 fi
27972         fi
27973         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27974 }
27975 run_test 820 "update max EA from open intent"
27976
27977 test_822() {
27978         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27979
27980         save_lustre_params mds1 \
27981                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27982         do_facet $SINGLEMDS "$LCTL set_param -n \
27983                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27984         do_facet $SINGLEMDS "$LCTL set_param -n \
27985                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27986
27987         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27988         local maxage=$(do_facet mds1 $LCTL get_param -n \
27989                        osp.$FSNAME-OST0000*MDT0000.maxage)
27990         sleep $((maxage + 1))
27991
27992         #define OBD_FAIL_NET_ERROR_RPC          0x532
27993         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27994
27995         stack_trap "restore_lustre_params < $p; rm $p"
27996
27997         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27998                       osp.$FSNAME-OST0000*MDT0000.create_count")
27999         for i in $(seq 1 $count); do
28000                 touch $DIR/$tfile.${i} || error "touch failed"
28001         done
28002 }
28003 run_test 822 "test precreate failure"
28004
28005 test_823() {
28006         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28007         local OST_MAX_PRECREATE=20000
28008
28009         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28010                 skip "Need MDS version at least 2.14.56"
28011
28012         save_lustre_params mds1 \
28013                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28014         do_facet $SINGLEMDS "$LCTL set_param -n \
28015                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28016         do_facet $SINGLEMDS "$LCTL set_param -n \
28017                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28018
28019         stack_trap "restore_lustre_params < $p; rm $p"
28020
28021         do_facet $SINGLEMDS "$LCTL set_param -n \
28022                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28023
28024         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28025                       osp.$FSNAME-OST0000*MDT0000.create_count")
28026         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28027                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28028         local expect_count=$(((($max/2)/256) * 256))
28029
28030         log "setting create_count to 100200:"
28031         log " -result- count: $count with max: $max, expecting: $expect_count"
28032
28033         [[ $count -eq expect_count ]] ||
28034                 error "Create count not set to max precreate."
28035 }
28036 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28037
28038 test_831() {
28039         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28040                 skip "Need MDS version 2.14.56"
28041
28042         local sync_changes=$(do_facet $SINGLEMDS \
28043                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28044
28045         [ "$sync_changes" -gt 100 ] &&
28046                 skip "Sync changes $sync_changes > 100 already"
28047
28048         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28049
28050         $LFS mkdir -i 0 $DIR/$tdir
28051         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28052
28053         save_lustre_params mds1 \
28054                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28055         save_lustre_params mds1 \
28056                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28057
28058         do_facet mds1 "$LCTL set_param -n \
28059                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28060                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28061         stack_trap "restore_lustre_params < $p" EXIT
28062
28063         createmany -o $DIR/$tdir/f- 1000
28064         unlinkmany $DIR/$tdir/f- 1000 &
28065         local UNLINK_PID=$!
28066
28067         while sleep 1; do
28068                 sync_changes=$(do_facet mds1 \
28069                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28070                 # the check in the code is racy, fail the test
28071                 # if the value above the limit by 10.
28072                 [ $sync_changes -gt 110 ] && {
28073                         kill -2 $UNLINK_PID
28074                         wait
28075                         error "osp changes throttling failed, $sync_changes>110"
28076                 }
28077                 kill -0 $UNLINK_PID 2> /dev/null || break
28078         done
28079         wait
28080 }
28081 run_test 831 "throttling unlink/setattr queuing on OSP"
28082
28083 #
28084 # tests that do cleanup/setup should be run at the end
28085 #
28086
28087 test_900() {
28088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28089         local ls
28090
28091         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28092         $LCTL set_param fail_loc=0x903
28093
28094         cancel_lru_locks MGC
28095
28096         FAIL_ON_ERROR=true cleanup
28097         FAIL_ON_ERROR=true setup
28098 }
28099 run_test 900 "umount should not race with any mgc requeue thread"
28100
28101 # LUS-6253/LU-11185
28102 test_901() {
28103         local old
28104         local count
28105         local oldc
28106         local newc
28107         local olds
28108         local news
28109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28110
28111         # some get_param have a bug to handle dot in param name
28112         cancel_lru_locks MGC
28113         old=$(mount -t lustre | wc -l)
28114         # 1 config+sptlrpc
28115         # 2 params
28116         # 3 nodemap
28117         # 4 IR
28118         old=$((old * 4))
28119         oldc=0
28120         count=0
28121         while [ $old -ne $oldc ]; do
28122                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28123                 sleep 1
28124                 ((count++))
28125                 if [ $count -ge $TIMEOUT ]; then
28126                         error "too large timeout"
28127                 fi
28128         done
28129         umount_client $MOUNT || error "umount failed"
28130         mount_client $MOUNT || error "mount failed"
28131         cancel_lru_locks MGC
28132         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28133
28134         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28135
28136         return 0
28137 }
28138 run_test 901 "don't leak a mgc lock on client umount"
28139
28140 # LU-13377
28141 test_902() {
28142         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28143                 skip "client does not have LU-13377 fix"
28144         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28145         $LCTL set_param fail_loc=0x1415
28146         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28147         cancel_lru_locks osc
28148         rm -f $DIR/$tfile
28149 }
28150 run_test 902 "test short write doesn't hang lustre"
28151
28152 # LU-14711
28153 test_903() {
28154         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28155         echo "blah" > $DIR/${tfile}-2
28156         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28157         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28158         $LCTL set_param fail_loc=0x417 fail_val=20
28159
28160         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28161         sleep 1 # To start the destroy
28162         wait_destroy_complete 150 || error "Destroy taking too long"
28163         cat $DIR/$tfile > /dev/null || error "Evicted"
28164 }
28165 run_test 903 "Test long page discard does not cause evictions"
28166
28167 test_904() {
28168         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28169         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28170                 grep -q project || skip "skip project quota not supported"
28171
28172         local testfile="$DIR/$tdir/$tfile"
28173         local xattr="trusted.projid"
28174         local projid
28175         local mdts=$(comma_list $(mdts_nodes))
28176         local saved=$(do_facet mds1 $LCTL get_param -n \
28177                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28178
28179         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28180         stack_trap "do_nodes $mdts $LCTL set_param \
28181                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28182
28183         mkdir -p $DIR/$tdir
28184         touch $testfile
28185         #hide projid xattr on server
28186         $LFS project -p 1 $testfile ||
28187                 error "set $testfile project id failed"
28188         getfattr -m - $testfile | grep $xattr &&
28189                 error "do not show trusted.projid when disabled on server"
28190         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28191         #should be hidden when projid is 0
28192         $LFS project -p 0 $testfile ||
28193                 error "set $testfile project id failed"
28194         getfattr -m - $testfile | grep $xattr &&
28195                 error "do not show trusted.projid with project ID 0"
28196
28197         #still can getxattr explicitly
28198         projid=$(getfattr -n $xattr $testfile |
28199                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28200         [ $projid == "0" ] ||
28201                 error "projid expected 0 not $projid"
28202
28203         #set the projid via setxattr
28204         setfattr -n $xattr -v "1000" $testfile ||
28205                 error "setattr failed with $?"
28206         projid=($($LFS project $testfile))
28207         [ ${projid[0]} == "1000" ] ||
28208                 error "projid expected 1000 not $projid"
28209
28210         #check the new projid via getxattr
28211         $LFS project -p 1001 $testfile ||
28212                 error "set $testfile project id failed"
28213         getfattr -m - $testfile | grep $xattr ||
28214                 error "should show trusted.projid when project ID != 0"
28215         projid=$(getfattr -n $xattr $testfile |
28216                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28217         [ $projid == "1001" ] ||
28218                 error "projid expected 1001 not $projid"
28219
28220         #try to set invalid projid
28221         setfattr -n $xattr -v "4294967295" $testfile &&
28222                 error "set invalid projid should fail"
28223
28224         #remove the xattr means setting projid to 0
28225         setfattr -x $xattr $testfile ||
28226                 error "setfattr failed with $?"
28227         projid=($($LFS project $testfile))
28228         [ ${projid[0]} == "0" ] ||
28229                 error "projid expected 0 not $projid"
28230
28231         #should be hidden when parent has inherit flag and same projid
28232         $LFS project -srp 1002 $DIR/$tdir ||
28233                 error "set $tdir project id failed"
28234         getfattr -m - $testfile | grep $xattr &&
28235                 error "do not show trusted.projid with inherit flag"
28236
28237         #still can getxattr explicitly
28238         projid=$(getfattr -n $xattr $testfile |
28239                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28240         [ $projid == "1002" ] ||
28241                 error "projid expected 1002 not $projid"
28242 }
28243 run_test 904 "virtual project ID xattr"
28244
28245 complete $SECONDS
28246 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28247 check_and_cleanup_lustre
28248 if [ "$I_MOUNTED" != "yes" ]; then
28249         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28250 fi
28251 exit_status