Whamcloud - gitweb
LU-15910 llite: enforce ROOT default on subdir mount
[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
32 TRACE=${TRACE:-""}
33 LUSTRE=${LUSTRE:-$(dirname $0)/..}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 . $LUSTRE/tests/test-framework.sh
36 init_test_env "$@"
37
38 init_logging
39
40 ALWAYS_EXCEPT="$SANITY_EXCEPT "
41 always_except LU-9693  42a 42c
42 always_except LU-6493  42b
43 always_except LU-14541 277
44 always_except LU-9054  312
45 always_except LU-8411  407
46
47 if $SHARED_KEY; then
48         always_except LU-14181 64e 64f
49 fi
50
51 # skip the grant tests for ARM until they are fixed
52 if [[ $(uname -m) = aarch64 ]]; then
53         always_except LU-11671 45
54 fi
55
56 # skip nfs tests on kernels >= 4.12.0 until they are fixed
57 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
58         always_except LU-12661 817
59 fi
60 # skip cgroup tests on RHEL8.1 kernels until they are fixed
61 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
62       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
63         always_except LU-13063 411
64 fi
65
66 #skip ACL tests on RHEL8 and SLES15 until tests changed to use other users
67 if (( $(egrep -cw "^bin|^daemon" /etc/passwd) < 2 )); then
68         always_except LU-15259 103a 125 154a
69 fi
70
71 #                                  5              12     8   12  15   (min)"
72 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
73
74 if [ "$mds1_FSTYPE" = "zfs" ]; then
75         #                                               13    (min)"
76         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
77 fi
78
79 if [ "$ost1_FSTYPE" = "zfs" ]; then
80         always_except LU-1941 130a 130b 130c 130d 130e 130f 130g
81 fi
82
83 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
84
85 # Get the SLES distro version
86 #
87 # Returns a version string that should only be used in comparing
88 # strings returned by version_code()
89 sles_version_code()
90 {
91         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
92
93         # All SuSE Linux versions have one decimal. version_code expects two
94         local sles_version=$version.0
95         version_code $sles_version
96 }
97
98 # Check if we are running on Ubuntu or SLES so we can make decisions on
99 # what tests to run
100 if [ -r /etc/SuSE-release ]; then
101         sles_version=$(sles_version_code)
102         [ $sles_version -lt $(version_code 11.4.0) ] &&
103                 always_except LU-4341 170
104
105         [ $sles_version -lt $(version_code 12.0.0) ] &&
106                 always_except LU-3703 234
107 elif [ -r /etc/os-release ]; then
108         if grep -qi ubuntu /etc/os-release; then
109                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
110                                                 -e 's/^VERSION=//p' \
111                                                 /etc/os-release |
112                                                 awk '{ print $1 }'))
113
114                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
115                         always_except LU-10334 103a
116                         always_except LU-10366 410
117                 fi
118         fi
119 fi
120
121 build_test_filter
122 FAIL_ON_ERROR=false
123
124 cleanup() {
125         echo -n "cln.."
126         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
127         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
128 }
129 setup() {
130         echo -n "mnt.."
131         load_modules
132         setupall || exit 10
133         echo "done"
134 }
135
136 check_swap_layouts_support()
137 {
138         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
139                 skip "Does not support layout lock."
140 }
141
142 check_swap_layout_no_dom()
143 {
144         local FOLDER=$1
145         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
146         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
147 }
148
149 check_and_setup_lustre
150 DIR=${DIR:-$MOUNT}
151 assert_DIR
152
153 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
154
155 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
156 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
157 rm -rf $DIR/[Rdfs][0-9]*
158
159 # $RUNAS_ID may get set incorrectly somewhere else
160 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
161         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
162
163 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
164
165 if [ "${ONLY}" = "MOUNT" ] ; then
166         echo "Lustre is up, please go on"
167         exit
168 fi
169
170 echo "preparing for tests involving mounts"
171 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
172 touch $EXT2_DEV
173 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
174 echo # add a newline after mke2fs.
175
176 umask 077
177
178 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
179 lctl set_param debug=-1 2> /dev/null || true
180 test_0a() {
181         touch $DIR/$tfile
182         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
183         rm $DIR/$tfile
184         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
185 }
186 run_test 0a "touch; rm ====================="
187
188 test_0b() {
189         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
190         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
191 }
192 run_test 0b "chmod 0755 $DIR ============================="
193
194 test_0c() {
195         $LCTL get_param mdc.*.import | grep "state: FULL" ||
196                 error "import not FULL"
197         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
198                 error "bad target"
199 }
200 run_test 0c "check import proc"
201
202 test_0d() { # LU-3397
203         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
204                 skip "proc exports not supported before 2.10.57"
205
206         local mgs_exp="mgs.MGS.exports"
207         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
208         local exp_client_nid
209         local exp_client_version
210         local exp_val
211         local imp_val
212         local temp_imp=$DIR/$tfile.import
213         local temp_exp=$DIR/$tfile.export
214
215         # save mgc import file to $temp_imp
216         $LCTL get_param mgc.*.import | tee $temp_imp
217         # Check if client uuid is found in MGS export
218         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
219                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
220                         $client_uuid ] &&
221                         break;
222         done
223         # save mgs export file to $temp_exp
224         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
225
226         # Compare the value of field "connect_flags"
227         imp_val=$(grep "connect_flags" $temp_imp)
228         exp_val=$(grep "connect_flags" $temp_exp)
229         [ "$exp_val" == "$imp_val" ] ||
230                 error "export flags '$exp_val' != import flags '$imp_val'"
231
232         # Compare client versions.  Only compare top-3 fields for compatibility
233         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
234         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
235         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
236         [ "$exp_val" == "$imp_val" ] ||
237                 error "exp version '$exp_client_version'($exp_val) != " \
238                         "'$(lustre_build_version client)'($imp_val)"
239 }
240 run_test 0d "check export proc ============================="
241
242 test_0e() { # LU-13417
243         (( $MDSCOUNT > 1 )) ||
244                 skip "We need at least 2 MDTs for this test"
245
246         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
247                 skip "Need server version at least 2.14.51"
248
249         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
250         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
251
252         [ $default_lmv_count -eq 1 ] ||
253                 error "$MOUNT default stripe count $default_lmv_count"
254
255         [ $default_lmv_index -eq -1 ] ||
256                 error "$MOUNT default stripe index $default_lmv_index"
257
258         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
259         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
260
261         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
262         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
263
264         [ $mdt_index1 -eq $mdt_index2 ] &&
265                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
266
267         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
268 }
269 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
270
271 test_1() {
272         test_mkdir $DIR/$tdir
273         test_mkdir $DIR/$tdir/d2
274         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
275         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
276         rmdir $DIR/$tdir/d2
277         rmdir $DIR/$tdir
278         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
279 }
280 run_test 1 "mkdir; remkdir; rmdir"
281
282 test_2() {
283         test_mkdir $DIR/$tdir
284         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
285         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
286         rm -r $DIR/$tdir
287         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
288 }
289 run_test 2 "mkdir; touch; rmdir; check file"
290
291 test_3() {
292         test_mkdir $DIR/$tdir
293         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
294         touch $DIR/$tdir/$tfile
295         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
296         rm -r $DIR/$tdir
297         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
298 }
299 run_test 3 "mkdir; touch; rmdir; check dir"
300
301 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
302 test_4() {
303         test_mkdir -i 1 $DIR/$tdir
304
305         touch $DIR/$tdir/$tfile ||
306                 error "Create file under remote directory failed"
307
308         rmdir $DIR/$tdir &&
309                 error "Expect error removing in-use dir $DIR/$tdir"
310
311         test -d $DIR/$tdir || error "Remote directory disappeared"
312
313         rm -rf $DIR/$tdir || error "remove remote dir error"
314 }
315 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
316
317 test_5() {
318         test_mkdir $DIR/$tdir
319         test_mkdir $DIR/$tdir/d2
320         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
321         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
322         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
323 }
324 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
325
326 test_6a() {
327         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
328         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
329         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
330                 error "$tfile does not have perm 0666 or UID $UID"
331         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
332         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
333                 error "$tfile should be 0666 and owned by UID $UID"
334 }
335 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
336
337 test_6c() {
338         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
339
340         touch $DIR/$tfile
341         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
342         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
343                 error "$tfile should be owned by UID $RUNAS_ID"
344         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
345         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
346                 error "$tfile should be owned by UID $RUNAS_ID"
347 }
348 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
349
350 test_6e() {
351         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
352
353         touch $DIR/$tfile
354         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
355         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
356                 error "$tfile should be owned by GID $UID"
357         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
358         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
359                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
360 }
361 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
362
363 test_6g() {
364         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
365
366         test_mkdir $DIR/$tdir
367         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
368         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
369         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
370         test_mkdir $DIR/$tdir/d/subdir
371         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
372                 error "$tdir/d/subdir should be GID $RUNAS_GID"
373         if [[ $MDSCOUNT -gt 1 ]]; then
374                 # check remote dir sgid inherite
375                 $LFS mkdir -i 0 $DIR/$tdir.local ||
376                         error "mkdir $tdir.local failed"
377                 chmod g+s $DIR/$tdir.local ||
378                         error "chmod $tdir.local failed"
379                 chgrp $RUNAS_GID $DIR/$tdir.local ||
380                         error "chgrp $tdir.local failed"
381                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
382                         error "mkdir $tdir.remote failed"
383                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
384                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
385                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
386                         error "$tdir.remote should be mode 02755"
387         fi
388 }
389 run_test 6g "verify new dir in sgid dir inherits group"
390
391 test_6h() { # bug 7331
392         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
393
394         touch $DIR/$tfile || error "touch failed"
395         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
396         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
397                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
398         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
399                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
400 }
401 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
402
403 test_7a() {
404         test_mkdir $DIR/$tdir
405         $MCREATE $DIR/$tdir/$tfile
406         chmod 0666 $DIR/$tdir/$tfile
407         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
408                 error "$tdir/$tfile should be mode 0666"
409 }
410 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
411
412 test_7b() {
413         if [ ! -d $DIR/$tdir ]; then
414                 test_mkdir $DIR/$tdir
415         fi
416         $MCREATE $DIR/$tdir/$tfile
417         echo -n foo > $DIR/$tdir/$tfile
418         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
419         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
420 }
421 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
422
423 test_8() {
424         test_mkdir $DIR/$tdir
425         touch $DIR/$tdir/$tfile
426         chmod 0666 $DIR/$tdir/$tfile
427         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
428                 error "$tfile mode not 0666"
429 }
430 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
431
432 test_9() {
433         test_mkdir $DIR/$tdir
434         test_mkdir $DIR/$tdir/d2
435         test_mkdir $DIR/$tdir/d2/d3
436         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
437 }
438 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
439
440 test_10() {
441         test_mkdir $DIR/$tdir
442         test_mkdir $DIR/$tdir/d2
443         touch $DIR/$tdir/d2/$tfile
444         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
445                 error "$tdir/d2/$tfile not a file"
446 }
447 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
448
449 test_11() {
450         test_mkdir $DIR/$tdir
451         test_mkdir $DIR/$tdir/d2
452         chmod 0666 $DIR/$tdir/d2
453         chmod 0705 $DIR/$tdir/d2
454         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
455                 error "$tdir/d2 mode not 0705"
456 }
457 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
458
459 test_12() {
460         test_mkdir $DIR/$tdir
461         touch $DIR/$tdir/$tfile
462         chmod 0666 $DIR/$tdir/$tfile
463         chmod 0654 $DIR/$tdir/$tfile
464         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
465                 error "$tdir/d2 mode not 0654"
466 }
467 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
468
469 test_13() {
470         test_mkdir $DIR/$tdir
471         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
472         >  $DIR/$tdir/$tfile
473         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
474                 error "$tdir/$tfile size not 0 after truncate"
475 }
476 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
477
478 test_14() {
479         test_mkdir $DIR/$tdir
480         touch $DIR/$tdir/$tfile
481         rm $DIR/$tdir/$tfile
482         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
483 }
484 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
485
486 test_15() {
487         test_mkdir $DIR/$tdir
488         touch $DIR/$tdir/$tfile
489         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
490         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
491                 error "$tdir/${tfile_2} not a file after rename"
492         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
493 }
494 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
495
496 test_16() {
497         test_mkdir $DIR/$tdir
498         touch $DIR/$tdir/$tfile
499         rm -rf $DIR/$tdir/$tfile
500         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
501 }
502 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
503
504 test_17a() {
505         test_mkdir $DIR/$tdir
506         touch $DIR/$tdir/$tfile
507         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
508         ls -l $DIR/$tdir
509         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
510                 error "$tdir/l-exist not a symlink"
511         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
512                 error "$tdir/l-exist not referencing a file"
513         rm -f $DIR/$tdir/l-exist
514         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
515 }
516 run_test 17a "symlinks: create, remove (real)"
517
518 test_17b() {
519         test_mkdir $DIR/$tdir
520         ln -s no-such-file $DIR/$tdir/l-dangle
521         ls -l $DIR/$tdir
522         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
523                 error "$tdir/l-dangle not referencing no-such-file"
524         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
525                 error "$tdir/l-dangle not referencing non-existent file"
526         rm -f $DIR/$tdir/l-dangle
527         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
528 }
529 run_test 17b "symlinks: create, remove (dangling)"
530
531 test_17c() { # bug 3440 - don't save failed open RPC for replay
532         test_mkdir $DIR/$tdir
533         ln -s foo $DIR/$tdir/$tfile
534         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
535 }
536 run_test 17c "symlinks: open dangling (should return error)"
537
538 test_17d() {
539         test_mkdir $DIR/$tdir
540         ln -s foo $DIR/$tdir/$tfile
541         touch $DIR/$tdir/$tfile || error "creating to new symlink"
542 }
543 run_test 17d "symlinks: create dangling"
544
545 test_17e() {
546         test_mkdir $DIR/$tdir
547         local foo=$DIR/$tdir/$tfile
548         ln -s $foo $foo || error "create symlink failed"
549         ls -l $foo || error "ls -l failed"
550         ls $foo && error "ls not failed" || true
551 }
552 run_test 17e "symlinks: create recursive symlink (should return error)"
553
554 test_17f() {
555         test_mkdir $DIR/$tdir
556         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
557         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
558         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
559         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
560         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
561         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
562         ls -l  $DIR/$tdir
563 }
564 run_test 17f "symlinks: long and very long symlink name"
565
566 # str_repeat(S, N) generate a string that is string S repeated N times
567 str_repeat() {
568         local s=$1
569         local n=$2
570         local ret=''
571         while [ $((n -= 1)) -ge 0 ]; do
572                 ret=$ret$s
573         done
574         echo $ret
575 }
576
577 # Long symlinks and LU-2241
578 test_17g() {
579         test_mkdir $DIR/$tdir
580         local TESTS="59 60 61 4094 4095"
581
582         # Fix for inode size boundary in 2.1.4
583         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
584                 TESTS="4094 4095"
585
586         # Patch not applied to 2.2 or 2.3 branches
587         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
588         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
589                 TESTS="4094 4095"
590
591         for i in $TESTS; do
592                 local SYMNAME=$(str_repeat 'x' $i)
593                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
594                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
595         done
596 }
597 run_test 17g "symlinks: really long symlink name and inode boundaries"
598
599 test_17h() { #bug 17378
600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
601         remote_mds_nodsh && skip "remote MDS with nodsh"
602
603         local mdt_idx
604
605         test_mkdir $DIR/$tdir
606         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
607         $LFS setstripe -c -1 $DIR/$tdir
608         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
609         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
610         touch $DIR/$tdir/$tfile || true
611 }
612 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
613
614 test_17i() { #bug 20018
615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
616         remote_mds_nodsh && skip "remote MDS with nodsh"
617
618         local foo=$DIR/$tdir/$tfile
619         local mdt_idx
620
621         test_mkdir -c1 $DIR/$tdir
622         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
623         ln -s $foo $foo || error "create symlink failed"
624 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
625         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
626         ls -l $foo && error "error not detected"
627         return 0
628 }
629 run_test 17i "don't panic on short symlink (should return error)"
630
631 test_17k() { #bug 22301
632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
633         [[ -z "$(which rsync 2>/dev/null)" ]] &&
634                 skip "no rsync command"
635         rsync --help | grep -q xattr ||
636                 skip_env "$(rsync --version | head -n1) does not support xattrs"
637         test_mkdir $DIR/$tdir
638         test_mkdir $DIR/$tdir.new
639         touch $DIR/$tdir/$tfile
640         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
641         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
642                 error "rsync failed with xattrs enabled"
643 }
644 run_test 17k "symlinks: rsync with xattrs enabled"
645
646 test_17l() { # LU-279
647         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
648                 skip "no getfattr command"
649
650         test_mkdir $DIR/$tdir
651         touch $DIR/$tdir/$tfile
652         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
653         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
654                 # -h to not follow symlinks. -m '' to list all the xattrs.
655                 # grep to remove first line: '# file: $path'.
656                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
657                 do
658                         lgetxattr_size_check $path $xattr ||
659                                 error "lgetxattr_size_check $path $xattr failed"
660                 done
661         done
662 }
663 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
664
665 # LU-1540
666 test_17m() {
667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
668         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
669         remote_mds_nodsh && skip "remote MDS with nodsh"
670         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
671         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
672                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
673
674         local short_sym="0123456789"
675         local wdir=$DIR/$tdir
676         local i
677
678         test_mkdir $wdir
679         long_sym=$short_sym
680         # create a long symlink file
681         for ((i = 0; i < 4; ++i)); do
682                 long_sym=${long_sym}${long_sym}
683         done
684
685         echo "create 512 short and long symlink files under $wdir"
686         for ((i = 0; i < 256; ++i)); do
687                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
688                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
689         done
690
691         echo "erase them"
692         rm -f $wdir/*
693         sync
694         wait_delete_completed
695
696         echo "recreate the 512 symlink files with a shorter string"
697         for ((i = 0; i < 512; ++i)); do
698                 # rewrite the symlink file with a shorter string
699                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
700                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
701         done
702
703         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
704
705         echo "stop and checking mds${mds_index}:"
706         # e2fsck should not return error
707         stop mds${mds_index}
708         local devname=$(mdsdevname $mds_index)
709         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
710         rc=$?
711
712         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
713                 error "start mds${mds_index} failed"
714         df $MOUNT > /dev/null 2>&1
715         [ $rc -eq 0 ] ||
716                 error "e2fsck detected error for short/long symlink: rc=$rc"
717         rm -f $wdir/*
718 }
719 run_test 17m "run e2fsck against MDT which contains short/long symlink"
720
721 check_fs_consistency_17n() {
722         local mdt_index
723         local rc=0
724
725         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
726         # so it only check MDT1/MDT2 instead of all of MDTs.
727         for mdt_index in 1 2; do
728                 # e2fsck should not return error
729                 stop mds${mdt_index}
730                 local devname=$(mdsdevname $mdt_index)
731                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
732                         rc=$((rc + $?))
733
734                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
735                         error "mount mds$mdt_index failed"
736                 df $MOUNT > /dev/null 2>&1
737         done
738         return $rc
739 }
740
741 test_17n() {
742         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
744         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
745         remote_mds_nodsh && skip "remote MDS with nodsh"
746         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
747         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
748                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
749
750         local i
751
752         test_mkdir $DIR/$tdir
753         for ((i=0; i<10; i++)); do
754                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
755                         error "create remote dir error $i"
756                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
757                         error "create files under remote dir failed $i"
758         done
759
760         check_fs_consistency_17n ||
761                 error "e2fsck report error after create files under remote dir"
762
763         for ((i = 0; i < 10; i++)); do
764                 rm -rf $DIR/$tdir/remote_dir_${i} ||
765                         error "destroy remote dir error $i"
766         done
767
768         check_fs_consistency_17n ||
769                 error "e2fsck report error after unlink files under remote dir"
770
771         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
772                 skip "lustre < 2.4.50 does not support migrate mv"
773
774         for ((i = 0; i < 10; i++)); do
775                 mkdir -p $DIR/$tdir/remote_dir_${i}
776                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
777                         error "create files under remote dir failed $i"
778                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
779                         error "migrate remote dir error $i"
780         done
781         check_fs_consistency_17n || error "e2fsck report error after migration"
782
783         for ((i = 0; i < 10; i++)); do
784                 rm -rf $DIR/$tdir/remote_dir_${i} ||
785                         error "destroy remote dir error $i"
786         done
787
788         check_fs_consistency_17n || error "e2fsck report error after unlink"
789 }
790 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
791
792 test_17o() {
793         remote_mds_nodsh && skip "remote MDS with nodsh"
794         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
795                 skip "Need MDS version at least 2.3.64"
796
797         local wdir=$DIR/${tdir}o
798         local mdt_index
799         local rc=0
800
801         test_mkdir $wdir
802         touch $wdir/$tfile
803         mdt_index=$($LFS getstripe -m $wdir/$tfile)
804         mdt_index=$((mdt_index + 1))
805
806         cancel_lru_locks mdc
807         #fail mds will wait the failover finish then set
808         #following fail_loc to avoid interfer the recovery process.
809         fail mds${mdt_index}
810
811         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
812         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
813         ls -l $wdir/$tfile && rc=1
814         do_facet mds${mdt_index} lctl set_param fail_loc=0
815         [[ $rc -eq 0 ]] || error "stat file should fail"
816 }
817 run_test 17o "stat file with incompat LMA feature"
818
819 test_18() {
820         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
821         ls $DIR || error "Failed to ls $DIR: $?"
822 }
823 run_test 18 "touch .../f ; ls ... =============================="
824
825 test_19a() {
826         touch $DIR/$tfile
827         ls -l $DIR
828         rm $DIR/$tfile
829         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
830 }
831 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
832
833 test_19b() {
834         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
835 }
836 run_test 19b "ls -l .../f19 (should return error) =============="
837
838 test_19c() {
839         [ $RUNAS_ID -eq $UID ] &&
840                 skip_env "RUNAS_ID = UID = $UID -- skipping"
841
842         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
843 }
844 run_test 19c "$RUNAS touch .../f19 (should return error) =="
845
846 test_19d() {
847         cat $DIR/f19 && error || true
848 }
849 run_test 19d "cat .../f19 (should return error) =============="
850
851 test_20() {
852         touch $DIR/$tfile
853         rm $DIR/$tfile
854         touch $DIR/$tfile
855         rm $DIR/$tfile
856         touch $DIR/$tfile
857         rm $DIR/$tfile
858         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
859 }
860 run_test 20 "touch .../f ; ls -l ..."
861
862 test_21() {
863         test_mkdir $DIR/$tdir
864         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
865         ln -s dangle $DIR/$tdir/link
866         echo foo >> $DIR/$tdir/link
867         cat $DIR/$tdir/dangle
868         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
869         $CHECKSTAT -f -t file $DIR/$tdir/link ||
870                 error "$tdir/link not linked to a file"
871 }
872 run_test 21 "write to dangling link"
873
874 test_22() {
875         local wdir=$DIR/$tdir
876         test_mkdir $wdir
877         chown $RUNAS_ID:$RUNAS_GID $wdir
878         (cd $wdir || error "cd $wdir failed";
879                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
880                 $RUNAS tar xf -)
881         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
882         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
883         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
884                 error "checkstat -u failed"
885 }
886 run_test 22 "unpack tar archive as non-root user"
887
888 # was test_23
889 test_23a() {
890         test_mkdir $DIR/$tdir
891         local file=$DIR/$tdir/$tfile
892
893         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
894         openfile -f O_CREAT:O_EXCL $file &&
895                 error "$file recreate succeeded" || true
896 }
897 run_test 23a "O_CREAT|O_EXCL in subdir"
898
899 test_23b() { # bug 18988
900         test_mkdir $DIR/$tdir
901         local file=$DIR/$tdir/$tfile
902
903         rm -f $file
904         echo foo > $file || error "write filed"
905         echo bar >> $file || error "append filed"
906         $CHECKSTAT -s 8 $file || error "wrong size"
907         rm $file
908 }
909 run_test 23b "O_APPEND check"
910
911 # LU-9409, size with O_APPEND and tiny writes
912 test_23c() {
913         local file=$DIR/$tfile
914
915         # single dd
916         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
917         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
918         rm -f $file
919
920         # racing tiny writes
921         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
922         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
923         wait
924         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
925         rm -f $file
926
927         #racing tiny & normal writes
928         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
929         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
930         wait
931         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
932         rm -f $file
933
934         #racing tiny & normal writes 2, ugly numbers
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
937         wait
938         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
939         rm -f $file
940 }
941 run_test 23c "O_APPEND size checks for tiny writes"
942
943 # LU-11069 file offset is correct after appending writes
944 test_23d() {
945         local file=$DIR/$tfile
946         local offset
947
948         echo CentaurHauls > $file
949         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
950         if ((offset != 26)); then
951                 error "wrong offset, expected 26, got '$offset'"
952         fi
953 }
954 run_test 23d "file offset is correct after appending writes"
955
956 # rename sanity
957 test_24a() {
958         echo '-- same directory rename'
959         test_mkdir $DIR/$tdir
960         touch $DIR/$tdir/$tfile.1
961         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
962         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
963 }
964 run_test 24a "rename file to non-existent target"
965
966 test_24b() {
967         test_mkdir $DIR/$tdir
968         touch $DIR/$tdir/$tfile.{1,2}
969         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
970         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
971         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
972 }
973 run_test 24b "rename file to existing target"
974
975 test_24c() {
976         test_mkdir $DIR/$tdir
977         test_mkdir $DIR/$tdir/d$testnum.1
978         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
979         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
980         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
981 }
982 run_test 24c "rename directory to non-existent target"
983
984 test_24d() {
985         test_mkdir -c1 $DIR/$tdir
986         test_mkdir -c1 $DIR/$tdir/d$testnum.1
987         test_mkdir -c1 $DIR/$tdir/d$testnum.2
988         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
989         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
990         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
991 }
992 run_test 24d "rename directory to existing target"
993
994 test_24e() {
995         echo '-- cross directory renames --'
996         test_mkdir $DIR/R5a
997         test_mkdir $DIR/R5b
998         touch $DIR/R5a/f
999         mv $DIR/R5a/f $DIR/R5b/g
1000         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1001         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1002 }
1003 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1004
1005 test_24f() {
1006         test_mkdir $DIR/R6a
1007         test_mkdir $DIR/R6b
1008         touch $DIR/R6a/f $DIR/R6b/g
1009         mv $DIR/R6a/f $DIR/R6b/g
1010         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1011         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1012 }
1013 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1014
1015 test_24g() {
1016         test_mkdir $DIR/R7a
1017         test_mkdir $DIR/R7b
1018         test_mkdir $DIR/R7a/d
1019         mv $DIR/R7a/d $DIR/R7b/e
1020         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1021         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1022 }
1023 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1024
1025 test_24h() {
1026         test_mkdir -c1 $DIR/R8a
1027         test_mkdir -c1 $DIR/R8b
1028         test_mkdir -c1 $DIR/R8a/d
1029         test_mkdir -c1 $DIR/R8b/e
1030         mrename $DIR/R8a/d $DIR/R8b/e
1031         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1032         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1033 }
1034 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1035
1036 test_24i() {
1037         echo "-- rename error cases"
1038         test_mkdir $DIR/R9
1039         test_mkdir $DIR/R9/a
1040         touch $DIR/R9/f
1041         mrename $DIR/R9/f $DIR/R9/a
1042         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1043         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1044         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1045 }
1046 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1047
1048 test_24j() {
1049         test_mkdir $DIR/R10
1050         mrename $DIR/R10/f $DIR/R10/g
1051         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1052         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1053         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1054 }
1055 run_test 24j "source does not exist ============================"
1056
1057 test_24k() {
1058         test_mkdir $DIR/R11a
1059         test_mkdir $DIR/R11a/d
1060         touch $DIR/R11a/f
1061         mv $DIR/R11a/f $DIR/R11a/d
1062         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1063         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1064 }
1065 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1066
1067 # bug 2429 - rename foo foo foo creates invalid file
1068 test_24l() {
1069         f="$DIR/f24l"
1070         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1071 }
1072 run_test 24l "Renaming a file to itself ========================"
1073
1074 test_24m() {
1075         f="$DIR/f24m"
1076         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1077         # on ext3 this does not remove either the source or target files
1078         # though the "expected" operation would be to remove the source
1079         $CHECKSTAT -t file ${f} || error "${f} missing"
1080         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1081 }
1082 run_test 24m "Renaming a file to a hard link to itself ========="
1083
1084 test_24n() {
1085     f="$DIR/f24n"
1086     # this stats the old file after it was renamed, so it should fail
1087     touch ${f}
1088     $CHECKSTAT ${f} || error "${f} missing"
1089     mv ${f} ${f}.rename
1090     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1091     $CHECKSTAT -a ${f} || error "${f} exists"
1092 }
1093 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1094
1095 test_24o() {
1096         test_mkdir $DIR/$tdir
1097         rename_many -s random -v -n 10 $DIR/$tdir
1098 }
1099 run_test 24o "rename of files during htree split"
1100
1101 test_24p() {
1102         test_mkdir $DIR/R12a
1103         test_mkdir $DIR/R12b
1104         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1105         mrename $DIR/R12a $DIR/R12b
1106         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1107         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1108         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1109         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1110 }
1111 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1112
1113 cleanup_multiop_pause() {
1114         trap 0
1115         kill -USR1 $MULTIPID
1116 }
1117
1118 test_24q() {
1119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1120
1121         test_mkdir $DIR/R13a
1122         test_mkdir $DIR/R13b
1123         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1124         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1125         MULTIPID=$!
1126
1127         trap cleanup_multiop_pause EXIT
1128         mrename $DIR/R13a $DIR/R13b
1129         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1130         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1131         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1132         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1133         cleanup_multiop_pause
1134         wait $MULTIPID || error "multiop close failed"
1135 }
1136 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1137
1138 test_24r() { #bug 3789
1139         test_mkdir $DIR/R14a
1140         test_mkdir $DIR/R14a/b
1141         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1142         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1143         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1144 }
1145 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1146
1147 test_24s() {
1148         test_mkdir $DIR/R15a
1149         test_mkdir $DIR/R15a/b
1150         test_mkdir $DIR/R15a/b/c
1151         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1152         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1153         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1154 }
1155 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1156 test_24t() {
1157         test_mkdir $DIR/R16a
1158         test_mkdir $DIR/R16a/b
1159         test_mkdir $DIR/R16a/b/c
1160         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1161         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1162         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1163 }
1164 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1165
1166 test_24u() { # bug12192
1167         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1168         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1169 }
1170 run_test 24u "create stripe file"
1171
1172 simple_cleanup_common() {
1173         local createmany=$1
1174         local rc=0
1175
1176         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1177
1178         local start=$SECONDS
1179
1180         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1181         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1182         rc=$?
1183         wait_delete_completed
1184         echo "cleanup time $((SECONDS - start))"
1185         return $rc
1186 }
1187
1188 max_pages_per_rpc() {
1189         local mdtname="$(printf "MDT%04x" ${1:-0})"
1190         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1191 }
1192
1193 test_24v() {
1194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1195
1196         local nrfiles=${COUNT:-100000}
1197         local fname="$DIR/$tdir/$tfile"
1198
1199         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1200         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1201
1202         test_mkdir "$(dirname $fname)"
1203         # assume MDT0000 has the fewest inodes
1204         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1205         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1206         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1207
1208         stack_trap "simple_cleanup_common $nrfiles"
1209
1210         createmany -m "$fname" $nrfiles
1211
1212         cancel_lru_locks mdc
1213         lctl set_param mdc.*.stats clear
1214
1215         # was previously test_24D: LU-6101
1216         # readdir() returns correct number of entries after cursor reload
1217         local num_ls=$(ls $DIR/$tdir | wc -l)
1218         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1219         local num_all=$(ls -a $DIR/$tdir | wc -l)
1220         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1221                 [ $num_all -ne $((nrfiles + 2)) ]; then
1222                         error "Expected $nrfiles files, got $num_ls " \
1223                                 "($num_uniq unique $num_all .&..)"
1224         fi
1225         # LU-5 large readdir
1226         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1227         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1228         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1229         # take into account of overhead in lu_dirpage header and end mark in
1230         # each page, plus one in rpc_num calculation.
1231         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1232         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1233         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1234         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1235         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1236         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1237         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1238         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1239                 error "large readdir doesn't take effect: " \
1240                       "$mds_readpage should be about $rpc_max"
1241 }
1242 run_test 24v "list large directory (test hash collision, b=17560)"
1243
1244 test_24w() { # bug21506
1245         SZ1=234852
1246         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1247         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1248         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1249         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1250         [[ "$SZ1" -eq "$SZ2" ]] ||
1251                 error "Error reading at the end of the file $tfile"
1252 }
1253 run_test 24w "Reading a file larger than 4Gb"
1254
1255 test_24x() {
1256         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1258         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1259                 skip "Need MDS version at least 2.7.56"
1260
1261         local MDTIDX=1
1262         local remote_dir=$DIR/$tdir/remote_dir
1263
1264         test_mkdir $DIR/$tdir
1265         $LFS mkdir -i $MDTIDX $remote_dir ||
1266                 error "create remote directory failed"
1267
1268         test_mkdir $DIR/$tdir/src_dir
1269         touch $DIR/$tdir/src_file
1270         test_mkdir $remote_dir/tgt_dir
1271         touch $remote_dir/tgt_file
1272
1273         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1274                 error "rename dir cross MDT failed!"
1275
1276         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1277                 error "rename file cross MDT failed!"
1278
1279         touch $DIR/$tdir/ln_file
1280         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1281                 error "ln file cross MDT failed"
1282
1283         rm -rf $DIR/$tdir || error "Can not delete directories"
1284 }
1285 run_test 24x "cross MDT rename/link"
1286
1287 test_24y() {
1288         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1290
1291         local remote_dir=$DIR/$tdir/remote_dir
1292         local mdtidx=1
1293
1294         test_mkdir $DIR/$tdir
1295         $LFS mkdir -i $mdtidx $remote_dir ||
1296                 error "create remote directory failed"
1297
1298         test_mkdir $remote_dir/src_dir
1299         touch $remote_dir/src_file
1300         test_mkdir $remote_dir/tgt_dir
1301         touch $remote_dir/tgt_file
1302
1303         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1304                 error "rename subdir in the same remote dir failed!"
1305
1306         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1307                 error "rename files in the same remote dir failed!"
1308
1309         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1310                 error "link files in the same remote dir failed!"
1311
1312         rm -rf $DIR/$tdir || error "Can not delete directories"
1313 }
1314 run_test 24y "rename/link on the same dir should succeed"
1315
1316 test_24z() {
1317         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1318         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1319                 skip "Need MDS version at least 2.12.51"
1320
1321         local index
1322
1323         for index in 0 1; do
1324                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1325                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1326         done
1327
1328         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1329
1330         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1331         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1332
1333         local mdts=$(comma_list $(mdts_nodes))
1334
1335         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1336         stack_trap "do_nodes $mdts $LCTL \
1337                 set_param mdt.*.enable_remote_rename=1" EXIT
1338
1339         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1340
1341         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1342         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1343 }
1344 run_test 24z "cross-MDT rename is done as cp"
1345
1346 test_24A() { # LU-3182
1347         local NFILES=5000
1348
1349         test_mkdir $DIR/$tdir
1350         stack_trap "simple_cleanup_common $NFILES"
1351         createmany -m $DIR/$tdir/$tfile $NFILES
1352         local t=$(ls $DIR/$tdir | wc -l)
1353         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1354         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1355
1356         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1357                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1358 }
1359 run_test 24A "readdir() returns correct number of entries."
1360
1361 test_24B() { # LU-4805
1362         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1363
1364         local count
1365
1366         test_mkdir $DIR/$tdir
1367         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1368                 error "create striped dir failed"
1369
1370         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1371         [ $count -eq 2 ] || error "Expected 2, got $count"
1372
1373         touch $DIR/$tdir/striped_dir/a
1374
1375         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1376         [ $count -eq 3 ] || error "Expected 3, got $count"
1377
1378         touch $DIR/$tdir/striped_dir/.f
1379
1380         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1381         [ $count -eq 4 ] || error "Expected 4, got $count"
1382
1383         rm -rf $DIR/$tdir || error "Can not delete directories"
1384 }
1385 run_test 24B "readdir for striped dir return correct number of entries"
1386
1387 test_24C() {
1388         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1389
1390         mkdir $DIR/$tdir
1391         mkdir $DIR/$tdir/d0
1392         mkdir $DIR/$tdir/d1
1393
1394         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1395                 error "create striped dir failed"
1396
1397         cd $DIR/$tdir/d0/striped_dir
1398
1399         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1400         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1401         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1402
1403         [ "$d0_ino" = "$parent_ino" ] ||
1404                 error ".. wrong, expect $d0_ino, get $parent_ino"
1405
1406         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1407                 error "mv striped dir failed"
1408
1409         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1410
1411         [ "$d1_ino" = "$parent_ino" ] ||
1412                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1413 }
1414 run_test 24C "check .. in striped dir"
1415
1416 test_24E() {
1417         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1419
1420         mkdir -p $DIR/$tdir
1421         mkdir $DIR/$tdir/src_dir
1422         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1423                 error "create remote source failed"
1424
1425         touch $DIR/$tdir/src_dir/src_child/a
1426
1427         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1428                 error "create remote target dir failed"
1429
1430         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1431                 error "create remote target child failed"
1432
1433         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1434                 error "rename dir cross MDT failed!"
1435
1436         find $DIR/$tdir
1437
1438         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1439                 error "src_child still exists after rename"
1440
1441         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1442                 error "missing file(a) after rename"
1443
1444         rm -rf $DIR/$tdir || error "Can not delete directories"
1445 }
1446 run_test 24E "cross MDT rename/link"
1447
1448 test_24F () {
1449         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1450
1451         local repeats=1000
1452         [ "$SLOW" = "no" ] && repeats=100
1453
1454         mkdir -p $DIR/$tdir
1455
1456         echo "$repeats repeats"
1457         for ((i = 0; i < repeats; i++)); do
1458                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1459                 touch $DIR/$tdir/test/a || error "touch fails"
1460                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1461                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1462         done
1463
1464         true
1465 }
1466 run_test 24F "hash order vs readdir (LU-11330)"
1467
1468 test_24G () {
1469         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1470
1471         local ino1
1472         local ino2
1473
1474         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1475         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1476         touch $DIR/$tdir-0/f1 || error "touch f1"
1477         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1478         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1479         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1480         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1481         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1482 }
1483 run_test 24G "migrate symlink in rename"
1484
1485 test_24H() {
1486         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1487         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1488                 skip "MDT1 should be on another node"
1489
1490         test_mkdir -i 1 -c 1 $DIR/$tdir
1491 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1492         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1493         touch $DIR/$tdir/$tfile || error "touch failed"
1494 }
1495 run_test 24H "repeat FLD_QUERY rpc"
1496
1497 test_25a() {
1498         echo '== symlink sanity ============================================='
1499
1500         test_mkdir $DIR/d25
1501         ln -s d25 $DIR/s25
1502         touch $DIR/s25/foo ||
1503                 error "File creation in symlinked directory failed"
1504 }
1505 run_test 25a "create file in symlinked directory ==============="
1506
1507 test_25b() {
1508         [ ! -d $DIR/d25 ] && test_25a
1509         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1510 }
1511 run_test 25b "lookup file in symlinked directory ==============="
1512
1513 test_26a() {
1514         test_mkdir $DIR/d26
1515         test_mkdir $DIR/d26/d26-2
1516         ln -s d26/d26-2 $DIR/s26
1517         touch $DIR/s26/foo || error "File creation failed"
1518 }
1519 run_test 26a "multiple component symlink ======================="
1520
1521 test_26b() {
1522         test_mkdir -p $DIR/$tdir/d26-2
1523         ln -s $tdir/d26-2/foo $DIR/s26-2
1524         touch $DIR/s26-2 || error "File creation failed"
1525 }
1526 run_test 26b "multiple component symlink at end of lookup ======"
1527
1528 test_26c() {
1529         test_mkdir $DIR/d26.2
1530         touch $DIR/d26.2/foo
1531         ln -s d26.2 $DIR/s26.2-1
1532         ln -s s26.2-1 $DIR/s26.2-2
1533         ln -s s26.2-2 $DIR/s26.2-3
1534         chmod 0666 $DIR/s26.2-3/foo
1535 }
1536 run_test 26c "chain of symlinks"
1537
1538 # recursive symlinks (bug 439)
1539 test_26d() {
1540         ln -s d26-3/foo $DIR/d26-3
1541 }
1542 run_test 26d "create multiple component recursive symlink"
1543
1544 test_26e() {
1545         [ ! -h $DIR/d26-3 ] && test_26d
1546         rm $DIR/d26-3
1547 }
1548 run_test 26e "unlink multiple component recursive symlink"
1549
1550 # recursive symlinks (bug 7022)
1551 test_26f() {
1552         test_mkdir $DIR/$tdir
1553         test_mkdir $DIR/$tdir/$tfile
1554         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1555         test_mkdir -p lndir/bar1
1556         test_mkdir $DIR/$tdir/$tfile/$tfile
1557         cd $tfile                || error "cd $tfile failed"
1558         ln -s .. dotdot          || error "ln dotdot failed"
1559         ln -s dotdot/lndir lndir || error "ln lndir failed"
1560         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1561         output=`ls $tfile/$tfile/lndir/bar1`
1562         [ "$output" = bar1 ] && error "unexpected output"
1563         rm -r $tfile             || error "rm $tfile failed"
1564         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1565 }
1566 run_test 26f "rm -r of a directory which has recursive symlink"
1567
1568 test_27a() {
1569         test_mkdir $DIR/$tdir
1570         $LFS getstripe $DIR/$tdir
1571         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1572         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1573         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1574 }
1575 run_test 27a "one stripe file"
1576
1577 test_27b() {
1578         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1579
1580         test_mkdir $DIR/$tdir
1581         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1582         $LFS getstripe -c $DIR/$tdir/$tfile
1583         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1584                 error "two-stripe file doesn't have two stripes"
1585
1586         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1587 }
1588 run_test 27b "create and write to two stripe file"
1589
1590 # 27c family tests specific striping, setstripe -o
1591 test_27ca() {
1592         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1593         test_mkdir -p $DIR/$tdir
1594         local osts="1"
1595
1596         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1597         $LFS getstripe -i $DIR/$tdir/$tfile
1598         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1599                 error "stripe not on specified OST"
1600
1601         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1602 }
1603 run_test 27ca "one stripe on specified OST"
1604
1605 test_27cb() {
1606         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1607         test_mkdir -p $DIR/$tdir
1608         local osts="1,0"
1609         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1610         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1611         echo "$getstripe"
1612
1613         # Strip getstripe output to a space separated list of OSTs
1614         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1615                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1616         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1617                 error "stripes not on specified OSTs"
1618
1619         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1620 }
1621 run_test 27cb "two stripes on specified OSTs"
1622
1623 test_27cc() {
1624         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1625         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1626                 skip "server does not support overstriping"
1627
1628         test_mkdir -p $DIR/$tdir
1629         local osts="0,0"
1630         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1631         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1632         echo "$getstripe"
1633
1634         # Strip getstripe output to a space separated list of OSTs
1635         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1636                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1637         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1638                 error "stripes not on specified OSTs"
1639
1640         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1641 }
1642 run_test 27cc "two stripes on the same OST"
1643
1644 test_27cd() {
1645         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1646         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1647                 skip "server does not support overstriping"
1648         test_mkdir -p $DIR/$tdir
1649         local osts="0,1,1,0"
1650         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1651         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1652         echo "$getstripe"
1653
1654         # Strip getstripe output to a space separated list of OSTs
1655         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1656                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1657         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1658                 error "stripes not on specified OSTs"
1659
1660         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1661 }
1662 run_test 27cd "four stripes on two OSTs"
1663
1664 test_27ce() {
1665         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1666                 skip_env "too many osts, skipping"
1667         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1668                 skip "server does not support overstriping"
1669         # We do one more stripe than we have OSTs
1670         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1671                 skip_env "ea_inode feature disabled"
1672
1673         test_mkdir -p $DIR/$tdir
1674         local osts=""
1675         for i in $(seq 0 $OSTCOUNT);
1676         do
1677                 osts=$osts"0"
1678                 if [ $i -ne $OSTCOUNT ]; then
1679                         osts=$osts","
1680                 fi
1681         done
1682         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1683         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1684         echo "$getstripe"
1685
1686         # Strip getstripe output to a space separated list of OSTs
1687         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1688                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1689         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1690                 error "stripes not on specified OSTs"
1691
1692         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1693 }
1694 run_test 27ce "more stripes than OSTs with -o"
1695
1696 test_27cf() {
1697         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1698         local pid=0
1699
1700         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1701         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1702         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1703         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1704                 error "failed to set $osp_proc=0"
1705
1706         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1707         pid=$!
1708         sleep 1
1709         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1710         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1711                 error "failed to set $osp_proc=1"
1712         wait $pid
1713         [[ $pid -ne 0 ]] ||
1714                 error "should return error due to $osp_proc=0"
1715 }
1716 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1717
1718 test_27d() {
1719         test_mkdir $DIR/$tdir
1720         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1721                 error "setstripe failed"
1722         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1723         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1724 }
1725 run_test 27d "create file with default settings"
1726
1727 test_27e() {
1728         # LU-5839 adds check for existed layout before setting it
1729         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1730                 skip "Need MDS version at least 2.7.56"
1731
1732         test_mkdir $DIR/$tdir
1733         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1734         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1735         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1736 }
1737 run_test 27e "setstripe existing file (should return error)"
1738
1739 test_27f() {
1740         test_mkdir $DIR/$tdir
1741         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1742                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1743         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1744                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1745         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1746         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1747 }
1748 run_test 27f "setstripe with bad stripe size (should return error)"
1749
1750 test_27g() {
1751         test_mkdir $DIR/$tdir
1752         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1753         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1754                 error "$DIR/$tdir/$tfile has object"
1755 }
1756 run_test 27g "$LFS getstripe with no objects"
1757
1758 test_27ga() {
1759         test_mkdir $DIR/$tdir
1760         touch $DIR/$tdir/$tfile || error "touch failed"
1761         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1762         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1763         local rc=$?
1764         (( rc == 2 )) || error "getstripe did not return ENOENT"
1765 }
1766 run_test 27ga "$LFS getstripe with missing file (should return error)"
1767
1768 test_27i() {
1769         test_mkdir $DIR/$tdir
1770         touch $DIR/$tdir/$tfile || error "touch failed"
1771         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1772                 error "missing objects"
1773 }
1774 run_test 27i "$LFS getstripe with some objects"
1775
1776 test_27j() {
1777         test_mkdir $DIR/$tdir
1778         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1779                 error "setstripe failed" || true
1780 }
1781 run_test 27j "setstripe with bad stripe offset (should return error)"
1782
1783 test_27k() { # bug 2844
1784         test_mkdir $DIR/$tdir
1785         local file=$DIR/$tdir/$tfile
1786         local ll_max_blksize=$((4 * 1024 * 1024))
1787         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1788         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1789         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1790         dd if=/dev/zero of=$file bs=4k count=1
1791         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1792         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1793 }
1794 run_test 27k "limit i_blksize for broken user apps"
1795
1796 test_27l() {
1797         mcreate $DIR/$tfile || error "creating file"
1798         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1799                 error "setstripe should have failed" || true
1800 }
1801 run_test 27l "check setstripe permissions (should return error)"
1802
1803 test_27m() {
1804         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1805
1806         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1807                 skip_env "multiple clients -- skipping"
1808
1809         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1810                    head -n1)
1811         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1812                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1813         fi
1814         stack_trap simple_cleanup_common
1815         test_mkdir $DIR/$tdir
1816         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1817         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1818                 error "dd should fill OST0"
1819         i=2
1820         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1821                 i=$((i + 1))
1822                 [ $i -gt 256 ] && break
1823         done
1824         i=$((i + 1))
1825         touch $DIR/$tdir/$tfile.$i
1826         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1827             awk '{print $1}'| grep -w "0") ] &&
1828                 error "OST0 was full but new created file still use it"
1829         i=$((i + 1))
1830         touch $DIR/$tdir/$tfile.$i
1831         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1832             awk '{print $1}'| grep -w "0") ] &&
1833                 error "OST0 was full but new created file still use it" || true
1834 }
1835 run_test 27m "create file while OST0 was full"
1836
1837 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1838 # if the OST isn't full anymore.
1839 reset_enospc() {
1840         local ostidx=${1:-""}
1841         local delay
1842         local ready
1843         local get_prealloc
1844
1845         local list=$(comma_list $(osts_nodes))
1846         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1847
1848         do_nodes $list lctl set_param fail_loc=0
1849         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1850         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1851                 awk '{print $1 * 2;exit;}')
1852         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1853                         grep -v \"^0$\""
1854         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1855 }
1856
1857 test_27n() {
1858         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1860         remote_mds_nodsh && skip "remote MDS with nodsh"
1861         remote_ost_nodsh && skip "remote OST with nodsh"
1862
1863         reset_enospc
1864         rm -f $DIR/$tdir/$tfile
1865         exhaust_precreations 0 0x80000215
1866         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1867         touch $DIR/$tdir/$tfile || error "touch failed"
1868         $LFS getstripe $DIR/$tdir/$tfile
1869         reset_enospc
1870 }
1871 run_test 27n "create file with some full OSTs"
1872
1873 test_27o() {
1874         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1876         remote_mds_nodsh && skip "remote MDS with nodsh"
1877         remote_ost_nodsh && skip "remote OST with nodsh"
1878
1879         reset_enospc
1880         rm -f $DIR/$tdir/$tfile
1881         exhaust_all_precreations 0x215
1882
1883         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1884
1885         reset_enospc
1886         rm -rf $DIR/$tdir/*
1887 }
1888 run_test 27o "create file with all full OSTs (should error)"
1889
1890 function create_and_checktime() {
1891         local fname=$1
1892         local loops=$2
1893         local i
1894
1895         for ((i=0; i < $loops; i++)); do
1896                 local start=$SECONDS
1897                 multiop $fname-$i Oc
1898                 ((SECONDS-start < TIMEOUT)) ||
1899                         error "creation took " $((SECONDS-$start)) && return 1
1900         done
1901 }
1902
1903 test_27oo() {
1904         local mdts=$(comma_list $(mdts_nodes))
1905
1906         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1907                 skip "Need MDS version at least 2.13.57"
1908
1909         local f0=$DIR/${tfile}-0
1910         local f1=$DIR/${tfile}-1
1911
1912         wait_delete_completed
1913
1914         # refill precreated objects
1915         $LFS setstripe -i0 -c1 $f0
1916
1917         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1918         # force QoS allocation policy
1919         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1920         stack_trap "do_nodes $mdts $LCTL set_param \
1921                 lov.*.qos_threshold_rr=$saved" EXIT
1922         sleep_maxage
1923
1924         # one OST is unavailable, but still have few objects preallocated
1925         stop ost1
1926         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1927                 rm -rf $f1 $DIR/$tdir*" EXIT
1928
1929         for ((i=0; i < 7; i++)); do
1930                 mkdir $DIR/$tdir$i || error "can't create dir"
1931                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1932                         error "can't set striping"
1933         done
1934         for ((i=0; i < 7; i++)); do
1935                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1936         done
1937         wait
1938 }
1939 run_test 27oo "don't let few threads to reserve too many objects"
1940
1941 test_27p() {
1942         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1944         remote_mds_nodsh && skip "remote MDS with nodsh"
1945         remote_ost_nodsh && skip "remote OST with nodsh"
1946
1947         reset_enospc
1948         rm -f $DIR/$tdir/$tfile
1949         test_mkdir $DIR/$tdir
1950
1951         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1952         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1953         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1954
1955         exhaust_precreations 0 0x80000215
1956         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1957         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1958         $LFS getstripe $DIR/$tdir/$tfile
1959
1960         reset_enospc
1961 }
1962 run_test 27p "append to a truncated file with some full OSTs"
1963
1964 test_27q() {
1965         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1967         remote_mds_nodsh && skip "remote MDS with nodsh"
1968         remote_ost_nodsh && skip "remote OST with nodsh"
1969
1970         reset_enospc
1971         rm -f $DIR/$tdir/$tfile
1972
1973         mkdir_on_mdt0 $DIR/$tdir
1974         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1975         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1976                 error "truncate $DIR/$tdir/$tfile failed"
1977         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1978
1979         exhaust_all_precreations 0x215
1980
1981         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1982         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1983
1984         reset_enospc
1985 }
1986 run_test 27q "append to truncated file with all OSTs full (should error)"
1987
1988 test_27r() {
1989         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1991         remote_mds_nodsh && skip "remote MDS with nodsh"
1992         remote_ost_nodsh && skip "remote OST with nodsh"
1993
1994         reset_enospc
1995         rm -f $DIR/$tdir/$tfile
1996         exhaust_precreations 0 0x80000215
1997
1998         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1999
2000         reset_enospc
2001 }
2002 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2003
2004 test_27s() { # bug 10725
2005         test_mkdir $DIR/$tdir
2006         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2007         local stripe_count=0
2008         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2009         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2010                 error "stripe width >= 2^32 succeeded" || true
2011
2012 }
2013 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2014
2015 test_27t() { # bug 10864
2016         WDIR=$(pwd)
2017         WLFS=$(which lfs)
2018         cd $DIR
2019         touch $tfile
2020         $WLFS getstripe $tfile
2021         cd $WDIR
2022 }
2023 run_test 27t "check that utils parse path correctly"
2024
2025 test_27u() { # bug 4900
2026         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2027         remote_mds_nodsh && skip "remote MDS with nodsh"
2028
2029         local index
2030         local list=$(comma_list $(mdts_nodes))
2031
2032 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2033         do_nodes $list $LCTL set_param fail_loc=0x139
2034         test_mkdir -p $DIR/$tdir
2035         stack_trap "simple_cleanup_common 1000"
2036         createmany -o $DIR/$tdir/$tfile 1000
2037         do_nodes $list $LCTL set_param fail_loc=0
2038
2039         TLOG=$TMP/$tfile.getstripe
2040         $LFS getstripe $DIR/$tdir > $TLOG
2041         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2042         [[ $OBJS -gt 0 ]] &&
2043                 error "$OBJS objects created on OST-0. See $TLOG" ||
2044                 rm -f $TLOG
2045 }
2046 run_test 27u "skip object creation on OSC w/o objects"
2047
2048 test_27v() { # bug 4900
2049         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2051         remote_mds_nodsh && skip "remote MDS with nodsh"
2052         remote_ost_nodsh && skip "remote OST with nodsh"
2053
2054         exhaust_all_precreations 0x215
2055         reset_enospc
2056
2057         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2058
2059         touch $DIR/$tdir/$tfile
2060         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2061         # all except ost1
2062         for (( i=1; i < OSTCOUNT; i++ )); do
2063                 do_facet ost$i lctl set_param fail_loc=0x705
2064         done
2065         local START=`date +%s`
2066         createmany -o $DIR/$tdir/$tfile 32
2067
2068         local FINISH=`date +%s`
2069         local TIMEOUT=`lctl get_param -n timeout`
2070         local PROCESS=$((FINISH - START))
2071         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2072                error "$FINISH - $START >= $TIMEOUT / 2"
2073         sleep $((TIMEOUT / 2 - PROCESS))
2074         reset_enospc
2075 }
2076 run_test 27v "skip object creation on slow OST"
2077
2078 test_27w() { # bug 10997
2079         test_mkdir $DIR/$tdir
2080         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2081         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2082                 error "stripe size $size != 65536" || true
2083         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2084                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2085 }
2086 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2087
2088 test_27wa() {
2089         [[ $OSTCOUNT -lt 2 ]] &&
2090                 skip_env "skipping multiple stripe count/offset test"
2091
2092         test_mkdir $DIR/$tdir
2093         for i in $(seq 1 $OSTCOUNT); do
2094                 offset=$((i - 1))
2095                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2096                         error "setstripe -c $i -i $offset failed"
2097                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2098                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2099                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2100                 [ $index -ne $offset ] &&
2101                         error "stripe offset $index != $offset" || true
2102         done
2103 }
2104 run_test 27wa "check $LFS setstripe -c -i options"
2105
2106 test_27x() {
2107         remote_ost_nodsh && skip "remote OST with nodsh"
2108         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2110
2111         OFFSET=$(($OSTCOUNT - 1))
2112         OSTIDX=0
2113         local OST=$(ostname_from_index $OSTIDX)
2114
2115         test_mkdir $DIR/$tdir
2116         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2117         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2118         sleep_maxage
2119         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2120         for i in $(seq 0 $OFFSET); do
2121                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2122                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2123                 error "OST0 was degraded but new created file still use it"
2124         done
2125         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2126 }
2127 run_test 27x "create files while OST0 is degraded"
2128
2129 test_27y() {
2130         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2131         remote_mds_nodsh && skip "remote MDS with nodsh"
2132         remote_ost_nodsh && skip "remote OST with nodsh"
2133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2134
2135         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2136         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2137                 osp.$mdtosc.prealloc_last_id)
2138         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2139                 osp.$mdtosc.prealloc_next_id)
2140         local fcount=$((last_id - next_id))
2141         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2142         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2143
2144         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2145                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2146         local OST_DEACTIVE_IDX=-1
2147         local OSC
2148         local OSTIDX
2149         local OST
2150
2151         for OSC in $MDS_OSCS; do
2152                 OST=$(osc_to_ost $OSC)
2153                 OSTIDX=$(index_from_ostuuid $OST)
2154                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2155                         OST_DEACTIVE_IDX=$OSTIDX
2156                 fi
2157                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2158                         echo $OSC "is Deactivated:"
2159                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2160                 fi
2161         done
2162
2163         OSTIDX=$(index_from_ostuuid $OST)
2164         test_mkdir $DIR/$tdir
2165         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2166
2167         for OSC in $MDS_OSCS; do
2168                 OST=$(osc_to_ost $OSC)
2169                 OSTIDX=$(index_from_ostuuid $OST)
2170                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2171                         echo $OST "is degraded:"
2172                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2173                                                 obdfilter.$OST.degraded=1
2174                 fi
2175         done
2176
2177         sleep_maxage
2178         createmany -o $DIR/$tdir/$tfile $fcount
2179
2180         for OSC in $MDS_OSCS; do
2181                 OST=$(osc_to_ost $OSC)
2182                 OSTIDX=$(index_from_ostuuid $OST)
2183                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2184                         echo $OST "is recovered from degraded:"
2185                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2186                                                 obdfilter.$OST.degraded=0
2187                 else
2188                         do_facet $SINGLEMDS lctl --device %$OSC activate
2189                 fi
2190         done
2191
2192         # all osp devices get activated, hence -1 stripe count restored
2193         local stripe_count=0
2194
2195         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2196         # devices get activated.
2197         sleep_maxage
2198         $LFS setstripe -c -1 $DIR/$tfile
2199         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2200         rm -f $DIR/$tfile
2201         [ $stripe_count -ne $OSTCOUNT ] &&
2202                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2203         return 0
2204 }
2205 run_test 27y "create files while OST0 is degraded and the rest inactive"
2206
2207 check_seq_oid()
2208 {
2209         log "check file $1"
2210
2211         lmm_count=$($LFS getstripe -c $1)
2212         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2213         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2214
2215         local old_ifs="$IFS"
2216         IFS=$'[:]'
2217         fid=($($LFS path2fid $1))
2218         IFS="$old_ifs"
2219
2220         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2221         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2222
2223         # compare lmm_seq and lu_fid->f_seq
2224         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2225         # compare lmm_object_id and lu_fid->oid
2226         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2227
2228         # check the trusted.fid attribute of the OST objects of the file
2229         local have_obdidx=false
2230         local stripe_nr=0
2231         $LFS getstripe $1 | while read obdidx oid hex seq; do
2232                 # skip lines up to and including "obdidx"
2233                 [ -z "$obdidx" ] && break
2234                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2235                 $have_obdidx || continue
2236
2237                 local ost=$((obdidx + 1))
2238                 local dev=$(ostdevname $ost)
2239                 local oid_hex
2240
2241                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2242
2243                 seq=$(echo $seq | sed -e "s/^0x//g")
2244                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2245                         oid_hex=$(echo $oid)
2246                 else
2247                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2248                 fi
2249                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2250
2251                 local ff=""
2252                 #
2253                 # Don't unmount/remount the OSTs if we don't need to do that.
2254                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2255                 # update too, until that use mount/ll_decode_filter_fid/mount.
2256                 # Re-enable when debugfs will understand new filter_fid.
2257                 #
2258                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2259                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2260                                 $dev 2>/dev/null" | grep "parent=")
2261                 fi
2262                 if [ -z "$ff" ]; then
2263                         stop ost$ost
2264                         mount_fstype ost$ost
2265                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2266                                 $(facet_mntpt ost$ost)/$obj_file)
2267                         unmount_fstype ost$ost
2268                         start ost$ost $dev $OST_MOUNT_OPTS
2269                         clients_up
2270                 fi
2271
2272                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2273
2274                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2275
2276                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2277                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2278                 #
2279                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2280                 #       stripe_size=1048576 component_id=1 component_start=0 \
2281                 #       component_end=33554432
2282                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2283                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2284                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2285                 local ff_pstripe
2286                 if grep -q 'stripe=' <<<$ff; then
2287                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2288                 else
2289                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2290                         # into f_ver in this case.  See comment on ff_parent.
2291                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2292                 fi
2293
2294                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2295                 [ $ff_pseq = $lmm_seq ] ||
2296                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2297                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2298                 [ $ff_poid = $lmm_oid ] ||
2299                         error "FF parent OID $ff_poid != $lmm_oid"
2300                 (($ff_pstripe == $stripe_nr)) ||
2301                         error "FF stripe $ff_pstripe != $stripe_nr"
2302
2303                 stripe_nr=$((stripe_nr + 1))
2304                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2305                         continue
2306                 if grep -q 'stripe_count=' <<<$ff; then
2307                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2308                                             -e 's/ .*//' <<<$ff)
2309                         [ $lmm_count = $ff_scnt ] ||
2310                                 error "FF stripe count $lmm_count != $ff_scnt"
2311                 fi
2312         done
2313 }
2314
2315 test_27z() {
2316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2317         remote_ost_nodsh && skip "remote OST with nodsh"
2318
2319         test_mkdir $DIR/$tdir
2320         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2321                 { error "setstripe -c -1 failed"; return 1; }
2322         # We need to send a write to every object to get parent FID info set.
2323         # This _should_ also work for setattr, but does not currently.
2324         # touch $DIR/$tdir/$tfile-1 ||
2325         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2326                 { error "dd $tfile-1 failed"; return 2; }
2327         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2328                 { error "setstripe -c -1 failed"; return 3; }
2329         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2330                 { error "dd $tfile-2 failed"; return 4; }
2331
2332         # make sure write RPCs have been sent to OSTs
2333         sync; sleep 5; sync
2334
2335         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2336         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2337 }
2338 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2339
2340 test_27A() { # b=19102
2341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2342
2343         save_layout_restore_at_exit $MOUNT
2344         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2345         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2346                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2347         local default_size=$($LFS getstripe -S $MOUNT)
2348         local default_offset=$($LFS getstripe -i $MOUNT)
2349         local dsize=$(do_facet $SINGLEMDS \
2350                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2351         [ $default_size -eq $dsize ] ||
2352                 error "stripe size $default_size != $dsize"
2353         [ $default_offset -eq -1 ] ||
2354                 error "stripe offset $default_offset != -1"
2355 }
2356 run_test 27A "check filesystem-wide default LOV EA values"
2357
2358 test_27B() { # LU-2523
2359         test_mkdir $DIR/$tdir
2360         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2361         touch $DIR/$tdir/f0
2362         # open f1 with O_LOV_DELAY_CREATE
2363         # rename f0 onto f1
2364         # call setstripe ioctl on open file descriptor for f1
2365         # close
2366         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2367                 $DIR/$tdir/f0
2368
2369         rm -f $DIR/$tdir/f1
2370         # open f1 with O_LOV_DELAY_CREATE
2371         # unlink f1
2372         # call setstripe ioctl on open file descriptor for f1
2373         # close
2374         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2375
2376         # Allow multiop to fail in imitation of NFS's busted semantics.
2377         true
2378 }
2379 run_test 27B "call setstripe on open unlinked file/rename victim"
2380
2381 # 27C family tests full striping and overstriping
2382 test_27Ca() { #LU-2871
2383         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2384
2385         declare -a ost_idx
2386         local index
2387         local found
2388         local i
2389         local j
2390
2391         test_mkdir $DIR/$tdir
2392         cd $DIR/$tdir
2393         for i in $(seq 0 $((OSTCOUNT - 1))); do
2394                 # set stripe across all OSTs starting from OST$i
2395                 $LFS setstripe -i $i -c -1 $tfile$i
2396                 # get striping information
2397                 ost_idx=($($LFS getstripe $tfile$i |
2398                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2399                 echo "OST Index: ${ost_idx[*]}"
2400
2401                 # check the layout
2402                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2403                         error "${#ost_idx[@]} != $OSTCOUNT"
2404
2405                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2406                         found=0
2407                         for j in "${ost_idx[@]}"; do
2408                                 if [ $index -eq $j ]; then
2409                                         found=1
2410                                         break
2411                                 fi
2412                         done
2413                         [ $found = 1 ] ||
2414                                 error "Can not find $index in ${ost_idx[*]}"
2415                 done
2416         done
2417 }
2418 run_test 27Ca "check full striping across all OSTs"
2419
2420 test_27Cb() {
2421         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2422                 skip "server does not support overstriping"
2423         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2424                 skip_env "too many osts, skipping"
2425
2426         test_mkdir -p $DIR/$tdir
2427         local setcount=$(($OSTCOUNT * 2))
2428         [ $setcount -lt 160 ] || large_xattr_enabled ||
2429                 skip_env "ea_inode feature disabled"
2430
2431         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2432                 error "setstripe failed"
2433
2434         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2435         [ $count -eq $setcount ] ||
2436                 error "stripe count $count, should be $setcount"
2437
2438         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2439                 error "overstriped should be set in pattern"
2440
2441         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2442                 error "dd failed"
2443 }
2444 run_test 27Cb "more stripes than OSTs with -C"
2445
2446 test_27Cc() {
2447         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2448                 skip "server does not support overstriping"
2449         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2450
2451         test_mkdir -p $DIR/$tdir
2452         local setcount=$(($OSTCOUNT - 1))
2453
2454         [ $setcount -lt 160 ] || large_xattr_enabled ||
2455                 skip_env "ea_inode feature disabled"
2456
2457         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2458                 error "setstripe failed"
2459
2460         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2461         [ $count -eq $setcount ] ||
2462                 error "stripe count $count, should be $setcount"
2463
2464         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2465                 error "overstriped should not be set in pattern"
2466
2467         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2468                 error "dd failed"
2469 }
2470 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2471
2472 test_27Cd() {
2473         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2474                 skip "server does not support overstriping"
2475         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2476         large_xattr_enabled || skip_env "ea_inode feature disabled"
2477
2478         test_mkdir -p $DIR/$tdir
2479         local setcount=$LOV_MAX_STRIPE_COUNT
2480
2481         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2482                 error "setstripe failed"
2483
2484         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2485         [ $count -eq $setcount ] ||
2486                 error "stripe count $count, should be $setcount"
2487
2488         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2489                 error "overstriped should be set in pattern"
2490
2491         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2492                 error "dd failed"
2493
2494         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2495 }
2496 run_test 27Cd "test maximum stripe count"
2497
2498 test_27Ce() {
2499         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2500                 skip "server does not support overstriping"
2501         test_mkdir -p $DIR/$tdir
2502
2503         pool_add $TESTNAME || error "Pool creation failed"
2504         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2505
2506         local setcount=8
2507
2508         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2509                 error "setstripe failed"
2510
2511         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2512         [ $count -eq $setcount ] ||
2513                 error "stripe count $count, should be $setcount"
2514
2515         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2516                 error "overstriped should be set in pattern"
2517
2518         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2519                 error "dd failed"
2520
2521         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2522 }
2523 run_test 27Ce "test pool with overstriping"
2524
2525 test_27Cf() {
2526         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2527                 skip "server does not support overstriping"
2528         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2529                 skip_env "too many osts, skipping"
2530
2531         test_mkdir -p $DIR/$tdir
2532
2533         local setcount=$(($OSTCOUNT * 2))
2534         [ $setcount -lt 160 ] || large_xattr_enabled ||
2535                 skip_env "ea_inode feature disabled"
2536
2537         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2538                 error "setstripe failed"
2539
2540         echo 1 > $DIR/$tdir/$tfile
2541
2542         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2543         [ $count -eq $setcount ] ||
2544                 error "stripe count $count, should be $setcount"
2545
2546         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2547                 error "overstriped should be set in pattern"
2548
2549         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2550                 error "dd failed"
2551
2552         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2553 }
2554 run_test 27Cf "test default inheritance with overstriping"
2555
2556 test_27D() {
2557         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2558         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2559         remote_mds_nodsh && skip "remote MDS with nodsh"
2560
2561         local POOL=${POOL:-testpool}
2562         local first_ost=0
2563         local last_ost=$(($OSTCOUNT - 1))
2564         local ost_step=1
2565         local ost_list=$(seq $first_ost $ost_step $last_ost)
2566         local ost_range="$first_ost $last_ost $ost_step"
2567
2568         test_mkdir $DIR/$tdir
2569         pool_add $POOL || error "pool_add failed"
2570         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2571
2572         local skip27D
2573         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2574                 skip27D+="-s 29"
2575         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2576                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2577                         skip27D+=" -s 30,31"
2578         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2579           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2580                 skip27D+=" -s 32,33"
2581         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2582                 skip27D+=" -s 34"
2583         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2584                 error "llapi_layout_test failed"
2585
2586         destroy_test_pools || error "destroy test pools failed"
2587 }
2588 run_test 27D "validate llapi_layout API"
2589
2590 # Verify that default_easize is increased from its initial value after
2591 # accessing a widely striped file.
2592 test_27E() {
2593         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2594         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2595                 skip "client does not have LU-3338 fix"
2596
2597         # 72 bytes is the minimum space required to store striping
2598         # information for a file striped across one OST:
2599         # (sizeof(struct lov_user_md_v3) +
2600         #  sizeof(struct lov_user_ost_data_v1))
2601         local min_easize=72
2602         $LCTL set_param -n llite.*.default_easize $min_easize ||
2603                 error "lctl set_param failed"
2604         local easize=$($LCTL get_param -n llite.*.default_easize)
2605
2606         [ $easize -eq $min_easize ] ||
2607                 error "failed to set default_easize"
2608
2609         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2610                 error "setstripe failed"
2611         # In order to ensure stat() call actually talks to MDS we need to
2612         # do something drastic to this file to shake off all lock, e.g.
2613         # rename it (kills lookup lock forcing cache cleaning)
2614         mv $DIR/$tfile $DIR/${tfile}-1
2615         ls -l $DIR/${tfile}-1
2616         rm $DIR/${tfile}-1
2617
2618         easize=$($LCTL get_param -n llite.*.default_easize)
2619
2620         [ $easize -gt $min_easize ] ||
2621                 error "default_easize not updated"
2622 }
2623 run_test 27E "check that default extended attribute size properly increases"
2624
2625 test_27F() { # LU-5346/LU-7975
2626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2627         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2628         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2629                 skip "Need MDS version at least 2.8.51"
2630         remote_ost_nodsh && skip "remote OST with nodsh"
2631
2632         test_mkdir $DIR/$tdir
2633         rm -f $DIR/$tdir/f0
2634         $LFS setstripe -c 2 $DIR/$tdir
2635
2636         # stop all OSTs to reproduce situation for LU-7975 ticket
2637         for num in $(seq $OSTCOUNT); do
2638                 stop ost$num
2639         done
2640
2641         # open/create f0 with O_LOV_DELAY_CREATE
2642         # truncate f0 to a non-0 size
2643         # close
2644         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2645
2646         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2647         # open/write it again to force delayed layout creation
2648         cat /etc/hosts > $DIR/$tdir/f0 &
2649         catpid=$!
2650
2651         # restart OSTs
2652         for num in $(seq $OSTCOUNT); do
2653                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2654                         error "ost$num failed to start"
2655         done
2656
2657         wait $catpid || error "cat failed"
2658
2659         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2660         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2661                 error "wrong stripecount"
2662
2663 }
2664 run_test 27F "Client resend delayed layout creation with non-zero size"
2665
2666 test_27G() { #LU-10629
2667         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2668                 skip "Need MDS version at least 2.11.51"
2669         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2670         remote_mds_nodsh && skip "remote MDS with nodsh"
2671         local POOL=${POOL:-testpool}
2672         local ostrange="0 0 1"
2673
2674         test_mkdir $DIR/$tdir
2675         touch $DIR/$tdir/$tfile.nopool
2676         pool_add $POOL || error "pool_add failed"
2677         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2678         $LFS setstripe -p $POOL $DIR/$tdir
2679
2680         local pool=$($LFS getstripe -p $DIR/$tdir)
2681
2682         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2683         touch $DIR/$tdir/$tfile.default
2684         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2685         $LFS find $DIR/$tdir -type f --pool $POOL
2686         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2687         [[ "$found" == "2" ]] ||
2688                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2689
2690         $LFS setstripe -d $DIR/$tdir
2691
2692         pool=$($LFS getstripe -p -d $DIR/$tdir)
2693
2694         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2695 }
2696 run_test 27G "Clear OST pool from stripe"
2697
2698 test_27H() {
2699         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2700                 skip "Need MDS version newer than 2.11.54"
2701         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2702         test_mkdir $DIR/$tdir
2703         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2704         touch $DIR/$tdir/$tfile
2705         $LFS getstripe -c $DIR/$tdir/$tfile
2706         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2707                 error "two-stripe file doesn't have two stripes"
2708
2709         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2710         $LFS getstripe -y $DIR/$tdir/$tfile
2711         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2712              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2713                 error "expected l_ost_idx: [02]$ not matched"
2714
2715         # make sure ost list has been cleared
2716         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2717         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2718                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2719         touch $DIR/$tdir/f3
2720         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2721 }
2722 run_test 27H "Set specific OSTs stripe"
2723
2724 test_27I() {
2725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2726         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2727         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2728                 skip "Need MDS version newer than 2.12.52"
2729         local pool=$TESTNAME
2730         local ostrange="1 1 1"
2731
2732         save_layout_restore_at_exit $MOUNT
2733         $LFS setstripe -c 2 -i 0 $MOUNT
2734         pool_add $pool || error "pool_add failed"
2735         pool_add_targets $pool $ostrange ||
2736                 error "pool_add_targets failed"
2737         test_mkdir $DIR/$tdir
2738         $LFS setstripe -p $pool $DIR/$tdir
2739         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2740         $LFS getstripe $DIR/$tdir/$tfile
2741 }
2742 run_test 27I "check that root dir striping does not break parent dir one"
2743
2744 test_27J() {
2745         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2746                 skip "Need MDS version newer than 2.12.51"
2747
2748         test_mkdir $DIR/$tdir
2749         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2750         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2751
2752         # create foreign file (raw way)
2753         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2754                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2755
2756         ! $LFS setstripe --foreign --flags foo \
2757                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2758                         error "creating $tfile with '--flags foo' should fail"
2759
2760         ! $LFS setstripe --foreign --flags 0xffffffff \
2761                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2762                         error "creating $tfile w/ 0xffffffff flags should fail"
2763
2764         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2765                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2766
2767         # verify foreign file (raw way)
2768         parse_foreign_file -f $DIR/$tdir/$tfile |
2769                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2770                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2771         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2772                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2773         parse_foreign_file -f $DIR/$tdir/$tfile |
2774                 grep "lov_foreign_size: 73" ||
2775                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2776         parse_foreign_file -f $DIR/$tdir/$tfile |
2777                 grep "lov_foreign_type: 1" ||
2778                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2779         parse_foreign_file -f $DIR/$tdir/$tfile |
2780                 grep "lov_foreign_flags: 0x0000DA08" ||
2781                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2782         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2783                 grep "lov_foreign_value: 0x" |
2784                 sed -e 's/lov_foreign_value: 0x//')
2785         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2786         [[ $lov = ${lov2// /} ]] ||
2787                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2788
2789         # create foreign file (lfs + API)
2790         $LFS setstripe --foreign=none --flags 0xda08 \
2791                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2792                 error "$DIR/$tdir/${tfile}2: create failed"
2793
2794         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2795                 grep "lfm_magic:.*0x0BD70BD0" ||
2796                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2797         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2798         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2799                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2800         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2801                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2802         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2803                 grep "lfm_flags:.*0x0000DA08" ||
2804                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2805         $LFS getstripe $DIR/$tdir/${tfile}2 |
2806                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2807                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2808
2809         # modify striping should fail
2810         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2811                 error "$DIR/$tdir/$tfile: setstripe should fail"
2812         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2813                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2814
2815         # R/W should fail
2816         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2817         cat $DIR/$tdir/${tfile}2 &&
2818                 error "$DIR/$tdir/${tfile}2: read should fail"
2819         cat /etc/passwd > $DIR/$tdir/$tfile &&
2820                 error "$DIR/$tdir/$tfile: write should fail"
2821         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2822                 error "$DIR/$tdir/${tfile}2: write should fail"
2823
2824         # chmod should work
2825         chmod 222 $DIR/$tdir/$tfile ||
2826                 error "$DIR/$tdir/$tfile: chmod failed"
2827         chmod 222 $DIR/$tdir/${tfile}2 ||
2828                 error "$DIR/$tdir/${tfile}2: chmod failed"
2829
2830         # chown should work
2831         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2832                 error "$DIR/$tdir/$tfile: chown failed"
2833         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2834                 error "$DIR/$tdir/${tfile}2: chown failed"
2835
2836         # rename should work
2837         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2838                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2839         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2840                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2841
2842         #remove foreign file
2843         rm $DIR/$tdir/${tfile}.new ||
2844                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2845         rm $DIR/$tdir/${tfile}2.new ||
2846                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2847 }
2848 run_test 27J "basic ops on file with foreign LOV"
2849
2850 test_27K() {
2851         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2852                 skip "Need MDS version newer than 2.12.49"
2853
2854         test_mkdir $DIR/$tdir
2855         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2856         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2857
2858         # create foreign dir (raw way)
2859         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2860                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2861
2862         ! $LFS setdirstripe --foreign --flags foo \
2863                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2864                         error "creating $tdir with '--flags foo' should fail"
2865
2866         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2867                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2868                         error "creating $tdir w/ 0xffffffff flags should fail"
2869
2870         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2871                 error "create_foreign_dir FAILED"
2872
2873         # verify foreign dir (raw way)
2874         parse_foreign_dir -d $DIR/$tdir/$tdir |
2875                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2876                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2877         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2878                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2879         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2880                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2881         parse_foreign_dir -d $DIR/$tdir/$tdir |
2882                 grep "lmv_foreign_flags: 55813$" ||
2883                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2884         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2885                 grep "lmv_foreign_value: 0x" |
2886                 sed 's/lmv_foreign_value: 0x//')
2887         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2888                 sed 's/ //g')
2889         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2890
2891         # create foreign dir (lfs + API)
2892         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2893                 $DIR/$tdir/${tdir}2 ||
2894                 error "$DIR/$tdir/${tdir}2: create failed"
2895
2896         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2897                 grep "lfm_magic:.*0x0CD50CD0" ||
2898                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2899         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2900         # - sizeof(lfm_type) - sizeof(lfm_flags)
2901         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2902                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2903         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2904                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2905         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2906                 grep "lfm_flags:.*0x0000DA05" ||
2907                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2908         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2909                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2910                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2911
2912         # file create in dir should fail
2913         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2914         touch $DIR/$tdir/${tdir}2/$tfile &&
2915                 error "$DIR/${tdir}2: file create should fail"
2916
2917         # chmod should work
2918         chmod 777 $DIR/$tdir/$tdir ||
2919                 error "$DIR/$tdir: chmod failed"
2920         chmod 777 $DIR/$tdir/${tdir}2 ||
2921                 error "$DIR/${tdir}2: chmod failed"
2922
2923         # chown should work
2924         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2925                 error "$DIR/$tdir: chown failed"
2926         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2927                 error "$DIR/${tdir}2: chown failed"
2928
2929         # rename should work
2930         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2931                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2932         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2933                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2934
2935         #remove foreign dir
2936         rmdir $DIR/$tdir/${tdir}.new ||
2937                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2938         rmdir $DIR/$tdir/${tdir}2.new ||
2939                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2940 }
2941 run_test 27K "basic ops on dir with foreign LMV"
2942
2943 test_27L() {
2944         remote_mds_nodsh && skip "remote MDS with nodsh"
2945
2946         local POOL=${POOL:-$TESTNAME}
2947
2948         pool_add $POOL || error "pool_add failed"
2949
2950         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2951                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2952                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2953 }
2954 run_test 27L "lfs pool_list gives correct pool name"
2955
2956 test_27M() {
2957         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2958                 skip "Need MDS version >= than 2.12.57"
2959         remote_mds_nodsh && skip "remote MDS with nodsh"
2960         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2961
2962         test_mkdir $DIR/$tdir
2963
2964         # Set default striping on directory
2965         local setcount=4
2966         local stripe_opt
2967
2968         # if we run against a 2.12 server which lacks overstring support
2969         # then the connect_flag will not report overstriping, even if client
2970         # is 2.14+
2971         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2972                 stripe_opt="-C $setcount"
2973         elif (( $OSTCOUNT >= $setcount )); then
2974                 stripe_opt="-c $setcount"
2975         else
2976                 skip "server does not support overstriping"
2977         fi
2978         $LFS setstripe $stripe_opt $DIR/$tdir
2979
2980         echo 1 > $DIR/$tdir/${tfile}.1
2981         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2982         [ $count -eq $setcount ] ||
2983                 error "(1) stripe count $count, should be $setcount"
2984
2985         # Capture existing append_stripe_count setting for restore
2986         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2987         local mdts=$(comma_list $(mdts_nodes))
2988         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2989
2990         local appendcount=$orig_count
2991         echo 1 >> $DIR/$tdir/${tfile}.2_append
2992         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2993         [ $count -eq $appendcount ] ||
2994                 error "(2)stripe count $count, should be $appendcount for append"
2995
2996         # Disable O_APPEND striping, verify it works
2997         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2998
2999         # Should now get the default striping, which is 4
3000         setcount=4
3001         echo 1 >> $DIR/$tdir/${tfile}.3_append
3002         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3003         [ $count -eq $setcount ] ||
3004                 error "(3) stripe count $count, should be $setcount"
3005
3006         # Try changing the stripe count for append files
3007         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3008
3009         # Append striping is now 2 (directory default is still 4)
3010         appendcount=2
3011         echo 1 >> $DIR/$tdir/${tfile}.4_append
3012         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3013         [ $count -eq $appendcount ] ||
3014                 error "(4) stripe count $count, should be $appendcount for append"
3015
3016         # Test append stripe count of -1
3017         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3018         appendcount=$OSTCOUNT
3019         echo 1 >> $DIR/$tdir/${tfile}.5
3020         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3021         [ $count -eq $appendcount ] ||
3022                 error "(5) stripe count $count, should be $appendcount for append"
3023
3024         # Set append striping back to default of 1
3025         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3026
3027         # Try a new default striping, PFL + DOM
3028         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3029
3030         # Create normal DOM file, DOM returns stripe count == 0
3031         setcount=0
3032         touch $DIR/$tdir/${tfile}.6
3033         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3034         [ $count -eq $setcount ] ||
3035                 error "(6) stripe count $count, should be $setcount"
3036
3037         # Show
3038         appendcount=1
3039         echo 1 >> $DIR/$tdir/${tfile}.7_append
3040         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3041         [ $count -eq $appendcount ] ||
3042                 error "(7) stripe count $count, should be $appendcount for append"
3043
3044         # Clean up DOM layout
3045         $LFS setstripe -d $DIR/$tdir
3046
3047         save_layout_restore_at_exit $MOUNT
3048         # Now test that append striping works when layout is from root
3049         $LFS setstripe -c 2 $MOUNT
3050         # Make a special directory for this
3051         mkdir $DIR/${tdir}/${tdir}.2
3052
3053         # Verify for normal file
3054         setcount=2
3055         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3056         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3057         [ $count -eq $setcount ] ||
3058                 error "(8) stripe count $count, should be $setcount"
3059
3060         appendcount=1
3061         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3062         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3063         [ $count -eq $appendcount ] ||
3064                 error "(9) stripe count $count, should be $appendcount for append"
3065
3066         # Now test O_APPEND striping with pools
3067         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3068         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3069
3070         # Create the pool
3071         pool_add $TESTNAME || error "pool creation failed"
3072         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3073
3074         echo 1 >> $DIR/$tdir/${tfile}.10_append
3075
3076         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3077         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3078
3079         # Check that count is still correct
3080         appendcount=1
3081         echo 1 >> $DIR/$tdir/${tfile}.11_append
3082         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3083         [ $count -eq $appendcount ] ||
3084                 error "(11) stripe count $count, should be $appendcount for append"
3085
3086         # Disable O_APPEND stripe count, verify pool works separately
3087         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3088
3089         echo 1 >> $DIR/$tdir/${tfile}.12_append
3090
3091         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3092         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3093
3094         # Remove pool setting, verify it's not applied
3095         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3096
3097         echo 1 >> $DIR/$tdir/${tfile}.13_append
3098
3099         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3100         [ "$pool" = "" ] || error "(13) pool found: $pool"
3101 }
3102 run_test 27M "test O_APPEND striping"
3103
3104 test_27N() {
3105         combined_mgs_mds && skip "needs separate MGS/MDT"
3106
3107         pool_add $TESTNAME || error "pool_add failed"
3108         do_facet mgs "$LCTL pool_list $FSNAME" |
3109                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3110                 error "lctl pool_list on MGS failed"
3111 }
3112 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3113
3114 clean_foreign_symlink() {
3115         trap 0
3116         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3117         for i in $DIR/$tdir/* ; do
3118                 $LFS unlink_foreign $i || true
3119         done
3120 }
3121
3122 test_27O() {
3123         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3124                 skip "Need MDS version newer than 2.12.51"
3125
3126         test_mkdir $DIR/$tdir
3127         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3128         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3129
3130         trap clean_foreign_symlink EXIT
3131
3132         # enable foreign_symlink behaviour
3133         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3134
3135         # foreign symlink LOV format is a partial path by default
3136
3137         # create foreign file (lfs + API)
3138         $LFS setstripe --foreign=symlink --flags 0xda05 \
3139                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3140                 error "$DIR/$tdir/${tfile}: create failed"
3141
3142         $LFS getstripe -v $DIR/$tdir/${tfile} |
3143                 grep "lfm_magic:.*0x0BD70BD0" ||
3144                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3145         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3146                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3147         $LFS getstripe -v $DIR/$tdir/${tfile} |
3148                 grep "lfm_flags:.*0x0000DA05" ||
3149                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3150         $LFS getstripe $DIR/$tdir/${tfile} |
3151                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3152                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3153
3154         # modify striping should fail
3155         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3156                 error "$DIR/$tdir/$tfile: setstripe should fail"
3157
3158         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3159         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3160         cat /etc/passwd > $DIR/$tdir/$tfile &&
3161                 error "$DIR/$tdir/$tfile: write should fail"
3162
3163         # rename should succeed
3164         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3165                 error "$DIR/$tdir/$tfile: rename has failed"
3166
3167         #remove foreign_symlink file should fail
3168         rm $DIR/$tdir/${tfile}.new &&
3169                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3170
3171         #test fake symlink
3172         mkdir /tmp/${uuid1} ||
3173                 error "/tmp/${uuid1}: mkdir has failed"
3174         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3175                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3176         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3177         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3178                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3179         #read should succeed now
3180         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3181                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3182         #write should succeed now
3183         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3184                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3185         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3186                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3187         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3188                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3189
3190         #check that getstripe still works
3191         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3192                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3193
3194         # chmod should still succeed
3195         chmod 644 $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3197
3198         # chown should still succeed
3199         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3200                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3201
3202         # rename should still succeed
3203         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3204                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3205
3206         #remove foreign_symlink file should still fail
3207         rm $DIR/$tdir/${tfile} &&
3208                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3209
3210         #use special ioctl() to unlink foreign_symlink file
3211         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3212                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3213
3214 }
3215 run_test 27O "basic ops on foreign file of symlink type"
3216
3217 test_27P() {
3218         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3219                 skip "Need MDS version newer than 2.12.49"
3220
3221         test_mkdir $DIR/$tdir
3222         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3223         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3224
3225         trap clean_foreign_symlink EXIT
3226
3227         # enable foreign_symlink behaviour
3228         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3229
3230         # foreign symlink LMV format is a partial path by default
3231
3232         # create foreign dir (lfs + API)
3233         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3234                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3235                 error "$DIR/$tdir/${tdir}: create failed"
3236
3237         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3238                 grep "lfm_magic:.*0x0CD50CD0" ||
3239                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3240         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3241                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3242         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3243                 grep "lfm_flags:.*0x0000DA05" ||
3244                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3245         $LFS getdirstripe $DIR/$tdir/${tdir} |
3246                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3247                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3248
3249         # file create in dir should fail
3250         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3251         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3252
3253         # rename should succeed
3254         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3255                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3256
3257         #remove foreign_symlink dir should fail
3258         rmdir $DIR/$tdir/${tdir}.new &&
3259                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3260
3261         #test fake symlink
3262         mkdir -p /tmp/${uuid1}/${uuid2} ||
3263                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3264         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3265                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3266         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3267         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3268                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3269         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3270                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3271
3272         #check that getstripe fails now that foreign_symlink enabled
3273         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3274                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3275
3276         # file create in dir should work now
3277         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3278                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3279         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3280                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3281         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3282                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3283
3284         # chmod should still succeed
3285         chmod 755 $DIR/$tdir/${tdir}.new ||
3286                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3287
3288         # chown should still succeed
3289         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3290                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3291
3292         # rename should still succeed
3293         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3294                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3295
3296         #remove foreign_symlink dir should still fail
3297         rmdir $DIR/$tdir/${tdir} &&
3298                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3299
3300         #use special ioctl() to unlink foreign_symlink file
3301         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3302                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3303
3304         #created file should still exist
3305         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3306                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3307         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3308                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3309 }
3310 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3311
3312 test_27Q() {
3313         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3314         stack_trap "rm -f $TMP/$tfile*"
3315
3316         test_mkdir $DIR/$tdir-1
3317         test_mkdir $DIR/$tdir-2
3318
3319         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3320         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3321
3322         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3323         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3324
3325         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3326         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3327
3328         # Create some bad symlinks and ensure that we don't loop
3329         # forever or something. These should return ELOOP (40) and
3330         # ENOENT (2) but I don't want to test for that because there's
3331         # always some weirdo architecture that needs to ruin
3332         # everything by defining these error numbers differently.
3333
3334         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3335         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3336
3337         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3338         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3339
3340         return 0
3341 }
3342 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3343
3344 test_27R() {
3345         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3346                 skip "need MDS 2.14.55 or later"
3347         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3348
3349         local testdir="$DIR/$tdir"
3350         test_mkdir -p $testdir
3351         stack_trap "rm -rf $testdir"
3352         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3353
3354         local f1="$testdir/f1"
3355         touch $f1 || error "failed to touch $f1"
3356         local count=$($LFS getstripe -c $f1)
3357         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3358
3359         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3360         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3361
3362         local maxcount=$(($OSTCOUNT - 1))
3363         local mdts=$(comma_list $(mdts_nodes))
3364         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3365         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3366
3367         local f2="$testdir/f2"
3368         touch $f2 || error "failed to touch $f2"
3369         local count=$($LFS getstripe -c $f2)
3370         (( $count == $maxcount )) || error "wrong stripe count"
3371 }
3372 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3373
3374 test_27S() {
3375         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
3376                 skip "Need MDS version at least 2.14.54"
3377         [[ "$(facet_host mds1)" != "$(facet_host ost1)" ]] ||
3378                 skip "needs different host for mdt1 ost1"
3379
3380         local count=$(precreated_ost_obj_count 0 0)
3381
3382         echo "precreate count $count"
3383         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
3384         $LFS setstripe -i 0 -c 1 $DIR/$tdir || error "setstripe $tdir failed"
3385         #define OBD_FAIL_OSP_GET_LAST_FID       0x2109
3386         do_facet mds1 $LCTL set_param fail_loc=0x2109
3387         #define OBD_FAIL_OST_GET_LAST_FID       0x252
3388         do_facet ost1 $LCTL set_param fail_loc=0x252
3389         createmany -o $DIR/$tdir/f $count &
3390         pid=$!
3391         echo "precreate count $(precreated_ost_obj_count 0 0)"
3392         do_facet mds1 $LCTL set_param fail_loc=0
3393         do_facet ost1 $LCTL set_param fail_loc=0
3394         wait $pid || error "createmany failed"
3395         echo "precreate count $(precreated_ost_obj_count 0 0)"
3396 }
3397 run_test 27S "don't deactivate OSP on network issue"
3398
3399 test_27T() {
3400         [ $(facet_host client) == $(facet_host ost1) ] &&
3401                 skip "need ost1 and client on different nodes"
3402
3403 #define OBD_FAIL_OSC_NO_GRANT            0x411
3404         $LCTL set_param fail_loc=0x20000411 fail_val=1
3405 #define OBD_FAIL_OST_ENOSPC              0x215
3406         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3407         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3408         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3409                 error "multiop failed"
3410 }
3411 run_test 27T "no eio on close on partial write due to enosp"
3412
3413 # createtest also checks that device nodes are created and
3414 # then visible correctly (#2091)
3415 test_28() { # bug 2091
3416         test_mkdir $DIR/d28
3417         $CREATETEST $DIR/d28/ct || error "createtest failed"
3418 }
3419 run_test 28 "create/mknod/mkdir with bad file types ============"
3420
3421 test_29() {
3422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3423
3424         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3425                 disable_opencache
3426                 stack_trap "restore_opencache"
3427         }
3428
3429         sync; sleep 1; sync # flush out any dirty pages from previous tests
3430         cancel_lru_locks
3431         test_mkdir $DIR/d29
3432         touch $DIR/d29/foo
3433         log 'first d29'
3434         ls -l $DIR/d29
3435
3436         declare -i LOCKCOUNTORIG=0
3437         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3438                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3439         done
3440         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3441
3442         declare -i LOCKUNUSEDCOUNTORIG=0
3443         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3444                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3445         done
3446
3447         log 'second d29'
3448         ls -l $DIR/d29
3449         log 'done'
3450
3451         declare -i LOCKCOUNTCURRENT=0
3452         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3453                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3454         done
3455
3456         declare -i LOCKUNUSEDCOUNTCURRENT=0
3457         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3458                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3459         done
3460
3461         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3462                 $LCTL set_param -n ldlm.dump_namespaces ""
3463                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3464                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3465                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3466                 return 2
3467         fi
3468         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3469                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3470                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3471                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3472                 return 3
3473         fi
3474 }
3475 run_test 29 "IT_GETATTR regression  ============================"
3476
3477 test_30a() { # was test_30
3478         cp $(which ls) $DIR || cp /bin/ls $DIR
3479         $DIR/ls / || error "Can't execute binary from lustre"
3480         rm $DIR/ls
3481 }
3482 run_test 30a "execute binary from Lustre (execve) =============="
3483
3484 test_30b() {
3485         cp `which ls` $DIR || cp /bin/ls $DIR
3486         chmod go+rx $DIR/ls
3487         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3488         rm $DIR/ls
3489 }
3490 run_test 30b "execute binary from Lustre as non-root ==========="
3491
3492 test_30c() { # b=22376
3493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3494
3495         cp $(which ls) $DIR || cp /bin/ls $DIR
3496         chmod a-rw $DIR/ls
3497         cancel_lru_locks mdc
3498         cancel_lru_locks osc
3499         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3500         rm -f $DIR/ls
3501 }
3502 run_test 30c "execute binary from Lustre without read perms ===="
3503
3504 test_30d() {
3505         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3506
3507         for i in {1..10}; do
3508                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3509                 local PID=$!
3510                 sleep 1
3511                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3512                 wait $PID || error "executing dd from Lustre failed"
3513                 rm -f $DIR/$tfile
3514         done
3515
3516         rm -f $DIR/dd
3517 }
3518 run_test 30d "execute binary from Lustre while clear locks"
3519
3520 test_31a() {
3521         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3522         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3523 }
3524 run_test 31a "open-unlink file =================================="
3525
3526 test_31b() {
3527         touch $DIR/f31 || error "touch $DIR/f31 failed"
3528         ln $DIR/f31 $DIR/f31b || error "ln failed"
3529         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3530         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3531 }
3532 run_test 31b "unlink file with multiple links while open ======="
3533
3534 test_31c() {
3535         touch $DIR/f31 || error "touch $DIR/f31 failed"
3536         ln $DIR/f31 $DIR/f31c || error "ln failed"
3537         multiop_bg_pause $DIR/f31 O_uc ||
3538                 error "multiop_bg_pause for $DIR/f31 failed"
3539         MULTIPID=$!
3540         $MULTIOP $DIR/f31c Ouc
3541         kill -USR1 $MULTIPID
3542         wait $MULTIPID
3543 }
3544 run_test 31c "open-unlink file with multiple links ============="
3545
3546 test_31d() {
3547         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3548         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3549 }
3550 run_test 31d "remove of open directory ========================="
3551
3552 test_31e() { # bug 2904
3553         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3554 }
3555 run_test 31e "remove of open non-empty directory ==============="
3556
3557 test_31f() { # bug 4554
3558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3559
3560         set -vx
3561         test_mkdir $DIR/d31f
3562         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3563         cp /etc/hosts $DIR/d31f
3564         ls -l $DIR/d31f
3565         $LFS getstripe $DIR/d31f/hosts
3566         multiop_bg_pause $DIR/d31f D_c || return 1
3567         MULTIPID=$!
3568
3569         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3570         test_mkdir $DIR/d31f
3571         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3572         cp /etc/hosts $DIR/d31f
3573         ls -l $DIR/d31f
3574         $LFS getstripe $DIR/d31f/hosts
3575         multiop_bg_pause $DIR/d31f D_c || return 1
3576         MULTIPID2=$!
3577
3578         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3579         wait $MULTIPID || error "first opendir $MULTIPID failed"
3580
3581         sleep 6
3582
3583         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3584         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3585         set +vx
3586 }
3587 run_test 31f "remove of open directory with open-unlink file ==="
3588
3589 test_31g() {
3590         echo "-- cross directory link --"
3591         test_mkdir -c1 $DIR/${tdir}ga
3592         test_mkdir -c1 $DIR/${tdir}gb
3593         touch $DIR/${tdir}ga/f
3594         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3595         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3596         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3597         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3598         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3599 }
3600 run_test 31g "cross directory link==============="
3601
3602 test_31h() {
3603         echo "-- cross directory link --"
3604         test_mkdir -c1 $DIR/${tdir}
3605         test_mkdir -c1 $DIR/${tdir}/dir
3606         touch $DIR/${tdir}/f
3607         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3608         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3609         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3610         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3611         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3612 }
3613 run_test 31h "cross directory link under child==============="
3614
3615 test_31i() {
3616         echo "-- cross directory link --"
3617         test_mkdir -c1 $DIR/$tdir
3618         test_mkdir -c1 $DIR/$tdir/dir
3619         touch $DIR/$tdir/dir/f
3620         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3621         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3622         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3623         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3624         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3625 }
3626 run_test 31i "cross directory link under parent==============="
3627
3628 test_31j() {
3629         test_mkdir -c1 -p $DIR/$tdir
3630         test_mkdir -c1 -p $DIR/$tdir/dir1
3631         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3632         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3633         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3634         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3635         return 0
3636 }
3637 run_test 31j "link for directory==============="
3638
3639 test_31k() {
3640         test_mkdir -c1 -p $DIR/$tdir
3641         touch $DIR/$tdir/s
3642         touch $DIR/$tdir/exist
3643         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3644         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3645         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3646         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3647         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3648         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3649         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3650         return 0
3651 }
3652 run_test 31k "link to file: the same, non-existing, dir==============="
3653
3654 test_31m() {
3655         mkdir $DIR/d31m
3656         touch $DIR/d31m/s
3657         mkdir $DIR/d31m2
3658         touch $DIR/d31m2/exist
3659         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3660         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3661         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3662         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3663         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3664         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3665         return 0
3666 }
3667 run_test 31m "link to file: the same, non-existing, dir==============="
3668
3669 test_31n() {
3670         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3671         nlink=$(stat --format=%h $DIR/$tfile)
3672         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3673         local fd=$(free_fd)
3674         local cmd="exec $fd<$DIR/$tfile"
3675         eval $cmd
3676         cmd="exec $fd<&-"
3677         trap "eval $cmd" EXIT
3678         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3679         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3680         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3681         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3682         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3683         eval $cmd
3684 }
3685 run_test 31n "check link count of unlinked file"
3686
3687 link_one() {
3688         local tempfile=$(mktemp $1_XXXXXX)
3689         mlink $tempfile $1 2> /dev/null &&
3690                 echo "$BASHPID: link $tempfile to $1 succeeded"
3691         munlink $tempfile
3692 }
3693
3694 test_31o() { # LU-2901
3695         test_mkdir $DIR/$tdir
3696         for LOOP in $(seq 100); do
3697                 rm -f $DIR/$tdir/$tfile*
3698                 for THREAD in $(seq 8); do
3699                         link_one $DIR/$tdir/$tfile.$LOOP &
3700                 done
3701                 wait
3702                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3703                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3704                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3705                         break || true
3706         done
3707 }
3708 run_test 31o "duplicate hard links with same filename"
3709
3710 test_31p() {
3711         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3712
3713         test_mkdir $DIR/$tdir
3714         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3715         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3716
3717         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3718                 error "open unlink test1 failed"
3719         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3720                 error "open unlink test2 failed"
3721
3722         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3723                 error "test1 still exists"
3724         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3725                 error "test2 still exists"
3726 }
3727 run_test 31p "remove of open striped directory"
3728
3729 test_31q() {
3730         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3731
3732         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3733         index=$($LFS getdirstripe -i $DIR/$tdir)
3734         [ $index -eq 3 ] || error "first stripe index $index != 3"
3735         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3736         [ $index -eq 1 ] || error "second stripe index $index != 1"
3737
3738         # when "-c <stripe_count>" is set, the number of MDTs specified after
3739         # "-i" should equal to the stripe count
3740         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3741 }
3742 run_test 31q "create striped directory on specific MDTs"
3743
3744 #LU-14949
3745 test_31r() {
3746         touch $DIR/$tfile.target
3747         touch $DIR/$tfile.source
3748
3749         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3750         $LCTL set_param fail_loc=0x1419 fail_val=3
3751         cat $DIR/$tfile.target &
3752         CATPID=$!
3753
3754         # Guarantee open is waiting before we get here
3755         sleep 1
3756         mv $DIR/$tfile.source $DIR/$tfile.target
3757
3758         wait $CATPID
3759         RC=$?
3760         if [[ $RC -ne 0 ]]; then
3761                 error "open with cat failed, rc=$RC"
3762         fi
3763 }
3764 run_test 31r "open-rename(replace) race"
3765
3766 cleanup_test32_mount() {
3767         local rc=0
3768         trap 0
3769         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3770         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3771         losetup -d $loopdev || true
3772         rm -rf $DIR/$tdir
3773         return $rc
3774 }
3775
3776 test_32a() {
3777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3778
3779         echo "== more mountpoints and symlinks ================="
3780         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3781         trap cleanup_test32_mount EXIT
3782         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3783         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3784                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3785         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3786                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3787         cleanup_test32_mount
3788 }
3789 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3790
3791 test_32b() {
3792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3793
3794         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3795         trap cleanup_test32_mount EXIT
3796         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3797         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3798                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3799         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3800                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3801         cleanup_test32_mount
3802 }
3803 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3804
3805 test_32c() {
3806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3807
3808         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3809         trap cleanup_test32_mount EXIT
3810         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3811         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3812                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3813         test_mkdir -p $DIR/$tdir/d2/test_dir
3814         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3815                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3816         cleanup_test32_mount
3817 }
3818 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3819
3820 test_32d() {
3821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3822
3823         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3824         trap cleanup_test32_mount EXIT
3825         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3826         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3827                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3828         test_mkdir -p $DIR/$tdir/d2/test_dir
3829         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3830                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3831         cleanup_test32_mount
3832 }
3833 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3834
3835 test_32e() {
3836         rm -fr $DIR/$tdir
3837         test_mkdir -p $DIR/$tdir/tmp
3838         local tmp_dir=$DIR/$tdir/tmp
3839         ln -s $DIR/$tdir $tmp_dir/symlink11
3840         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3841         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3842         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3843 }
3844 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3845
3846 test_32f() {
3847         rm -fr $DIR/$tdir
3848         test_mkdir -p $DIR/$tdir/tmp
3849         local tmp_dir=$DIR/$tdir/tmp
3850         ln -s $DIR/$tdir $tmp_dir/symlink11
3851         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3852         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3853         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3854 }
3855 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3856
3857 test_32g() {
3858         local tmp_dir=$DIR/$tdir/tmp
3859         test_mkdir -p $tmp_dir
3860         test_mkdir $DIR/${tdir}2
3861         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3862         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3863         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3864         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3865         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3866         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3867 }
3868 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3869
3870 test_32h() {
3871         rm -fr $DIR/$tdir $DIR/${tdir}2
3872         tmp_dir=$DIR/$tdir/tmp
3873         test_mkdir -p $tmp_dir
3874         test_mkdir $DIR/${tdir}2
3875         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3876         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3877         ls $tmp_dir/symlink12 || error "listing symlink12"
3878         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3879 }
3880 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3881
3882 test_32i() {
3883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3884
3885         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3886         trap cleanup_test32_mount EXIT
3887         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3888         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3889                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3890         touch $DIR/$tdir/test_file
3891         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3892                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3893         cleanup_test32_mount
3894 }
3895 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3896
3897 test_32j() {
3898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3899
3900         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3901         trap cleanup_test32_mount EXIT
3902         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3903         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3904                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3905         touch $DIR/$tdir/test_file
3906         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3907                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3908         cleanup_test32_mount
3909 }
3910 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3911
3912 test_32k() {
3913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3914
3915         rm -fr $DIR/$tdir
3916         trap cleanup_test32_mount EXIT
3917         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3918         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3919                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3920         test_mkdir -p $DIR/$tdir/d2
3921         touch $DIR/$tdir/d2/test_file || error "touch failed"
3922         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3923                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3924         cleanup_test32_mount
3925 }
3926 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3927
3928 test_32l() {
3929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3930
3931         rm -fr $DIR/$tdir
3932         trap cleanup_test32_mount EXIT
3933         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3934         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3935                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3936         test_mkdir -p $DIR/$tdir/d2
3937         touch $DIR/$tdir/d2/test_file || error "touch failed"
3938         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3939                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3940         cleanup_test32_mount
3941 }
3942 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3943
3944 test_32m() {
3945         rm -fr $DIR/d32m
3946         test_mkdir -p $DIR/d32m/tmp
3947         TMP_DIR=$DIR/d32m/tmp
3948         ln -s $DIR $TMP_DIR/symlink11
3949         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3950         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3951                 error "symlink11 not a link"
3952         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3953                 error "symlink01 not a link"
3954 }
3955 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3956
3957 test_32n() {
3958         rm -fr $DIR/d32n
3959         test_mkdir -p $DIR/d32n/tmp
3960         TMP_DIR=$DIR/d32n/tmp
3961         ln -s $DIR $TMP_DIR/symlink11
3962         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3963         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3964         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3965 }
3966 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3967
3968 test_32o() {
3969         touch $DIR/$tfile
3970         test_mkdir -p $DIR/d32o/tmp
3971         TMP_DIR=$DIR/d32o/tmp
3972         ln -s $DIR/$tfile $TMP_DIR/symlink12
3973         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3974         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3975                 error "symlink12 not a link"
3976         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3977         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3978                 error "$DIR/d32o/tmp/symlink12 not file type"
3979         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3980                 error "$DIR/d32o/symlink02 not file type"
3981 }
3982 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3983
3984 test_32p() {
3985         log 32p_1
3986         rm -fr $DIR/d32p
3987         log 32p_2
3988         rm -f $DIR/$tfile
3989         log 32p_3
3990         touch $DIR/$tfile
3991         log 32p_4
3992         test_mkdir -p $DIR/d32p/tmp
3993         log 32p_5
3994         TMP_DIR=$DIR/d32p/tmp
3995         log 32p_6
3996         ln -s $DIR/$tfile $TMP_DIR/symlink12
3997         log 32p_7
3998         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3999         log 32p_8
4000         cat $DIR/d32p/tmp/symlink12 ||
4001                 error "Can't open $DIR/d32p/tmp/symlink12"
4002         log 32p_9
4003         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4004         log 32p_10
4005 }
4006 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4007
4008 test_32q() {
4009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4010
4011         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4012         trap cleanup_test32_mount EXIT
4013         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4014         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4015         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4016                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4017         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4018         cleanup_test32_mount
4019 }
4020 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4021
4022 test_32r() {
4023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4024
4025         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4026         trap cleanup_test32_mount EXIT
4027         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4028         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4029         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4030                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4031         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4032         cleanup_test32_mount
4033 }
4034 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4035
4036 test_33aa() {
4037         rm -f $DIR/$tfile
4038         touch $DIR/$tfile
4039         chmod 444 $DIR/$tfile
4040         chown $RUNAS_ID $DIR/$tfile
4041         log 33_1
4042         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4043         log 33_2
4044 }
4045 run_test 33aa "write file with mode 444 (should return error)"
4046
4047 test_33a() {
4048         rm -fr $DIR/$tdir
4049         test_mkdir $DIR/$tdir
4050         chown $RUNAS_ID $DIR/$tdir
4051         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4052                 error "$RUNAS create $tdir/$tfile failed"
4053         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4054                 error "open RDWR" || true
4055 }
4056 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4057
4058 test_33b() {
4059         rm -fr $DIR/$tdir
4060         test_mkdir $DIR/$tdir
4061         chown $RUNAS_ID $DIR/$tdir
4062         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4063 }
4064 run_test 33b "test open file with malformed flags (No panic)"
4065
4066 test_33c() {
4067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4068         remote_ost_nodsh && skip "remote OST with nodsh"
4069
4070         local ostnum
4071         local ostname
4072         local write_bytes
4073         local all_zeros
4074
4075         all_zeros=true
4076         test_mkdir $DIR/$tdir
4077         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4078
4079         sync
4080         for ostnum in $(seq $OSTCOUNT); do
4081                 # test-framework's OST numbering is one-based, while Lustre's
4082                 # is zero-based
4083                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4084                 # check if at least some write_bytes stats are counted
4085                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4086                               obdfilter.$ostname.stats |
4087                               awk '/^write_bytes/ {print $7}' )
4088                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4089                 if (( ${write_bytes:-0} > 0 )); then
4090                         all_zeros=false
4091                         break
4092                 fi
4093         done
4094
4095         $all_zeros || return 0
4096
4097         # Write four bytes
4098         echo foo > $DIR/$tdir/bar
4099         # Really write them
4100         sync
4101
4102         # Total up write_bytes after writing.  We'd better find non-zeros.
4103         for ostnum in $(seq $OSTCOUNT); do
4104                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4105                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4106                               obdfilter/$ostname/stats |
4107                               awk '/^write_bytes/ {print $7}' )
4108                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4109                 if (( ${write_bytes:-0} > 0 )); then
4110                         all_zeros=false
4111                         break
4112                 fi
4113         done
4114
4115         if $all_zeros; then
4116                 for ostnum in $(seq $OSTCOUNT); do
4117                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4118                         echo "Check write_bytes is in obdfilter.*.stats:"
4119                         do_facet ost$ostnum lctl get_param -n \
4120                                 obdfilter.$ostname.stats
4121                 done
4122                 error "OST not keeping write_bytes stats (b=22312)"
4123         fi
4124 }
4125 run_test 33c "test write_bytes stats"
4126
4127 test_33d() {
4128         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4130
4131         local MDTIDX=1
4132         local remote_dir=$DIR/$tdir/remote_dir
4133
4134         test_mkdir $DIR/$tdir
4135         $LFS mkdir -i $MDTIDX $remote_dir ||
4136                 error "create remote directory failed"
4137
4138         touch $remote_dir/$tfile
4139         chmod 444 $remote_dir/$tfile
4140         chown $RUNAS_ID $remote_dir/$tfile
4141
4142         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4143
4144         chown $RUNAS_ID $remote_dir
4145         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4146                                         error "create" || true
4147         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4148                                     error "open RDWR" || true
4149         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4150 }
4151 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4152
4153 test_33e() {
4154         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4155
4156         mkdir $DIR/$tdir
4157
4158         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4159         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4160         mkdir $DIR/$tdir/local_dir
4161
4162         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4163         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4164         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4165
4166         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4167                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4168
4169         rmdir $DIR/$tdir/* || error "rmdir failed"
4170
4171         umask 777
4172         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4173         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4174         mkdir $DIR/$tdir/local_dir
4175
4176         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4177         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4178         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4179
4180         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4181                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4182
4183         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4184
4185         umask 000
4186         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4187         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4188         mkdir $DIR/$tdir/local_dir
4189
4190         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4191         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4192         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4193
4194         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4195                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4196 }
4197 run_test 33e "mkdir and striped directory should have same mode"
4198
4199 cleanup_33f() {
4200         trap 0
4201         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4202 }
4203
4204 test_33f() {
4205         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4206         remote_mds_nodsh && skip "remote MDS with nodsh"
4207
4208         mkdir $DIR/$tdir
4209         chmod go+rwx $DIR/$tdir
4210         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4211         trap cleanup_33f EXIT
4212
4213         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4214                 error "cannot create striped directory"
4215
4216         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4217                 error "cannot create files in striped directory"
4218
4219         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4220                 error "cannot remove files in striped directory"
4221
4222         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4223                 error "cannot remove striped directory"
4224
4225         cleanup_33f
4226 }
4227 run_test 33f "nonroot user can create, access, and remove a striped directory"
4228
4229 test_33g() {
4230         mkdir -p $DIR/$tdir/dir2
4231
4232         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4233         echo $err
4234         [[ $err =~ "exists" ]] || error "Not exists error"
4235 }
4236 run_test 33g "nonroot user create already existing root created file"
4237
4238 test_33h() {
4239         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4240         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4241                 skip "Need MDS version at least 2.13.50"
4242
4243         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4244                 error "mkdir $tdir failed"
4245         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4246
4247         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4248         local index2
4249
4250         for fname in $DIR/$tdir/$tfile.bak \
4251                      $DIR/$tdir/$tfile.SAV \
4252                      $DIR/$tdir/$tfile.orig \
4253                      $DIR/$tdir/$tfile~; do
4254                 touch $fname  || error "touch $fname failed"
4255                 index2=$($LFS getstripe -m $fname)
4256                 [ $index -eq $index2 ] ||
4257                         error "$fname MDT index mismatch $index != $index2"
4258         done
4259
4260         local failed=0
4261         for i in {1..250}; do
4262                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4263                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4264                         touch $fname  || error "touch $fname failed"
4265                         index2=$($LFS getstripe -m $fname)
4266                         if [[ $index != $index2 ]]; then
4267                                 failed=$((failed + 1))
4268                                 echo "$fname MDT index mismatch $index != $index2"
4269                         fi
4270                 done
4271         done
4272         echo "$failed MDT index mismatches"
4273         (( failed < 20 )) || error "MDT index mismatch $failed times"
4274
4275 }
4276 run_test 33h "temp file is located on the same MDT as target"
4277
4278 test_33i()
4279 {
4280         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4281
4282         local FNAME=$(str_repeat 'f' 250)
4283
4284         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4285         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4286
4287         local count
4288         local total
4289
4290         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4291
4292         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4293
4294         lctl --device %$MDC deactivate
4295         stack_trap "lctl --device %$MDC activate"
4296         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4297         total=$(\ls -l $DIR/$tdir | wc -l)
4298         # "ls -l" will list total in the first line
4299         total=$((total - 1))
4300         (( total + count == 1000 )) ||
4301                 error "ls list $total files, $count files on MDT1"
4302 }
4303 run_test 33i "striped directory can be accessed when one MDT is down"
4304
4305 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4306 test_34a() {
4307         rm -f $DIR/f34
4308         $MCREATE $DIR/f34 || error "mcreate failed"
4309         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4310                 error "getstripe failed"
4311         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4312         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4313                 error "getstripe failed"
4314         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4315                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4316 }
4317 run_test 34a "truncate file that has not been opened ==========="
4318
4319 test_34b() {
4320         [ ! -f $DIR/f34 ] && test_34a
4321         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4322                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4323         $OPENFILE -f O_RDONLY $DIR/f34
4324         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4325                 error "getstripe failed"
4326         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4327                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4328 }
4329 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4330
4331 test_34c() {
4332         [ ! -f $DIR/f34 ] && test_34a
4333         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4334                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4335         $OPENFILE -f O_RDWR $DIR/f34
4336         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4337                 error "$LFS getstripe failed"
4338         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4339                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4340 }
4341 run_test 34c "O_RDWR opening file-with-size works =============="
4342
4343 test_34d() {
4344         [ ! -f $DIR/f34 ] && test_34a
4345         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4346                 error "dd failed"
4347         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4348                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4349         rm $DIR/f34
4350 }
4351 run_test 34d "write to sparse file ============================="
4352
4353 test_34e() {
4354         rm -f $DIR/f34e
4355         $MCREATE $DIR/f34e || error "mcreate failed"
4356         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4357         $CHECKSTAT -s 1000 $DIR/f34e ||
4358                 error "Size of $DIR/f34e not equal to 1000 bytes"
4359         $OPENFILE -f O_RDWR $DIR/f34e
4360         $CHECKSTAT -s 1000 $DIR/f34e ||
4361                 error "Size of $DIR/f34e not equal to 1000 bytes"
4362 }
4363 run_test 34e "create objects, some with size and some without =="
4364
4365 test_34f() { # bug 6242, 6243
4366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4367
4368         SIZE34F=48000
4369         rm -f $DIR/f34f
4370         $MCREATE $DIR/f34f || error "mcreate failed"
4371         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4372         dd if=$DIR/f34f of=$TMP/f34f
4373         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4374         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4375         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4376         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4377         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4378 }
4379 run_test 34f "read from a file with no objects until EOF ======="
4380
4381 test_34g() {
4382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4383
4384         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4385                 error "dd failed"
4386         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4387         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4388                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4389         cancel_lru_locks osc
4390         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4391                 error "wrong size after lock cancel"
4392
4393         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4394         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4395                 error "expanding truncate failed"
4396         cancel_lru_locks osc
4397         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4398                 error "wrong expanded size after lock cancel"
4399 }
4400 run_test 34g "truncate long file ==============================="
4401
4402 test_34h() {
4403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4404
4405         local gid=10
4406         local sz=1000
4407
4408         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4409         sync # Flush the cache so that multiop below does not block on cache
4410              # flush when getting the group lock
4411         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4412         MULTIPID=$!
4413
4414         # Since just timed wait is not good enough, let's do a sync write
4415         # that way we are sure enough time for a roundtrip + processing
4416         # passed + 2 seconds of extra margin.
4417         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4418         rm $DIR/${tfile}-1
4419         sleep 2
4420
4421         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4422                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4423                 kill -9 $MULTIPID
4424         fi
4425         wait $MULTIPID
4426         local nsz=`stat -c %s $DIR/$tfile`
4427         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4428 }
4429 run_test 34h "ftruncate file under grouplock should not block"
4430
4431 test_35a() {
4432         cp /bin/sh $DIR/f35a
4433         chmod 444 $DIR/f35a
4434         chown $RUNAS_ID $DIR/f35a
4435         $RUNAS $DIR/f35a && error || true
4436         rm $DIR/f35a
4437 }
4438 run_test 35a "exec file with mode 444 (should return and not leak)"
4439
4440 test_36a() {
4441         rm -f $DIR/f36
4442         utime $DIR/f36 || error "utime failed for MDS"
4443 }
4444 run_test 36a "MDS utime check (mknod, utime)"
4445
4446 test_36b() {
4447         echo "" > $DIR/f36
4448         utime $DIR/f36 || error "utime failed for OST"
4449 }
4450 run_test 36b "OST utime check (open, utime)"
4451
4452 test_36c() {
4453         rm -f $DIR/d36/f36
4454         test_mkdir $DIR/d36
4455         chown $RUNAS_ID $DIR/d36
4456         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4457 }
4458 run_test 36c "non-root MDS utime check (mknod, utime)"
4459
4460 test_36d() {
4461         [ ! -d $DIR/d36 ] && test_36c
4462         echo "" > $DIR/d36/f36
4463         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4464 }
4465 run_test 36d "non-root OST utime check (open, utime)"
4466
4467 test_36e() {
4468         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4469
4470         test_mkdir $DIR/$tdir
4471         touch $DIR/$tdir/$tfile
4472         $RUNAS utime $DIR/$tdir/$tfile &&
4473                 error "utime worked, expected failure" || true
4474 }
4475 run_test 36e "utime on non-owned file (should return error)"
4476
4477 subr_36fh() {
4478         local fl="$1"
4479         local LANG_SAVE=$LANG
4480         local LC_LANG_SAVE=$LC_LANG
4481         export LANG=C LC_LANG=C # for date language
4482
4483         DATESTR="Dec 20  2000"
4484         test_mkdir $DIR/$tdir
4485         lctl set_param fail_loc=$fl
4486         date; date +%s
4487         cp /etc/hosts $DIR/$tdir/$tfile
4488         sync & # write RPC generated with "current" inode timestamp, but delayed
4489         sleep 1
4490         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4491         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4492         cancel_lru_locks $OSC
4493         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4494         date; date +%s
4495         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4496                 echo "BEFORE: $LS_BEFORE" && \
4497                 echo "AFTER : $LS_AFTER" && \
4498                 echo "WANT  : $DATESTR" && \
4499                 error "$DIR/$tdir/$tfile timestamps changed" || true
4500
4501         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4502 }
4503
4504 test_36f() {
4505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4506
4507         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4508         subr_36fh "0x80000214"
4509 }
4510 run_test 36f "utime on file racing with OST BRW write =========="
4511
4512 test_36g() {
4513         remote_ost_nodsh && skip "remote OST with nodsh"
4514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4515         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4516                 skip "Need MDS version at least 2.12.51"
4517
4518         local fmd_max_age
4519         local fmd
4520         local facet="ost1"
4521         local tgt="obdfilter"
4522
4523         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4524
4525         test_mkdir $DIR/$tdir
4526         fmd_max_age=$(do_facet $facet \
4527                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4528                 head -n 1")
4529
4530         echo "FMD max age: ${fmd_max_age}s"
4531         touch $DIR/$tdir/$tfile
4532         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4533                 gawk '{cnt=cnt+$1}  END{print cnt}')
4534         echo "FMD before: $fmd"
4535         [[ $fmd == 0 ]] &&
4536                 error "FMD wasn't create by touch"
4537         sleep $((fmd_max_age + 12))
4538         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4539                 gawk '{cnt=cnt+$1}  END{print cnt}')
4540         echo "FMD after: $fmd"
4541         [[ $fmd == 0 ]] ||
4542                 error "FMD wasn't expired by ping"
4543 }
4544 run_test 36g "FMD cache expiry ====================="
4545
4546 test_36h() {
4547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4548
4549         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4550         subr_36fh "0x80000227"
4551 }
4552 run_test 36h "utime on file racing with OST BRW write =========="
4553
4554 test_36i() {
4555         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4556
4557         test_mkdir $DIR/$tdir
4558         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4559
4560         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4561         local new_mtime=$((mtime + 200))
4562
4563         #change Modify time of striped dir
4564         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4565                         error "change mtime failed"
4566
4567         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4568
4569         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4570 }
4571 run_test 36i "change mtime on striped directory"
4572
4573 # test_37 - duplicate with tests 32q 32r
4574
4575 test_38() {
4576         local file=$DIR/$tfile
4577         touch $file
4578         openfile -f O_DIRECTORY $file
4579         local RC=$?
4580         local ENOTDIR=20
4581         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4582         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4583 }
4584 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4585
4586 test_39a() { # was test_39
4587         touch $DIR/$tfile
4588         touch $DIR/${tfile}2
4589 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4590 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4591 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4592         sleep 2
4593         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4594         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4595                 echo "mtime"
4596                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4597                 echo "atime"
4598                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4599                 echo "ctime"
4600                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4601                 error "O_TRUNC didn't change timestamps"
4602         fi
4603 }
4604 run_test 39a "mtime changed on create"
4605
4606 test_39b() {
4607         test_mkdir -c1 $DIR/$tdir
4608         cp -p /etc/passwd $DIR/$tdir/fopen
4609         cp -p /etc/passwd $DIR/$tdir/flink
4610         cp -p /etc/passwd $DIR/$tdir/funlink
4611         cp -p /etc/passwd $DIR/$tdir/frename
4612         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4613
4614         sleep 1
4615         echo "aaaaaa" >> $DIR/$tdir/fopen
4616         echo "aaaaaa" >> $DIR/$tdir/flink
4617         echo "aaaaaa" >> $DIR/$tdir/funlink
4618         echo "aaaaaa" >> $DIR/$tdir/frename
4619
4620         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4621         local link_new=`stat -c %Y $DIR/$tdir/flink`
4622         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4623         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4624
4625         cat $DIR/$tdir/fopen > /dev/null
4626         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4627         rm -f $DIR/$tdir/funlink2
4628         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4629
4630         for (( i=0; i < 2; i++ )) ; do
4631                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4632                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4633                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4634                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4635
4636                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4637                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4638                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4639                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4640
4641                 cancel_lru_locks $OSC
4642                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4643         done
4644 }
4645 run_test 39b "mtime change on open, link, unlink, rename  ======"
4646
4647 # this should be set to past
4648 TEST_39_MTIME=`date -d "1 year ago" +%s`
4649
4650 # bug 11063
4651 test_39c() {
4652         touch $DIR1/$tfile
4653         sleep 2
4654         local mtime0=`stat -c %Y $DIR1/$tfile`
4655
4656         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4657         local mtime1=`stat -c %Y $DIR1/$tfile`
4658         [ "$mtime1" = $TEST_39_MTIME ] || \
4659                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4660
4661         local d1=`date +%s`
4662         echo hello >> $DIR1/$tfile
4663         local d2=`date +%s`
4664         local mtime2=`stat -c %Y $DIR1/$tfile`
4665         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4666                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4667
4668         mv $DIR1/$tfile $DIR1/$tfile-1
4669
4670         for (( i=0; i < 2; i++ )) ; do
4671                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4672                 [ "$mtime2" = "$mtime3" ] || \
4673                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4674
4675                 cancel_lru_locks $OSC
4676                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4677         done
4678 }
4679 run_test 39c "mtime change on rename ==========================="
4680
4681 # bug 21114
4682 test_39d() {
4683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4684
4685         touch $DIR1/$tfile
4686         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4687
4688         for (( i=0; i < 2; i++ )) ; do
4689                 local mtime=`stat -c %Y $DIR1/$tfile`
4690                 [ $mtime = $TEST_39_MTIME ] || \
4691                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4692
4693                 cancel_lru_locks $OSC
4694                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4695         done
4696 }
4697 run_test 39d "create, utime, stat =============================="
4698
4699 # bug 21114
4700 test_39e() {
4701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4702
4703         touch $DIR1/$tfile
4704         local mtime1=`stat -c %Y $DIR1/$tfile`
4705
4706         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4707
4708         for (( i=0; i < 2; i++ )) ; do
4709                 local mtime2=`stat -c %Y $DIR1/$tfile`
4710                 [ $mtime2 = $TEST_39_MTIME ] || \
4711                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4712
4713                 cancel_lru_locks $OSC
4714                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4715         done
4716 }
4717 run_test 39e "create, stat, utime, stat ========================"
4718
4719 # bug 21114
4720 test_39f() {
4721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4722
4723         touch $DIR1/$tfile
4724         mtime1=`stat -c %Y $DIR1/$tfile`
4725
4726         sleep 2
4727         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4728
4729         for (( i=0; i < 2; i++ )) ; do
4730                 local mtime2=`stat -c %Y $DIR1/$tfile`
4731                 [ $mtime2 = $TEST_39_MTIME ] || \
4732                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4733
4734                 cancel_lru_locks $OSC
4735                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4736         done
4737 }
4738 run_test 39f "create, stat, sleep, utime, stat ================="
4739
4740 # bug 11063
4741 test_39g() {
4742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4743
4744         echo hello >> $DIR1/$tfile
4745         local mtime1=`stat -c %Y $DIR1/$tfile`
4746
4747         sleep 2
4748         chmod o+r $DIR1/$tfile
4749
4750         for (( i=0; i < 2; i++ )) ; do
4751                 local mtime2=`stat -c %Y $DIR1/$tfile`
4752                 [ "$mtime1" = "$mtime2" ] || \
4753                         error "lost mtime: $mtime2, should be $mtime1"
4754
4755                 cancel_lru_locks $OSC
4756                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4757         done
4758 }
4759 run_test 39g "write, chmod, stat ==============================="
4760
4761 # bug 11063
4762 test_39h() {
4763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4764
4765         touch $DIR1/$tfile
4766         sleep 1
4767
4768         local d1=`date`
4769         echo hello >> $DIR1/$tfile
4770         local mtime1=`stat -c %Y $DIR1/$tfile`
4771
4772         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4773         local d2=`date`
4774         if [ "$d1" != "$d2" ]; then
4775                 echo "write and touch not within one second"
4776         else
4777                 for (( i=0; i < 2; i++ )) ; do
4778                         local mtime2=`stat -c %Y $DIR1/$tfile`
4779                         [ "$mtime2" = $TEST_39_MTIME ] || \
4780                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4781
4782                         cancel_lru_locks $OSC
4783                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4784                 done
4785         fi
4786 }
4787 run_test 39h "write, utime within one second, stat ============="
4788
4789 test_39i() {
4790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4791
4792         touch $DIR1/$tfile
4793         sleep 1
4794
4795         echo hello >> $DIR1/$tfile
4796         local mtime1=`stat -c %Y $DIR1/$tfile`
4797
4798         mv $DIR1/$tfile $DIR1/$tfile-1
4799
4800         for (( i=0; i < 2; i++ )) ; do
4801                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4802
4803                 [ "$mtime1" = "$mtime2" ] || \
4804                         error "lost mtime: $mtime2, should be $mtime1"
4805
4806                 cancel_lru_locks $OSC
4807                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4808         done
4809 }
4810 run_test 39i "write, rename, stat =============================="
4811
4812 test_39j() {
4813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4814
4815         start_full_debug_logging
4816         touch $DIR1/$tfile
4817         sleep 1
4818
4819         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4820         lctl set_param fail_loc=0x80000412
4821         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4822                 error "multiop failed"
4823         local multipid=$!
4824         local mtime1=`stat -c %Y $DIR1/$tfile`
4825
4826         mv $DIR1/$tfile $DIR1/$tfile-1
4827
4828         kill -USR1 $multipid
4829         wait $multipid || error "multiop close failed"
4830
4831         for (( i=0; i < 2; i++ )) ; do
4832                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4833                 [ "$mtime1" = "$mtime2" ] ||
4834                         error "mtime is lost on close: $mtime2, " \
4835                               "should be $mtime1"
4836
4837                 cancel_lru_locks
4838                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4839         done
4840         lctl set_param fail_loc=0
4841         stop_full_debug_logging
4842 }
4843 run_test 39j "write, rename, close, stat ======================="
4844
4845 test_39k() {
4846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4847
4848         touch $DIR1/$tfile
4849         sleep 1
4850
4851         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4852         local multipid=$!
4853         local mtime1=`stat -c %Y $DIR1/$tfile`
4854
4855         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4856
4857         kill -USR1 $multipid
4858         wait $multipid || error "multiop close failed"
4859
4860         for (( i=0; i < 2; i++ )) ; do
4861                 local mtime2=`stat -c %Y $DIR1/$tfile`
4862
4863                 [ "$mtime2" = $TEST_39_MTIME ] || \
4864                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4865
4866                 cancel_lru_locks
4867                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4868         done
4869 }
4870 run_test 39k "write, utime, close, stat ========================"
4871
4872 # this should be set to future
4873 TEST_39_ATIME=`date -d "1 year" +%s`
4874
4875 test_39l() {
4876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4877         remote_mds_nodsh && skip "remote MDS with nodsh"
4878
4879         local atime_diff=$(do_facet $SINGLEMDS \
4880                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4881         rm -rf $DIR/$tdir
4882         mkdir_on_mdt0 $DIR/$tdir
4883
4884         # test setting directory atime to future
4885         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4886         local atime=$(stat -c %X $DIR/$tdir)
4887         [ "$atime" = $TEST_39_ATIME ] ||
4888                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4889
4890         # test setting directory atime from future to now
4891         local now=$(date +%s)
4892         touch -a -d @$now $DIR/$tdir
4893
4894         atime=$(stat -c %X $DIR/$tdir)
4895         [ "$atime" -eq "$now"  ] ||
4896                 error "atime is not updated from future: $atime, $now"
4897
4898         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4899         sleep 3
4900
4901         # test setting directory atime when now > dir atime + atime_diff
4902         local d1=$(date +%s)
4903         ls $DIR/$tdir
4904         local d2=$(date +%s)
4905         cancel_lru_locks mdc
4906         atime=$(stat -c %X $DIR/$tdir)
4907         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4908                 error "atime is not updated  : $atime, should be $d2"
4909
4910         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4911         sleep 3
4912
4913         # test not setting directory atime when now < dir atime + atime_diff
4914         ls $DIR/$tdir
4915         cancel_lru_locks mdc
4916         atime=$(stat -c %X $DIR/$tdir)
4917         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4918                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4919
4920         do_facet $SINGLEMDS \
4921                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4922 }
4923 run_test 39l "directory atime update ==========================="
4924
4925 test_39m() {
4926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4927
4928         touch $DIR1/$tfile
4929         sleep 2
4930         local far_past_mtime=$(date -d "May 29 1953" +%s)
4931         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4932
4933         touch -m -d @$far_past_mtime $DIR1/$tfile
4934         touch -a -d @$far_past_atime $DIR1/$tfile
4935
4936         for (( i=0; i < 2; i++ )) ; do
4937                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4938                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4939                         error "atime or mtime set incorrectly"
4940
4941                 cancel_lru_locks $OSC
4942                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4943         done
4944 }
4945 run_test 39m "test atime and mtime before 1970"
4946
4947 test_39n() { # LU-3832
4948         remote_mds_nodsh && skip "remote MDS with nodsh"
4949
4950         local atime_diff=$(do_facet $SINGLEMDS \
4951                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4952         local atime0
4953         local atime1
4954         local atime2
4955
4956         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4957
4958         rm -rf $DIR/$tfile
4959         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4960         atime0=$(stat -c %X $DIR/$tfile)
4961
4962         sleep 5
4963         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4964         atime1=$(stat -c %X $DIR/$tfile)
4965
4966         sleep 5
4967         cancel_lru_locks mdc
4968         cancel_lru_locks osc
4969         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4970         atime2=$(stat -c %X $DIR/$tfile)
4971
4972         do_facet $SINGLEMDS \
4973                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4974
4975         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4976         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4977 }
4978 run_test 39n "check that O_NOATIME is honored"
4979
4980 test_39o() {
4981         TESTDIR=$DIR/$tdir/$tfile
4982         [ -e $TESTDIR ] && rm -rf $TESTDIR
4983         mkdir -p $TESTDIR
4984         cd $TESTDIR
4985         links1=2
4986         ls
4987         mkdir a b
4988         ls
4989         links2=$(stat -c %h .)
4990         [ $(($links1 + 2)) != $links2 ] &&
4991                 error "wrong links count $(($links1 + 2)) != $links2"
4992         rmdir b
4993         links3=$(stat -c %h .)
4994         [ $(($links1 + 1)) != $links3 ] &&
4995                 error "wrong links count $links1 != $links3"
4996         return 0
4997 }
4998 run_test 39o "directory cached attributes updated after create"
4999
5000 test_39p() {
5001         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5002
5003         local MDTIDX=1
5004         TESTDIR=$DIR/$tdir/$tdir
5005         [ -e $TESTDIR ] && rm -rf $TESTDIR
5006         test_mkdir -p $TESTDIR
5007         cd $TESTDIR
5008         links1=2
5009         ls
5010         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5011         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5012         ls
5013         links2=$(stat -c %h .)
5014         [ $(($links1 + 2)) != $links2 ] &&
5015                 error "wrong links count $(($links1 + 2)) != $links2"
5016         rmdir remote_dir2
5017         links3=$(stat -c %h .)
5018         [ $(($links1 + 1)) != $links3 ] &&
5019                 error "wrong links count $links1 != $links3"
5020         return 0
5021 }
5022 run_test 39p "remote directory cached attributes updated after create ========"
5023
5024 test_39r() {
5025         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5026                 skip "no atime update on old OST"
5027         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5028                 skip_env "ldiskfs only test"
5029         fi
5030
5031         local saved_adiff
5032         saved_adiff=$(do_facet ost1 \
5033                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5034         stack_trap "do_facet ost1 \
5035                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5036
5037         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5038
5039         $LFS setstripe -i 0 $DIR/$tfile
5040         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5041                 error "can't write initial file"
5042         cancel_lru_locks osc
5043
5044         # exceed atime_diff and access file
5045         sleep 10
5046         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5047                 error "can't udpate atime"
5048
5049         local atime_cli=$(stat -c %X $DIR/$tfile)
5050         echo "client atime: $atime_cli"
5051         # allow atime update to be written to device
5052         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5053         sleep 5
5054
5055         local ostdev=$(ostdevname 1)
5056         local fid=($(lfs getstripe -y $DIR/$tfile |
5057                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5058         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5059         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5060
5061         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5062         local atime_ost=$(do_facet ost1 "$cmd" |&
5063                           awk -F'[: ]' '/atime:/ { print $4 }')
5064         (( atime_cli == atime_ost )) ||
5065                 error "atime on client $atime_cli != ost $atime_ost"
5066 }
5067 run_test 39r "lazy atime update on OST"
5068
5069 test_39q() { # LU-8041
5070         local testdir=$DIR/$tdir
5071         mkdir -p $testdir
5072         multiop_bg_pause $testdir D_c || error "multiop failed"
5073         local multipid=$!
5074         cancel_lru_locks mdc
5075         kill -USR1 $multipid
5076         local atime=$(stat -c %X $testdir)
5077         [ "$atime" -ne 0 ] || error "atime is zero"
5078 }
5079 run_test 39q "close won't zero out atime"
5080
5081 test_40() {
5082         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5083         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5084                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5085         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5086                 error "$tfile is not 4096 bytes in size"
5087 }
5088 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5089
5090 test_41() {
5091         # bug 1553
5092         small_write $DIR/f41 18
5093 }
5094 run_test 41 "test small file write + fstat ====================="
5095
5096 count_ost_writes() {
5097         lctl get_param -n ${OSC}.*.stats |
5098                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5099                         END { printf("%0.0f", writes) }'
5100 }
5101
5102 # decent default
5103 WRITEBACK_SAVE=500
5104 DIRTY_RATIO_SAVE=40
5105 MAX_DIRTY_RATIO=50
5106 BG_DIRTY_RATIO_SAVE=10
5107 MAX_BG_DIRTY_RATIO=25
5108
5109 start_writeback() {
5110         trap 0
5111         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5112         # dirty_ratio, dirty_background_ratio
5113         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5114                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5115                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5116                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5117         else
5118                 # if file not here, we are a 2.4 kernel
5119                 kill -CONT `pidof kupdated`
5120         fi
5121 }
5122
5123 stop_writeback() {
5124         # setup the trap first, so someone cannot exit the test at the
5125         # exact wrong time and mess up a machine
5126         trap start_writeback EXIT
5127         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5128         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5129                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5130                 sysctl -w vm.dirty_writeback_centisecs=0
5131                 sysctl -w vm.dirty_writeback_centisecs=0
5132                 # save and increase /proc/sys/vm/dirty_ratio
5133                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5134                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5135                 # save and increase /proc/sys/vm/dirty_background_ratio
5136                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5137                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5138         else
5139                 # if file not here, we are a 2.4 kernel
5140                 kill -STOP `pidof kupdated`
5141         fi
5142 }
5143
5144 # ensure that all stripes have some grant before we test client-side cache
5145 setup_test42() {
5146         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5147                 dd if=/dev/zero of=$i bs=4k count=1
5148                 rm $i
5149         done
5150 }
5151
5152 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5153 # file truncation, and file removal.
5154 test_42a() {
5155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5156
5157         setup_test42
5158         cancel_lru_locks $OSC
5159         stop_writeback
5160         sync; sleep 1; sync # just to be safe
5161         BEFOREWRITES=`count_ost_writes`
5162         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5163         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5164         AFTERWRITES=`count_ost_writes`
5165         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5166                 error "$BEFOREWRITES < $AFTERWRITES"
5167         start_writeback
5168 }
5169 run_test 42a "ensure that we don't flush on close"
5170
5171 test_42b() {
5172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5173
5174         setup_test42
5175         cancel_lru_locks $OSC
5176         stop_writeback
5177         sync
5178         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5179         BEFOREWRITES=$(count_ost_writes)
5180         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5181         AFTERWRITES=$(count_ost_writes)
5182         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5183                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5184         fi
5185         BEFOREWRITES=$(count_ost_writes)
5186         sync || error "sync: $?"
5187         AFTERWRITES=$(count_ost_writes)
5188         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5189                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5190         fi
5191         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5192         start_writeback
5193         return 0
5194 }
5195 run_test 42b "test destroy of file with cached dirty data ======"
5196
5197 # if these tests just want to test the effect of truncation,
5198 # they have to be very careful.  consider:
5199 # - the first open gets a {0,EOF}PR lock
5200 # - the first write conflicts and gets a {0, count-1}PW
5201 # - the rest of the writes are under {count,EOF}PW
5202 # - the open for truncate tries to match a {0,EOF}PR
5203 #   for the filesize and cancels the PWs.
5204 # any number of fixes (don't get {0,EOF} on open, match
5205 # composite locks, do smarter file size management) fix
5206 # this, but for now we want these tests to verify that
5207 # the cancellation with truncate intent works, so we
5208 # start the file with a full-file pw lock to match against
5209 # until the truncate.
5210 trunc_test() {
5211         test=$1
5212         file=$DIR/$test
5213         offset=$2
5214         cancel_lru_locks $OSC
5215         stop_writeback
5216         # prime the file with 0,EOF PW to match
5217         touch $file
5218         $TRUNCATE $file 0
5219         sync; sync
5220         # now the real test..
5221         dd if=/dev/zero of=$file bs=1024 count=100
5222         BEFOREWRITES=`count_ost_writes`
5223         $TRUNCATE $file $offset
5224         cancel_lru_locks $OSC
5225         AFTERWRITES=`count_ost_writes`
5226         start_writeback
5227 }
5228
5229 test_42c() {
5230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5231
5232         trunc_test 42c 1024
5233         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5234                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5235         rm $file
5236 }
5237 run_test 42c "test partial truncate of file with cached dirty data"
5238
5239 test_42d() {
5240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5241
5242         trunc_test 42d 0
5243         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5244                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5245         rm $file
5246 }
5247 run_test 42d "test complete truncate of file with cached dirty data"
5248
5249 test_42e() { # bug22074
5250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5251
5252         local TDIR=$DIR/${tdir}e
5253         local pages=16 # hardcoded 16 pages, don't change it.
5254         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5255         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5256         local max_dirty_mb
5257         local warmup_files
5258
5259         test_mkdir $DIR/${tdir}e
5260         $LFS setstripe -c 1 $TDIR
5261         createmany -o $TDIR/f $files
5262
5263         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5264
5265         # we assume that with $OSTCOUNT files, at least one of them will
5266         # be allocated on OST0.
5267         warmup_files=$((OSTCOUNT * max_dirty_mb))
5268         createmany -o $TDIR/w $warmup_files
5269
5270         # write a large amount of data into one file and sync, to get good
5271         # avail_grant number from OST.
5272         for ((i=0; i<$warmup_files; i++)); do
5273                 idx=$($LFS getstripe -i $TDIR/w$i)
5274                 [ $idx -ne 0 ] && continue
5275                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5276                 break
5277         done
5278         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5279         sync
5280         $LCTL get_param $proc_osc0/cur_dirty_bytes
5281         $LCTL get_param $proc_osc0/cur_grant_bytes
5282
5283         # create as much dirty pages as we can while not to trigger the actual
5284         # RPCs directly. but depends on the env, VFS may trigger flush during this
5285         # period, hopefully we are good.
5286         for ((i=0; i<$warmup_files; i++)); do
5287                 idx=$($LFS getstripe -i $TDIR/w$i)
5288                 [ $idx -ne 0 ] && continue
5289                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5290         done
5291         $LCTL get_param $proc_osc0/cur_dirty_bytes
5292         $LCTL get_param $proc_osc0/cur_grant_bytes
5293
5294         # perform the real test
5295         $LCTL set_param $proc_osc0/rpc_stats 0
5296         for ((;i<$files; i++)); do
5297                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5298                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5299         done
5300         sync
5301         $LCTL get_param $proc_osc0/rpc_stats
5302
5303         local percent=0
5304         local have_ppr=false
5305         $LCTL get_param $proc_osc0/rpc_stats |
5306                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5307                         # skip lines until we are at the RPC histogram data
5308                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5309                         $have_ppr || continue
5310
5311                         # we only want the percent stat for < 16 pages
5312                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5313
5314                         percent=$((percent + WPCT))
5315                         if [[ $percent -gt 15 ]]; then
5316                                 error "less than 16-pages write RPCs" \
5317                                       "$percent% > 15%"
5318                                 break
5319                         fi
5320                 done
5321         rm -rf $TDIR
5322 }
5323 run_test 42e "verify sub-RPC writes are not done synchronously"
5324
5325 test_43A() { # was test_43
5326         test_mkdir $DIR/$tdir
5327         cp -p /bin/ls $DIR/$tdir/$tfile
5328         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5329         pid=$!
5330         # give multiop a chance to open
5331         sleep 1
5332
5333         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5334         kill -USR1 $pid
5335         # Wait for multiop to exit
5336         wait $pid
5337 }
5338 run_test 43A "execution of file opened for write should return -ETXTBSY"
5339
5340 test_43a() {
5341         test_mkdir $DIR/$tdir
5342         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5343         $DIR/$tdir/sleep 60 &
5344         SLEEP_PID=$!
5345         # Make sure exec of $tdir/sleep wins race with truncate
5346         sleep 1
5347         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5348         kill $SLEEP_PID
5349 }
5350 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5351
5352 test_43b() {
5353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5354
5355         test_mkdir $DIR/$tdir
5356         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5357         $DIR/$tdir/sleep 60 &
5358         SLEEP_PID=$!
5359         # Make sure exec of $tdir/sleep wins race with truncate
5360         sleep 1
5361         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5362         kill $SLEEP_PID
5363 }
5364 run_test 43b "truncate of file being executed should return -ETXTBSY"
5365
5366 test_43c() {
5367         local testdir="$DIR/$tdir"
5368         test_mkdir $testdir
5369         cp $SHELL $testdir/
5370         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5371                 ( cd $testdir && md5sum -c )
5372 }
5373 run_test 43c "md5sum of copy into lustre"
5374
5375 test_44A() { # was test_44
5376         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5377
5378         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5379         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5380 }
5381 run_test 44A "zero length read from a sparse stripe"
5382
5383 test_44a() {
5384         local nstripe=$($LFS getstripe -c -d $DIR)
5385         [ -z "$nstripe" ] && skip "can't get stripe info"
5386         [[ $nstripe -gt $OSTCOUNT ]] &&
5387                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5388
5389         local stride=$($LFS getstripe -S -d $DIR)
5390         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5391                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5392         fi
5393
5394         OFFSETS="0 $((stride/2)) $((stride-1))"
5395         for offset in $OFFSETS; do
5396                 for i in $(seq 0 $((nstripe-1))); do
5397                         local GLOBALOFFSETS=""
5398                         # size in Bytes
5399                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5400                         local myfn=$DIR/d44a-$size
5401                         echo "--------writing $myfn at $size"
5402                         ll_sparseness_write $myfn $size ||
5403                                 error "ll_sparseness_write"
5404                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5405                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5406                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5407
5408                         for j in $(seq 0 $((nstripe-1))); do
5409                                 # size in Bytes
5410                                 size=$((((j + $nstripe )*$stride + $offset)))
5411                                 ll_sparseness_write $myfn $size ||
5412                                         error "ll_sparseness_write"
5413                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5414                         done
5415                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5416                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5417                         rm -f $myfn
5418                 done
5419         done
5420 }
5421 run_test 44a "test sparse pwrite ==============================="
5422
5423 dirty_osc_total() {
5424         tot=0
5425         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5426                 tot=$(($tot + $d))
5427         done
5428         echo $tot
5429 }
5430 do_dirty_record() {
5431         before=`dirty_osc_total`
5432         echo executing "\"$*\""
5433         eval $*
5434         after=`dirty_osc_total`
5435         echo before $before, after $after
5436 }
5437 test_45() {
5438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5439
5440         f="$DIR/f45"
5441         # Obtain grants from OST if it supports it
5442         echo blah > ${f}_grant
5443         stop_writeback
5444         sync
5445         do_dirty_record "echo blah > $f"
5446         [[ $before -eq $after ]] && error "write wasn't cached"
5447         do_dirty_record "> $f"
5448         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5449         do_dirty_record "echo blah > $f"
5450         [[ $before -eq $after ]] && error "write wasn't cached"
5451         do_dirty_record "sync"
5452         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5453         do_dirty_record "echo blah > $f"
5454         [[ $before -eq $after ]] && error "write wasn't cached"
5455         do_dirty_record "cancel_lru_locks osc"
5456         [[ $before -gt $after ]] ||
5457                 error "lock cancellation didn't lower dirty count"
5458         start_writeback
5459 }
5460 run_test 45 "osc io page accounting ============================"
5461
5462 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5463 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5464 # objects offset and an assert hit when an rpc was built with 1023's mapped
5465 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5466 test_46() {
5467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5468
5469         f="$DIR/f46"
5470         stop_writeback
5471         sync
5472         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5473         sync
5474         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5475         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5476         sync
5477         start_writeback
5478 }
5479 run_test 46 "dirtying a previously written page ================"
5480
5481 # test_47 is removed "Device nodes check" is moved to test_28
5482
5483 test_48a() { # bug 2399
5484         [ "$mds1_FSTYPE" = "zfs" ] &&
5485         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5486                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5487
5488         test_mkdir $DIR/$tdir
5489         cd $DIR/$tdir
5490         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5491         test_mkdir $DIR/$tdir
5492         touch foo || error "'touch foo' failed after recreating cwd"
5493         test_mkdir bar
5494         touch .foo || error "'touch .foo' failed after recreating cwd"
5495         test_mkdir .bar
5496         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5497         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5498         cd . || error "'cd .' failed after recreating cwd"
5499         mkdir . && error "'mkdir .' worked after recreating cwd"
5500         rmdir . && error "'rmdir .' worked after recreating cwd"
5501         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5502         cd .. || error "'cd ..' failed after recreating cwd"
5503 }
5504 run_test 48a "Access renamed working dir (should return errors)="
5505
5506 test_48b() { # bug 2399
5507         rm -rf $DIR/$tdir
5508         test_mkdir $DIR/$tdir
5509         cd $DIR/$tdir
5510         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5511         touch foo && error "'touch foo' worked after removing cwd"
5512         mkdir foo && error "'mkdir foo' worked after removing cwd"
5513         touch .foo && error "'touch .foo' worked after removing cwd"
5514         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5515         ls . > /dev/null && error "'ls .' worked after removing cwd"
5516         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5517         mkdir . && error "'mkdir .' worked after removing cwd"
5518         rmdir . && error "'rmdir .' worked after removing cwd"
5519         ln -s . foo && error "'ln -s .' worked after removing cwd"
5520         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5521 }
5522 run_test 48b "Access removed working dir (should return errors)="
5523
5524 test_48c() { # bug 2350
5525         #lctl set_param debug=-1
5526         #set -vx
5527         rm -rf $DIR/$tdir
5528         test_mkdir -p $DIR/$tdir/dir
5529         cd $DIR/$tdir/dir
5530         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5531         $TRACE touch foo && error "touch foo worked after removing cwd"
5532         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5533         touch .foo && error "touch .foo worked after removing cwd"
5534         mkdir .foo && error "mkdir .foo worked after removing cwd"
5535         $TRACE ls . && error "'ls .' worked after removing cwd"
5536         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5537         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5538         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5539         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5540         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5541 }
5542 run_test 48c "Access removed working subdir (should return errors)"
5543
5544 test_48d() { # bug 2350
5545         #lctl set_param debug=-1
5546         #set -vx
5547         rm -rf $DIR/$tdir
5548         test_mkdir -p $DIR/$tdir/dir
5549         cd $DIR/$tdir/dir
5550         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5551         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5552         $TRACE touch foo && error "'touch foo' worked after removing parent"
5553         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5554         touch .foo && error "'touch .foo' worked after removing parent"
5555         mkdir .foo && error "mkdir .foo worked after removing parent"
5556         $TRACE ls . && error "'ls .' worked after removing parent"
5557         $TRACE ls .. && error "'ls ..' worked after removing parent"
5558         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5559         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5560         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5561         true
5562 }
5563 run_test 48d "Access removed parent subdir (should return errors)"
5564
5565 test_48e() { # bug 4134
5566         #lctl set_param debug=-1
5567         #set -vx
5568         rm -rf $DIR/$tdir
5569         test_mkdir -p $DIR/$tdir/dir
5570         cd $DIR/$tdir/dir
5571         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5572         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5573         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5574         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5575         # On a buggy kernel addition of "touch foo" after cd .. will
5576         # produce kernel oops in lookup_hash_it
5577         touch ../foo && error "'cd ..' worked after recreate parent"
5578         cd $DIR
5579         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5580 }
5581 run_test 48e "Access to recreated parent subdir (should return errors)"
5582
5583 test_48f() {
5584         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5585                 skip "need MDS >= 2.13.55"
5586         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5587         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5588                 skip "needs different host for mdt1 mdt2"
5589         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5590
5591         $LFS mkdir -i0 $DIR/$tdir
5592         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5593
5594         for d in sub1 sub2 sub3; do
5595                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5596                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5597                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5598         done
5599
5600         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5601 }
5602 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5603
5604 test_49() { # LU-1030
5605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5606         remote_ost_nodsh && skip "remote OST with nodsh"
5607
5608         # get ost1 size - $FSNAME-OST0000
5609         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5610                 awk '{ print $4 }')
5611         # write 800M at maximum
5612         [[ $ost1_size -lt 2 ]] && ost1_size=2
5613         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5614
5615         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5616         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5617         local dd_pid=$!
5618
5619         # change max_pages_per_rpc while writing the file
5620         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5621         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5622         # loop until dd process exits
5623         while ps ax -opid | grep -wq $dd_pid; do
5624                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5625                 sleep $((RANDOM % 5 + 1))
5626         done
5627         # restore original max_pages_per_rpc
5628         $LCTL set_param $osc1_mppc=$orig_mppc
5629         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5630 }
5631 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5632
5633 test_50() {
5634         # bug 1485
5635         test_mkdir $DIR/$tdir
5636         cd $DIR/$tdir
5637         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5638 }
5639 run_test 50 "special situations: /proc symlinks  ==============="
5640
5641 test_51a() {    # was test_51
5642         # bug 1516 - create an empty entry right after ".." then split dir
5643         test_mkdir -c1 $DIR/$tdir
5644         touch $DIR/$tdir/foo
5645         $MCREATE $DIR/$tdir/bar
5646         rm $DIR/$tdir/foo
5647         createmany -m $DIR/$tdir/longfile 201
5648         FNUM=202
5649         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5650                 $MCREATE $DIR/$tdir/longfile$FNUM
5651                 FNUM=$(($FNUM + 1))
5652                 echo -n "+"
5653         done
5654         echo
5655         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5656 }
5657 run_test 51a "special situations: split htree with empty entry =="
5658
5659 cleanup_print_lfs_df () {
5660         trap 0
5661         $LFS df
5662         $LFS df -i
5663 }
5664
5665 test_51b() {
5666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5667
5668         local dir=$DIR/$tdir
5669         local nrdirs=$((65536 + 100))
5670
5671         # cleanup the directory
5672         rm -fr $dir
5673
5674         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5675
5676         $LFS df
5677         $LFS df -i
5678         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5679         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5680         [[ $numfree -lt $nrdirs ]] &&
5681                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5682
5683         # need to check free space for the directories as well
5684         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5685         numfree=$(( blkfree / $(fs_inode_ksize) ))
5686         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5687
5688         trap cleanup_print_lfs_df EXIT
5689
5690         # create files
5691         createmany -d $dir/d $nrdirs || {
5692                 unlinkmany $dir/d $nrdirs
5693                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5694         }
5695
5696         # really created :
5697         nrdirs=$(ls -U $dir | wc -l)
5698
5699         # unlink all but 100 subdirectories, then check it still works
5700         local left=100
5701         local delete=$((nrdirs - left))
5702
5703         $LFS df
5704         $LFS df -i
5705
5706         # for ldiskfs the nlink count should be 1, but this is OSD specific
5707         # and so this is listed for informational purposes only
5708         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5709         unlinkmany -d $dir/d $delete ||
5710                 error "unlink of first $delete subdirs failed"
5711
5712         echo "nlink between: $(stat -c %h $dir)"
5713         local found=$(ls -U $dir | wc -l)
5714         [ $found -ne $left ] &&
5715                 error "can't find subdirs: found only $found, expected $left"
5716
5717         unlinkmany -d $dir/d $delete $left ||
5718                 error "unlink of second $left subdirs failed"
5719         # regardless of whether the backing filesystem tracks nlink accurately
5720         # or not, the nlink count shouldn't be more than "." and ".." here
5721         local after=$(stat -c %h $dir)
5722         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5723                 echo "nlink after: $after"
5724
5725         cleanup_print_lfs_df
5726 }
5727 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5728
5729 test_51d() {
5730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5731         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5732         local qos_old
5733
5734         test_mkdir $DIR/$tdir
5735         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5736
5737         qos_old=$(do_facet mds1 \
5738                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5739         do_nodes $(comma_list $(mdts_nodes)) \
5740                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5741         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5742                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5743
5744         createmany -o $DIR/$tdir/t- 1000
5745         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5746         for ((n = 0; n < $OSTCOUNT; n++)); do
5747                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5748                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5749                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5750                             '($1 == '$n') { objs += 1 } \
5751                             END { printf("%0.0f", objs) }')
5752                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5753         done
5754         unlinkmany $DIR/$tdir/t- 1000
5755
5756         nlast=0
5757         for ((n = 0; n < $OSTCOUNT; n++)); do
5758                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5759                         { $LFS df && $LFS df -i &&
5760                         error "OST $n has fewer objects vs. OST $nlast" \
5761                               " (${objs[$n]} < ${objs[$nlast]}"; }
5762                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5763                         { $LFS df && $LFS df -i &&
5764                         error "OST $n has fewer objects vs. OST $nlast" \
5765                               " (${objs[$n]} < ${objs[$nlast]}"; }
5766
5767                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5768                         { $LFS df && $LFS df -i &&
5769                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5770                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5771                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5772                         { $LFS df && $LFS df -i &&
5773                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5774                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5775                 nlast=$n
5776         done
5777 }
5778 run_test 51d "check object distribution"
5779
5780 test_51e() {
5781         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5782                 skip_env "ldiskfs only test"
5783         fi
5784
5785         test_mkdir -c1 $DIR/$tdir
5786         test_mkdir -c1 $DIR/$tdir/d0
5787
5788         touch $DIR/$tdir/d0/foo
5789         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5790                 error "file exceed 65000 nlink limit!"
5791         unlinkmany $DIR/$tdir/d0/f- 65001
5792         return 0
5793 }
5794 run_test 51e "check file nlink limit"
5795
5796 test_51f() {
5797         test_mkdir $DIR/$tdir
5798
5799         local max=100000
5800         local ulimit_old=$(ulimit -n)
5801         local spare=20 # number of spare fd's for scripts/libraries, etc.
5802         local mdt=$($LFS getstripe -m $DIR/$tdir)
5803         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5804
5805         echo "MDT$mdt numfree=$numfree, max=$max"
5806         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5807         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5808                 while ! ulimit -n $((numfree + spare)); do
5809                         numfree=$((numfree * 3 / 4))
5810                 done
5811                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5812         else
5813                 echo "left ulimit at $ulimit_old"
5814         fi
5815
5816         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5817                 unlinkmany $DIR/$tdir/f $numfree
5818                 error "create+open $numfree files in $DIR/$tdir failed"
5819         }
5820         ulimit -n $ulimit_old
5821
5822         # if createmany exits at 120s there will be fewer than $numfree files
5823         unlinkmany $DIR/$tdir/f $numfree || true
5824 }
5825 run_test 51f "check many open files limit"
5826
5827 test_52a() {
5828         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5829         test_mkdir $DIR/$tdir
5830         touch $DIR/$tdir/foo
5831         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5832         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5833         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5834         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5835         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5836                                         error "link worked"
5837         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5838         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5839         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5840                                                      error "lsattr"
5841         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5842         cp -r $DIR/$tdir $TMP/
5843         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5844 }
5845 run_test 52a "append-only flag test (should return errors)"
5846
5847 test_52b() {
5848         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5849         test_mkdir $DIR/$tdir
5850         touch $DIR/$tdir/foo
5851         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5852         cat test > $DIR/$tdir/foo && error "cat test worked"
5853         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5854         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5855         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5856                                         error "link worked"
5857         echo foo >> $DIR/$tdir/foo && error "echo worked"
5858         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5859         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5860         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5861         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5862                                                         error "lsattr"
5863         chattr -i $DIR/$tdir/foo || error "chattr failed"
5864
5865         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5866 }
5867 run_test 52b "immutable flag test (should return errors) ======="
5868
5869 test_53() {
5870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5871         remote_mds_nodsh && skip "remote MDS with nodsh"
5872         remote_ost_nodsh && skip "remote OST with nodsh"
5873
5874         local param
5875         local param_seq
5876         local ostname
5877         local mds_last
5878         local mds_last_seq
5879         local ost_last
5880         local ost_last_seq
5881         local ost_last_id
5882         local ostnum
5883         local node
5884         local found=false
5885         local support_last_seq=true
5886
5887         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5888                 support_last_seq=false
5889
5890         # only test MDT0000
5891         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5892         local value
5893         for value in $(do_facet $SINGLEMDS \
5894                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5895                 param=$(echo ${value[0]} | cut -d "=" -f1)
5896                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5897
5898                 if $support_last_seq; then
5899                         param_seq=$(echo $param |
5900                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5901                         mds_last_seq=$(do_facet $SINGLEMDS \
5902                                        $LCTL get_param -n $param_seq)
5903                 fi
5904                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5905
5906                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5907                 node=$(facet_active_host ost$((ostnum+1)))
5908                 param="obdfilter.$ostname.last_id"
5909                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5910                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5911                         ost_last_id=$ost_last
5912
5913                         if $support_last_seq; then
5914                                 ost_last_id=$(echo $ost_last |
5915                                               awk -F':' '{print $2}' |
5916                                               sed -e "s/^0x//g")
5917                                 ost_last_seq=$(echo $ost_last |
5918                                                awk -F':' '{print $1}')
5919                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5920                         fi
5921
5922                         if [[ $ost_last_id != $mds_last ]]; then
5923                                 error "$ost_last_id != $mds_last"
5924                         else
5925                                 found=true
5926                                 break
5927                         fi
5928                 done
5929         done
5930         $found || error "can not match last_seq/last_id for $mdtosc"
5931         return 0
5932 }
5933 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5934
5935 test_54a() {
5936         perl -MSocket -e ';' || skip "no Socket perl module installed"
5937
5938         $SOCKETSERVER $DIR/socket ||
5939                 error "$SOCKETSERVER $DIR/socket failed: $?"
5940         $SOCKETCLIENT $DIR/socket ||
5941                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5942         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5943 }
5944 run_test 54a "unix domain socket test =========================="
5945
5946 test_54b() {
5947         f="$DIR/f54b"
5948         mknod $f c 1 3
5949         chmod 0666 $f
5950         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5951 }
5952 run_test 54b "char device works in lustre ======================"
5953
5954 find_loop_dev() {
5955         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5956         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5957         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5958
5959         for i in $(seq 3 7); do
5960                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5961                 LOOPDEV=$LOOPBASE$i
5962                 LOOPNUM=$i
5963                 break
5964         done
5965 }
5966
5967 cleanup_54c() {
5968         local rc=0
5969         loopdev="$DIR/loop54c"
5970
5971         trap 0
5972         $UMOUNT $DIR/$tdir || rc=$?
5973         losetup -d $loopdev || true
5974         losetup -d $LOOPDEV || true
5975         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5976         return $rc
5977 }
5978
5979 test_54c() {
5980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5981
5982         loopdev="$DIR/loop54c"
5983
5984         find_loop_dev
5985         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5986         trap cleanup_54c EXIT
5987         mknod $loopdev b 7 $LOOPNUM
5988         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5989         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5990         losetup $loopdev $DIR/$tfile ||
5991                 error "can't set up $loopdev for $DIR/$tfile"
5992         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5993         test_mkdir $DIR/$tdir
5994         mount -t ext2 $loopdev $DIR/$tdir ||
5995                 error "error mounting $loopdev on $DIR/$tdir"
5996         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5997                 error "dd write"
5998         df $DIR/$tdir
5999         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6000                 error "dd read"
6001         cleanup_54c
6002 }
6003 run_test 54c "block device works in lustre ====================="
6004
6005 test_54d() {
6006         local pipe="$DIR/$tfile.pipe"
6007         local string="aaaaaa"
6008
6009         mknod $pipe p
6010         echo -n "$string" > $pipe &
6011         local result=$(cat $pipe)
6012         [[ "$result" == "$string" ]] || error "$result != $string"
6013 }
6014 run_test 54d "fifo device works in lustre ======================"
6015
6016 test_54e() {
6017         f="$DIR/f54e"
6018         string="aaaaaa"
6019         cp -aL /dev/console $f
6020         echo $string > $f || error "echo $string to $f failed"
6021 }
6022 run_test 54e "console/tty device works in lustre ======================"
6023
6024 test_56a() {
6025         local numfiles=3
6026         local numdirs=2
6027         local dir=$DIR/$tdir
6028
6029         rm -rf $dir
6030         test_mkdir -p $dir/dir
6031         for i in $(seq $numfiles); do
6032                 touch $dir/file$i
6033                 touch $dir/dir/file$i
6034         done
6035
6036         local numcomp=$($LFS getstripe --component-count $dir)
6037
6038         [[ $numcomp == 0 ]] && numcomp=1
6039
6040         # test lfs getstripe with --recursive
6041         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6042
6043         [[ $filenum -eq $((numfiles * 2)) ]] ||
6044                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6045         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6046         [[ $filenum -eq $numfiles ]] ||
6047                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6048         echo "$LFS getstripe showed obdidx or l_ost_idx"
6049
6050         # test lfs getstripe with file instead of dir
6051         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6052         [[ $filenum -eq 1 ]] ||
6053                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6054         echo "$LFS getstripe file1 passed"
6055
6056         #test lfs getstripe with --verbose
6057         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6058         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6059                 error "$LFS getstripe --verbose $dir: "\
6060                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6061         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6062                 error "$LFS getstripe $dir: showed lmm_magic"
6063
6064         #test lfs getstripe with -v prints lmm_fid
6065         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6066         local countfids=$((numdirs + numfiles * numcomp))
6067         [[ $filenum -eq $countfids ]] ||
6068                 error "$LFS getstripe -v $dir: "\
6069                       "got $filenum want $countfids lmm_fid"
6070         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6071                 error "$LFS getstripe $dir: showed lmm_fid by default"
6072         echo "$LFS getstripe --verbose passed"
6073
6074         #check for FID information
6075         local fid1=$($LFS getstripe --fid $dir/file1)
6076         local fid2=$($LFS getstripe --verbose $dir/file1 |
6077                      awk '/lmm_fid: / { print $2; exit; }')
6078         local fid3=$($LFS path2fid $dir/file1)
6079
6080         [ "$fid1" != "$fid2" ] &&
6081                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6082         [ "$fid1" != "$fid3" ] &&
6083                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6084         echo "$LFS getstripe --fid passed"
6085
6086         #test lfs getstripe with --obd
6087         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6088                 error "$LFS getstripe --obd wrong_uuid: should return error"
6089
6090         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6091
6092         local ostidx=1
6093         local obduuid=$(ostuuid_from_index $ostidx)
6094         local found=$($LFS getstripe -r --obd $obduuid $dir |
6095                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6096
6097         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6098         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6099                 ((filenum--))
6100         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6101                 ((filenum--))
6102
6103         [[ $found -eq $filenum ]] ||
6104                 error "$LFS getstripe --obd: found $found expect $filenum"
6105         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6106                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6107                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6108                 error "$LFS getstripe --obd: should not show file on other obd"
6109         echo "$LFS getstripe --obd passed"
6110 }
6111 run_test 56a "check $LFS getstripe"
6112
6113 test_56b() {
6114         local dir=$DIR/$tdir
6115         local numdirs=3
6116
6117         test_mkdir $dir
6118         for i in $(seq $numdirs); do
6119                 test_mkdir $dir/dir$i
6120         done
6121
6122         # test lfs getdirstripe default mode is non-recursion, which is
6123         # different from lfs getstripe
6124         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6125
6126         [[ $dircnt -eq 1 ]] ||
6127                 error "$LFS getdirstripe: found $dircnt, not 1"
6128         dircnt=$($LFS getdirstripe --recursive $dir |
6129                 grep -c lmv_stripe_count)
6130         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6131                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6132 }
6133 run_test 56b "check $LFS getdirstripe"
6134
6135 test_56c() {
6136         remote_ost_nodsh && skip "remote OST with nodsh"
6137
6138         local ost_idx=0
6139         local ost_name=$(ostname_from_index $ost_idx)
6140         local old_status=$(ost_dev_status $ost_idx)
6141         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6142
6143         [[ -z "$old_status" ]] ||
6144                 skip_env "OST $ost_name is in $old_status status"
6145
6146         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6147         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6148                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6149         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6150                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6151                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6152         fi
6153
6154         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6155                 error "$LFS df -v showing inactive devices"
6156         sleep_maxage
6157
6158         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6159
6160         [[ "$new_status" =~ "D" ]] ||
6161                 error "$ost_name status is '$new_status', missing 'D'"
6162         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6163                 [[ "$new_status" =~ "N" ]] ||
6164                         error "$ost_name status is '$new_status', missing 'N'"
6165         fi
6166         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6167                 [[ "$new_status" =~ "f" ]] ||
6168                         error "$ost_name status is '$new_status', missing 'f'"
6169         fi
6170
6171         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6172         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6173                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6174         [[ -z "$p" ]] && restore_lustre_params < $p || true
6175         sleep_maxage
6176
6177         new_status=$(ost_dev_status $ost_idx)
6178         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6179                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6180         # can't check 'f' as devices may actually be on flash
6181 }
6182 run_test 56c "check 'lfs df' showing device status"
6183
6184 test_56d() {
6185         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6186         local osts=$($LFS df -v $MOUNT | grep -c OST)
6187
6188         $LFS df $MOUNT
6189
6190         (( mdts == MDSCOUNT )) ||
6191                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6192         (( osts == OSTCOUNT )) ||
6193                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6194 }
6195 run_test 56d "'lfs df -v' prints only configured devices"
6196
6197 test_56e() {
6198         err_enoent=2 # No such file or directory
6199         err_eopnotsupp=95 # Operation not supported
6200
6201         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6202         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6203
6204         # Check for handling of path not exists
6205         output=$($LFS df $enoent_mnt 2>&1)
6206         ret=$?
6207
6208         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6209         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6210                 error "expect failure $err_enoent, not $ret"
6211
6212         # Check for handling of non-Lustre FS
6213         output=$($LFS df $notsup_mnt)
6214         ret=$?
6215
6216         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6217         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6218                 error "expect success $err_eopnotsupp, not $ret"
6219
6220         # Check for multiple LustreFS argument
6221         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6222         ret=$?
6223
6224         [[ $output -eq 3 && $ret -eq 0 ]] ||
6225                 error "expect success 3, not $output, rc = $ret"
6226
6227         # Check for correct non-Lustre FS handling among multiple
6228         # LustreFS argument
6229         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6230                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6231         ret=$?
6232
6233         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6234                 error "expect success 2, not $output, rc = $ret"
6235 }
6236 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6237
6238 NUMFILES=3
6239 NUMDIRS=3
6240 setup_56() {
6241         local local_tdir="$1"
6242         local local_numfiles="$2"
6243         local local_numdirs="$3"
6244         local dir_params="$4"
6245         local dir_stripe_params="$5"
6246
6247         if [ ! -d "$local_tdir" ] ; then
6248                 test_mkdir -p $dir_stripe_params $local_tdir
6249                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6250                 for i in $(seq $local_numfiles) ; do
6251                         touch $local_tdir/file$i
6252                 done
6253                 for i in $(seq $local_numdirs) ; do
6254                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6255                         for j in $(seq $local_numfiles) ; do
6256                                 touch $local_tdir/dir$i/file$j
6257                         done
6258                 done
6259         fi
6260 }
6261
6262 setup_56_special() {
6263         local local_tdir=$1
6264         local local_numfiles=$2
6265         local local_numdirs=$3
6266
6267         setup_56 $local_tdir $local_numfiles $local_numdirs
6268
6269         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6270                 for i in $(seq $local_numfiles) ; do
6271                         mknod $local_tdir/loop${i}b b 7 $i
6272                         mknod $local_tdir/null${i}c c 1 3
6273                         ln -s $local_tdir/file1 $local_tdir/link${i}
6274                 done
6275                 for i in $(seq $local_numdirs) ; do
6276                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6277                         mknod $local_tdir/dir$i/null${i}c c 1 3
6278                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6279                 done
6280         fi
6281 }
6282
6283 test_56g() {
6284         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6285         local expected=$(($NUMDIRS + 2))
6286
6287         setup_56 $dir $NUMFILES $NUMDIRS
6288
6289         # test lfs find with -name
6290         for i in $(seq $NUMFILES) ; do
6291                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6292
6293                 [ $nums -eq $expected ] ||
6294                         error "lfs find -name '*$i' $dir wrong: "\
6295                               "found $nums, expected $expected"
6296         done
6297 }
6298 run_test 56g "check lfs find -name"
6299
6300 test_56h() {
6301         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6302         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6303
6304         setup_56 $dir $NUMFILES $NUMDIRS
6305
6306         # test lfs find with ! -name
6307         for i in $(seq $NUMFILES) ; do
6308                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6309
6310                 [ $nums -eq $expected ] ||
6311                         error "lfs find ! -name '*$i' $dir wrong: "\
6312                               "found $nums, expected $expected"
6313         done
6314 }
6315 run_test 56h "check lfs find ! -name"
6316
6317 test_56i() {
6318         local dir=$DIR/$tdir
6319
6320         test_mkdir $dir
6321
6322         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6323         local out=$($cmd)
6324
6325         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6326 }
6327 run_test 56i "check 'lfs find -ost UUID' skips directories"
6328
6329 test_56j() {
6330         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6331
6332         setup_56_special $dir $NUMFILES $NUMDIRS
6333
6334         local expected=$((NUMDIRS + 1))
6335         local cmd="$LFS find -type d $dir"
6336         local nums=$($cmd | wc -l)
6337
6338         [ $nums -eq $expected ] ||
6339                 error "'$cmd' wrong: found $nums, expected $expected"
6340 }
6341 run_test 56j "check lfs find -type d"
6342
6343 test_56k() {
6344         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6345
6346         setup_56_special $dir $NUMFILES $NUMDIRS
6347
6348         local expected=$(((NUMDIRS + 1) * NUMFILES))
6349         local cmd="$LFS find -type f $dir"
6350         local nums=$($cmd | wc -l)
6351
6352         [ $nums -eq $expected ] ||
6353                 error "'$cmd' wrong: found $nums, expected $expected"
6354 }
6355 run_test 56k "check lfs find -type f"
6356
6357 test_56l() {
6358         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6359
6360         setup_56_special $dir $NUMFILES $NUMDIRS
6361
6362         local expected=$((NUMDIRS + NUMFILES))
6363         local cmd="$LFS find -type b $dir"
6364         local nums=$($cmd | wc -l)
6365
6366         [ $nums -eq $expected ] ||
6367                 error "'$cmd' wrong: found $nums, expected $expected"
6368 }
6369 run_test 56l "check lfs find -type b"
6370
6371 test_56m() {
6372         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6373
6374         setup_56_special $dir $NUMFILES $NUMDIRS
6375
6376         local expected=$((NUMDIRS + NUMFILES))
6377         local cmd="$LFS find -type c $dir"
6378         local nums=$($cmd | wc -l)
6379         [ $nums -eq $expected ] ||
6380                 error "'$cmd' wrong: found $nums, expected $expected"
6381 }
6382 run_test 56m "check lfs find -type c"
6383
6384 test_56n() {
6385         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6386         setup_56_special $dir $NUMFILES $NUMDIRS
6387
6388         local expected=$((NUMDIRS + NUMFILES))
6389         local cmd="$LFS find -type l $dir"
6390         local nums=$($cmd | wc -l)
6391
6392         [ $nums -eq $expected ] ||
6393                 error "'$cmd' wrong: found $nums, expected $expected"
6394 }
6395 run_test 56n "check lfs find -type l"
6396
6397 test_56o() {
6398         local dir=$DIR/$tdir
6399
6400         setup_56 $dir $NUMFILES $NUMDIRS
6401         utime $dir/file1 > /dev/null || error "utime (1)"
6402         utime $dir/file2 > /dev/null || error "utime (2)"
6403         utime $dir/dir1 > /dev/null || error "utime (3)"
6404         utime $dir/dir2 > /dev/null || error "utime (4)"
6405         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6406         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6407
6408         local expected=4
6409         local nums=$($LFS find -mtime +0 $dir | wc -l)
6410
6411         [ $nums -eq $expected ] ||
6412                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6413
6414         expected=12
6415         cmd="$LFS find -mtime 0 $dir"
6416         nums=$($cmd | wc -l)
6417         [ $nums -eq $expected ] ||
6418                 error "'$cmd' wrong: found $nums, expected $expected"
6419 }
6420 run_test 56o "check lfs find -mtime for old files"
6421
6422 test_56ob() {
6423         local dir=$DIR/$tdir
6424         local expected=1
6425         local count=0
6426
6427         # just to make sure there is something that won't be found
6428         test_mkdir $dir
6429         touch $dir/$tfile.now
6430
6431         for age in year week day hour min; do
6432                 count=$((count + 1))
6433
6434                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6435                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6436                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6437
6438                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6439                 local nums=$($cmd | wc -l)
6440                 [ $nums -eq $expected ] ||
6441                         error "'$cmd' wrong: found $nums, expected $expected"
6442
6443                 cmd="$LFS find $dir -atime $count${age:0:1}"
6444                 nums=$($cmd | wc -l)
6445                 [ $nums -eq $expected ] ||
6446                         error "'$cmd' wrong: found $nums, expected $expected"
6447         done
6448
6449         sleep 2
6450         cmd="$LFS find $dir -ctime +1s -type f"
6451         nums=$($cmd | wc -l)
6452         (( $nums == $count * 2 + 1)) ||
6453                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6454 }
6455 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6456
6457 test_newerXY_base() {
6458         local x=$1
6459         local y=$2
6460         local dir=$DIR/$tdir
6461         local ref
6462         local negref
6463
6464         if [ $y == "t" ]; then
6465                 if [ $x == "b" ]; then
6466                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6467                 else
6468                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6469                 fi
6470         else
6471                 ref=$DIR/$tfile.newer.$x$y
6472                 touch $ref || error "touch $ref failed"
6473         fi
6474
6475         echo "before = $ref"
6476         sleep 2
6477         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6478         sleep 2
6479         if [ $y == "t" ]; then
6480                 if [ $x == "b" ]; then
6481                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6482                 else
6483                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6484                 fi
6485         else
6486                 negref=$DIR/$tfile.negnewer.$x$y
6487                 touch $negref || error "touch $negref failed"
6488         fi
6489
6490         echo "after = $negref"
6491         local cmd="$LFS find $dir -newer$x$y $ref"
6492         local nums=$(eval $cmd | wc -l)
6493         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6494
6495         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6496                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6497
6498         cmd="$LFS find $dir ! -newer$x$y $negref"
6499         nums=$(eval $cmd | wc -l)
6500         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6501                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6502
6503         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6504         nums=$(eval $cmd | wc -l)
6505         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6506                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6507
6508         rm -rf $DIR/*
6509 }
6510
6511 test_56oc() {
6512         test_newerXY_base "a" "a"
6513         test_newerXY_base "a" "m"
6514         test_newerXY_base "a" "c"
6515         test_newerXY_base "m" "a"
6516         test_newerXY_base "m" "m"
6517         test_newerXY_base "m" "c"
6518         test_newerXY_base "c" "a"
6519         test_newerXY_base "c" "m"
6520         test_newerXY_base "c" "c"
6521
6522         [[ -n "$sles_version" ]] &&
6523                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6524
6525         test_newerXY_base "a" "t"
6526         test_newerXY_base "m" "t"
6527         test_newerXY_base "c" "t"
6528
6529         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6530            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6531                 ! btime_supported && echo "btime unsupported" && return 0
6532
6533         test_newerXY_base "b" "b"
6534         test_newerXY_base "b" "t"
6535 }
6536 run_test 56oc "check lfs find -newerXY work"
6537
6538 btime_supported() {
6539         local dir=$DIR/$tdir
6540         local rc
6541
6542         mkdir -p $dir
6543         touch $dir/$tfile
6544         $LFS find $dir -btime -1d -type f
6545         rc=$?
6546         rm -rf $dir
6547         return $rc
6548 }
6549
6550 test_56od() {
6551         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6552                 ! btime_supported && skip "btime unsupported on MDS"
6553
6554         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6555                 ! btime_supported && skip "btime unsupported on clients"
6556
6557         local dir=$DIR/$tdir
6558         local ref=$DIR/$tfile.ref
6559         local negref=$DIR/$tfile.negref
6560
6561         mkdir $dir || error "mkdir $dir failed"
6562         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6563         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6564         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6565         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6566         touch $ref || error "touch $ref failed"
6567         # sleep 3 seconds at least
6568         sleep 3
6569
6570         local before=$(do_facet mds1 date +%s)
6571         local skew=$(($(date +%s) - before + 1))
6572
6573         if (( skew < 0 && skew > -5 )); then
6574                 sleep $((0 - skew + 1))
6575                 skew=0
6576         fi
6577
6578         # Set the dir stripe params to limit files all on MDT0,
6579         # otherwise we need to calc the max clock skew between
6580         # the client and MDTs.
6581         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6582         sleep 2
6583         touch $negref || error "touch $negref failed"
6584
6585         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6586         local nums=$($cmd | wc -l)
6587         local expected=$(((NUMFILES + 1) * NUMDIRS))
6588
6589         [ $nums -eq $expected ] ||
6590                 error "'$cmd' wrong: found $nums, expected $expected"
6591
6592         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6593         nums=$($cmd | wc -l)
6594         expected=$((NUMFILES + 1))
6595         [ $nums -eq $expected ] ||
6596                 error "'$cmd' wrong: found $nums, expected $expected"
6597
6598         [ $skew -lt 0 ] && return
6599
6600         local after=$(do_facet mds1 date +%s)
6601         local age=$((after - before + 1 + skew))
6602
6603         cmd="$LFS find $dir -btime -${age}s -type f"
6604         nums=$($cmd | wc -l)
6605         expected=$(((NUMFILES + 1) * NUMDIRS))
6606
6607         echo "Clock skew between client and server: $skew, age:$age"
6608         [ $nums -eq $expected ] ||
6609                 error "'$cmd' wrong: found $nums, expected $expected"
6610
6611         expected=$(($NUMDIRS + 1))
6612         cmd="$LFS find $dir -btime -${age}s -type d"
6613         nums=$($cmd | wc -l)
6614         [ $nums -eq $expected ] ||
6615                 error "'$cmd' wrong: found $nums, expected $expected"
6616         rm -f $ref $negref || error "Failed to remove $ref $negref"
6617 }
6618 run_test 56od "check lfs find -btime with units"
6619
6620 test_56p() {
6621         [ $RUNAS_ID -eq $UID ] &&
6622                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6623
6624         local dir=$DIR/$tdir
6625
6626         setup_56 $dir $NUMFILES $NUMDIRS
6627         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6628
6629         local expected=$NUMFILES
6630         local cmd="$LFS find -uid $RUNAS_ID $dir"
6631         local nums=$($cmd | wc -l)
6632
6633         [ $nums -eq $expected ] ||
6634                 error "'$cmd' wrong: found $nums, expected $expected"
6635
6636         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6637         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6638         nums=$($cmd | wc -l)
6639         [ $nums -eq $expected ] ||
6640                 error "'$cmd' wrong: found $nums, expected $expected"
6641 }
6642 run_test 56p "check lfs find -uid and ! -uid"
6643
6644 test_56q() {
6645         [ $RUNAS_ID -eq $UID ] &&
6646                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6647
6648         local dir=$DIR/$tdir
6649
6650         setup_56 $dir $NUMFILES $NUMDIRS
6651         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6652
6653         local expected=$NUMFILES
6654         local cmd="$LFS find -gid $RUNAS_GID $dir"
6655         local nums=$($cmd | wc -l)
6656
6657         [ $nums -eq $expected ] ||
6658                 error "'$cmd' wrong: found $nums, expected $expected"
6659
6660         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6661         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6662         nums=$($cmd | wc -l)
6663         [ $nums -eq $expected ] ||
6664                 error "'$cmd' wrong: found $nums, expected $expected"
6665 }
6666 run_test 56q "check lfs find -gid and ! -gid"
6667
6668 test_56r() {
6669         local dir=$DIR/$tdir
6670
6671         setup_56 $dir $NUMFILES $NUMDIRS
6672
6673         local expected=12
6674         local cmd="$LFS find -size 0 -type f -lazy $dir"
6675         local nums=$($cmd | wc -l)
6676
6677         [ $nums -eq $expected ] ||
6678                 error "'$cmd' wrong: found $nums, expected $expected"
6679         cmd="$LFS find -size 0 -type f $dir"
6680         nums=$($cmd | wc -l)
6681         [ $nums -eq $expected ] ||
6682                 error "'$cmd' wrong: found $nums, expected $expected"
6683
6684         expected=0
6685         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6686         nums=$($cmd | wc -l)
6687         [ $nums -eq $expected ] ||
6688                 error "'$cmd' wrong: found $nums, expected $expected"
6689         cmd="$LFS find ! -size 0 -type f $dir"
6690         nums=$($cmd | wc -l)
6691         [ $nums -eq $expected ] ||
6692                 error "'$cmd' wrong: found $nums, expected $expected"
6693
6694         echo "test" > $dir/$tfile
6695         echo "test2" > $dir/$tfile.2 && sync
6696         expected=1
6697         cmd="$LFS find -size 5 -type f -lazy $dir"
6698         nums=$($cmd | wc -l)
6699         [ $nums -eq $expected ] ||
6700                 error "'$cmd' wrong: found $nums, expected $expected"
6701         cmd="$LFS find -size 5 -type f $dir"
6702         nums=$($cmd | wc -l)
6703         [ $nums -eq $expected ] ||
6704                 error "'$cmd' wrong: found $nums, expected $expected"
6705
6706         expected=1
6707         cmd="$LFS find -size +5 -type f -lazy $dir"
6708         nums=$($cmd | wc -l)
6709         [ $nums -eq $expected ] ||
6710                 error "'$cmd' wrong: found $nums, expected $expected"
6711         cmd="$LFS find -size +5 -type f $dir"
6712         nums=$($cmd | wc -l)
6713         [ $nums -eq $expected ] ||
6714                 error "'$cmd' wrong: found $nums, expected $expected"
6715
6716         expected=2
6717         cmd="$LFS find -size +0 -type f -lazy $dir"
6718         nums=$($cmd | wc -l)
6719         [ $nums -eq $expected ] ||
6720                 error "'$cmd' wrong: found $nums, expected $expected"
6721         cmd="$LFS find -size +0 -type f $dir"
6722         nums=$($cmd | wc -l)
6723         [ $nums -eq $expected ] ||
6724                 error "'$cmd' wrong: found $nums, expected $expected"
6725
6726         expected=2
6727         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6728         nums=$($cmd | wc -l)
6729         [ $nums -eq $expected ] ||
6730                 error "'$cmd' wrong: found $nums, expected $expected"
6731         cmd="$LFS find ! -size -5 -type f $dir"
6732         nums=$($cmd | wc -l)
6733         [ $nums -eq $expected ] ||
6734                 error "'$cmd' wrong: found $nums, expected $expected"
6735
6736         expected=12
6737         cmd="$LFS find -size -5 -type f -lazy $dir"
6738         nums=$($cmd | wc -l)
6739         [ $nums -eq $expected ] ||
6740                 error "'$cmd' wrong: found $nums, expected $expected"
6741         cmd="$LFS find -size -5 -type f $dir"
6742         nums=$($cmd | wc -l)
6743         [ $nums -eq $expected ] ||
6744                 error "'$cmd' wrong: found $nums, expected $expected"
6745 }
6746 run_test 56r "check lfs find -size works"
6747
6748 test_56ra_sub() {
6749         local expected=$1
6750         local glimpses=$2
6751         local cmd="$3"
6752
6753         cancel_lru_locks $OSC
6754
6755         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6756         local nums=$($cmd | wc -l)
6757
6758         [ $nums -eq $expected ] ||
6759                 error "'$cmd' wrong: found $nums, expected $expected"
6760
6761         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6762
6763         if (( rpcs_before + glimpses != rpcs_after )); then
6764                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6765                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6766
6767                 if [[ $glimpses == 0 ]]; then
6768                         error "'$cmd' should not send glimpse RPCs to OST"
6769                 else
6770                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6771                 fi
6772         fi
6773 }
6774
6775 test_56ra() {
6776         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6777                 skip "MDS < 2.12.58 doesn't return LSOM data"
6778         local dir=$DIR/$tdir
6779         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6780
6781         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6782
6783         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6784         $LCTL set_param -n llite.*.statahead_agl=0
6785         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6786
6787         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6788         # open and close all files to ensure LSOM is updated
6789         cancel_lru_locks $OSC
6790         find $dir -type f | xargs cat > /dev/null
6791
6792         #   expect_found  glimpse_rpcs  command_to_run
6793         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6794         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6795         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6796         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6797
6798         echo "test" > $dir/$tfile
6799         echo "test2" > $dir/$tfile.2 && sync
6800         cancel_lru_locks $OSC
6801         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6802
6803         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6804         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6805         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6806         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6807
6808         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6809         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6810         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6811         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6812         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6813         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6814 }
6815 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6816
6817 test_56rb() {
6818         local dir=$DIR/$tdir
6819         local tmp=$TMP/$tfile.log
6820         local mdt_idx;
6821
6822         test_mkdir -p $dir || error "failed to mkdir $dir"
6823         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6824                 error "failed to setstripe $dir/$tfile"
6825         mdt_idx=$($LFS getdirstripe -i $dir)
6826         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6827
6828         stack_trap "rm -f $tmp" EXIT
6829         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6830         ! grep -q obd_uuid $tmp ||
6831                 error "failed to find --size +100K --ost 0 $dir"
6832         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6833         ! grep -q obd_uuid $tmp ||
6834                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6835 }
6836 run_test 56rb "check lfs find --size --ost/--mdt works"
6837
6838 test_56rc() {
6839         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6840         local dir=$DIR/$tdir
6841         local found
6842
6843         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6844         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6845         (( $MDSCOUNT > 2 )) &&
6846                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6847         mkdir $dir/$tdir-{1..10}
6848         touch $dir/$tfile-{1..10}
6849
6850         found=$($LFS find $dir --mdt-count 2 | wc -l)
6851         expect=11
6852         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6853
6854         found=$($LFS find $dir -T +1 | wc -l)
6855         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6856         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6857
6858         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6859         expect=11
6860         (( $found == $expect )) || error "found $found all_char, expect $expect"
6861
6862         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6863         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6864         (( $found == $expect )) || error "found $found all_char, expect $expect"
6865 }
6866 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6867
6868 test_56s() { # LU-611 #LU-9369
6869         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6870
6871         local dir=$DIR/$tdir
6872         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6873
6874         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6875         for i in $(seq $NUMDIRS); do
6876                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6877         done
6878
6879         local expected=$NUMDIRS
6880         local cmd="$LFS find -c $OSTCOUNT $dir"
6881         local nums=$($cmd | wc -l)
6882
6883         [ $nums -eq $expected ] || {
6884                 $LFS getstripe -R $dir
6885                 error "'$cmd' wrong: found $nums, expected $expected"
6886         }
6887
6888         expected=$((NUMDIRS + onestripe))
6889         cmd="$LFS find -stripe-count +0 -type f $dir"
6890         nums=$($cmd | wc -l)
6891         [ $nums -eq $expected ] || {
6892                 $LFS getstripe -R $dir
6893                 error "'$cmd' wrong: found $nums, expected $expected"
6894         }
6895
6896         expected=$onestripe
6897         cmd="$LFS find -stripe-count 1 -type f $dir"
6898         nums=$($cmd | wc -l)
6899         [ $nums -eq $expected ] || {
6900                 $LFS getstripe -R $dir
6901                 error "'$cmd' wrong: found $nums, expected $expected"
6902         }
6903
6904         cmd="$LFS find -stripe-count -2 -type f $dir"
6905         nums=$($cmd | wc -l)
6906         [ $nums -eq $expected ] || {
6907                 $LFS getstripe -R $dir
6908                 error "'$cmd' wrong: found $nums, expected $expected"
6909         }
6910
6911         expected=0
6912         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6913         nums=$($cmd | wc -l)
6914         [ $nums -eq $expected ] || {
6915                 $LFS getstripe -R $dir
6916                 error "'$cmd' wrong: found $nums, expected $expected"
6917         }
6918 }
6919 run_test 56s "check lfs find -stripe-count works"
6920
6921 test_56t() { # LU-611 #LU-9369
6922         local dir=$DIR/$tdir
6923
6924         setup_56 $dir 0 $NUMDIRS
6925         for i in $(seq $NUMDIRS); do
6926                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6927         done
6928
6929         local expected=$NUMDIRS
6930         local cmd="$LFS find -S 8M $dir"
6931         local nums=$($cmd | wc -l)
6932
6933         [ $nums -eq $expected ] || {
6934                 $LFS getstripe -R $dir
6935                 error "'$cmd' wrong: found $nums, expected $expected"
6936         }
6937         rm -rf $dir
6938
6939         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6940
6941         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6942
6943         expected=$(((NUMDIRS + 1) * NUMFILES))
6944         cmd="$LFS find -stripe-size 512k -type f $dir"
6945         nums=$($cmd | wc -l)
6946         [ $nums -eq $expected ] ||
6947                 error "'$cmd' wrong: found $nums, expected $expected"
6948
6949         cmd="$LFS find -stripe-size +320k -type f $dir"
6950         nums=$($cmd | wc -l)
6951         [ $nums -eq $expected ] ||
6952                 error "'$cmd' wrong: found $nums, expected $expected"
6953
6954         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6955         cmd="$LFS find -stripe-size +200k -type f $dir"
6956         nums=$($cmd | wc -l)
6957         [ $nums -eq $expected ] ||
6958                 error "'$cmd' wrong: found $nums, expected $expected"
6959
6960         cmd="$LFS find -stripe-size -640k -type f $dir"
6961         nums=$($cmd | wc -l)
6962         [ $nums -eq $expected ] ||
6963                 error "'$cmd' wrong: found $nums, expected $expected"
6964
6965         expected=4
6966         cmd="$LFS find -stripe-size 256k -type f $dir"
6967         nums=$($cmd | wc -l)
6968         [ $nums -eq $expected ] ||
6969                 error "'$cmd' wrong: found $nums, expected $expected"
6970
6971         cmd="$LFS find -stripe-size -320k -type f $dir"
6972         nums=$($cmd | wc -l)
6973         [ $nums -eq $expected ] ||
6974                 error "'$cmd' wrong: found $nums, expected $expected"
6975
6976         expected=0
6977         cmd="$LFS find -stripe-size 1024k -type f $dir"
6978         nums=$($cmd | wc -l)
6979         [ $nums -eq $expected ] ||
6980                 error "'$cmd' wrong: found $nums, expected $expected"
6981 }
6982 run_test 56t "check lfs find -stripe-size works"
6983
6984 test_56u() { # LU-611
6985         local dir=$DIR/$tdir
6986
6987         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6988
6989         if [[ $OSTCOUNT -gt 1 ]]; then
6990                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6991                 onestripe=4
6992         else
6993                 onestripe=0
6994         fi
6995
6996         local expected=$(((NUMDIRS + 1) * NUMFILES))
6997         local cmd="$LFS find -stripe-index 0 -type f $dir"
6998         local nums=$($cmd | wc -l)
6999
7000         [ $nums -eq $expected ] ||
7001                 error "'$cmd' wrong: found $nums, expected $expected"
7002
7003         expected=$onestripe
7004         cmd="$LFS find -stripe-index 1 -type f $dir"
7005         nums=$($cmd | wc -l)
7006         [ $nums -eq $expected ] ||
7007                 error "'$cmd' wrong: found $nums, expected $expected"
7008
7009         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7010         nums=$($cmd | wc -l)
7011         [ $nums -eq $expected ] ||
7012                 error "'$cmd' wrong: found $nums, expected $expected"
7013
7014         expected=0
7015         # This should produce an error and not return any files
7016         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7017         nums=$($cmd 2>/dev/null | wc -l)
7018         [ $nums -eq $expected ] ||
7019                 error "'$cmd' wrong: found $nums, expected $expected"
7020
7021         if [[ $OSTCOUNT -gt 1 ]]; then
7022                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7023                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7024                 nums=$($cmd | wc -l)
7025                 [ $nums -eq $expected ] ||
7026                         error "'$cmd' wrong: found $nums, expected $expected"
7027         fi
7028 }
7029 run_test 56u "check lfs find -stripe-index works"
7030
7031 test_56v() {
7032         local mdt_idx=0
7033         local dir=$DIR/$tdir
7034
7035         setup_56 $dir $NUMFILES $NUMDIRS
7036
7037         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7038         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7039
7040         for file in $($LFS find -m $UUID $dir); do
7041                 file_midx=$($LFS getstripe -m $file)
7042                 [ $file_midx -eq $mdt_idx ] ||
7043                         error "lfs find -m $UUID != getstripe -m $file_midx"
7044         done
7045 }
7046 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7047
7048 test_56w() {
7049         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7051
7052         local dir=$DIR/$tdir
7053
7054         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7055
7056         local stripe_size=$($LFS getstripe -S -d $dir) ||
7057                 error "$LFS getstripe -S -d $dir failed"
7058         stripe_size=${stripe_size%% *}
7059
7060         local file_size=$((stripe_size * OSTCOUNT))
7061         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7062         local required_space=$((file_num * file_size))
7063         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7064                            head -n1)
7065         [[ $free_space -le $((required_space / 1024)) ]] &&
7066                 skip_env "need $required_space, have $free_space kbytes"
7067
7068         local dd_bs=65536
7069         local dd_count=$((file_size / dd_bs))
7070
7071         # write data into the files
7072         local i
7073         local j
7074         local file
7075
7076         for i in $(seq $NUMFILES); do
7077                 file=$dir/file$i
7078                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7079                         error "write data into $file failed"
7080         done
7081         for i in $(seq $NUMDIRS); do
7082                 for j in $(seq $NUMFILES); do
7083                         file=$dir/dir$i/file$j
7084                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7085                                 error "write data into $file failed"
7086                 done
7087         done
7088
7089         # $LFS_MIGRATE will fail if hard link migration is unsupported
7090         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7091                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7092                         error "creating links to $dir/dir1/file1 failed"
7093         fi
7094
7095         local expected=-1
7096
7097         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7098
7099         # lfs_migrate file
7100         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7101
7102         echo "$cmd"
7103         eval $cmd || error "$cmd failed"
7104
7105         check_stripe_count $dir/file1 $expected
7106
7107         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7108         then
7109                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7110                 # OST 1 if it is on OST 0. This file is small enough to
7111                 # be on only one stripe.
7112                 file=$dir/migr_1_ost
7113                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7114                         error "write data into $file failed"
7115                 local obdidx=$($LFS getstripe -i $file)
7116                 local oldmd5=$(md5sum $file)
7117                 local newobdidx=0
7118
7119                 [[ $obdidx -eq 0 ]] && newobdidx=1
7120                 cmd="$LFS migrate -i $newobdidx $file"
7121                 echo $cmd
7122                 eval $cmd || error "$cmd failed"
7123
7124                 local realobdix=$($LFS getstripe -i $file)
7125                 local newmd5=$(md5sum $file)
7126
7127                 [[ $newobdidx -ne $realobdix ]] &&
7128                         error "new OST is different (was=$obdidx, "\
7129                               "wanted=$newobdidx, got=$realobdix)"
7130                 [[ "$oldmd5" != "$newmd5" ]] &&
7131                         error "md5sum differ: $oldmd5, $newmd5"
7132         fi
7133
7134         # lfs_migrate dir
7135         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7136         echo "$cmd"
7137         eval $cmd || error "$cmd failed"
7138
7139         for j in $(seq $NUMFILES); do
7140                 check_stripe_count $dir/dir1/file$j $expected
7141         done
7142
7143         # lfs_migrate works with lfs find
7144         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7145              $LFS_MIGRATE -y -c $expected"
7146         echo "$cmd"
7147         eval $cmd || error "$cmd failed"
7148
7149         for i in $(seq 2 $NUMFILES); do
7150                 check_stripe_count $dir/file$i $expected
7151         done
7152         for i in $(seq 2 $NUMDIRS); do
7153                 for j in $(seq $NUMFILES); do
7154                 check_stripe_count $dir/dir$i/file$j $expected
7155                 done
7156         done
7157 }
7158 run_test 56w "check lfs_migrate -c stripe_count works"
7159
7160 test_56wb() {
7161         local file1=$DIR/$tdir/file1
7162         local create_pool=false
7163         local initial_pool=$($LFS getstripe -p $DIR)
7164         local pool_list=()
7165         local pool=""
7166
7167         echo -n "Creating test dir..."
7168         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7169         echo "done."
7170
7171         echo -n "Creating test file..."
7172         touch $file1 || error "cannot create file"
7173         echo "done."
7174
7175         echo -n "Detecting existing pools..."
7176         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7177
7178         if [ ${#pool_list[@]} -gt 0 ]; then
7179                 echo "${pool_list[@]}"
7180                 for thispool in "${pool_list[@]}"; do
7181                         if [[ -z "$initial_pool" ||
7182                               "$initial_pool" != "$thispool" ]]; then
7183                                 pool="$thispool"
7184                                 echo "Using existing pool '$pool'"
7185                                 break
7186                         fi
7187                 done
7188         else
7189                 echo "none detected."
7190         fi
7191         if [ -z "$pool" ]; then
7192                 pool=${POOL:-testpool}
7193                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7194                 echo -n "Creating pool '$pool'..."
7195                 create_pool=true
7196                 pool_add $pool &> /dev/null ||
7197                         error "pool_add failed"
7198                 echo "done."
7199
7200                 echo -n "Adding target to pool..."
7201                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7202                         error "pool_add_targets failed"
7203                 echo "done."
7204         fi
7205
7206         echo -n "Setting pool using -p option..."
7207         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7208                 error "migrate failed rc = $?"
7209         echo "done."
7210
7211         echo -n "Verifying test file is in pool after migrating..."
7212         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7213                 error "file was not migrated to pool $pool"
7214         echo "done."
7215
7216         echo -n "Removing test file from pool '$pool'..."
7217         # "lfs migrate $file" won't remove the file from the pool
7218         # until some striping information is changed.
7219         $LFS migrate -c 1 $file1 &> /dev/null ||
7220                 error "cannot remove from pool"
7221         [ "$($LFS getstripe -p $file1)" ] &&
7222                 error "pool still set"
7223         echo "done."
7224
7225         echo -n "Setting pool using --pool option..."
7226         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7227                 error "migrate failed rc = $?"
7228         echo "done."
7229
7230         # Clean up
7231         rm -f $file1
7232         if $create_pool; then
7233                 destroy_test_pools 2> /dev/null ||
7234                         error "destroy test pools failed"
7235         fi
7236 }
7237 run_test 56wb "check lfs_migrate pool support"
7238
7239 test_56wc() {
7240         local file1="$DIR/$tdir/file1"
7241         local parent_ssize
7242         local parent_scount
7243         local cur_ssize
7244         local cur_scount
7245         local orig_ssize
7246
7247         echo -n "Creating test dir..."
7248         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7249         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7250                 error "cannot set stripe by '-S 1M -c 1'"
7251         echo "done"
7252
7253         echo -n "Setting initial stripe for test file..."
7254         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7255                 error "cannot set stripe"
7256         cur_ssize=$($LFS getstripe -S "$file1")
7257         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7258         echo "done."
7259
7260         # File currently set to -S 512K -c 1
7261
7262         # Ensure -c and -S options are rejected when -R is set
7263         echo -n "Verifying incompatible options are detected..."
7264         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7265                 error "incompatible -c and -R options not detected"
7266         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7267                 error "incompatible -S and -R options not detected"
7268         echo "done."
7269
7270         # Ensure unrecognized options are passed through to 'lfs migrate'
7271         echo -n "Verifying -S option is passed through to lfs migrate..."
7272         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7273                 error "migration failed"
7274         cur_ssize=$($LFS getstripe -S "$file1")
7275         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7276         echo "done."
7277
7278         # File currently set to -S 1M -c 1
7279
7280         # Ensure long options are supported
7281         echo -n "Verifying long options supported..."
7282         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7283                 error "long option without argument not supported"
7284         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7285                 error "long option with argument not supported"
7286         cur_ssize=$($LFS getstripe -S "$file1")
7287         [ $cur_ssize -eq 524288 ] ||
7288                 error "migrate --stripe-size $cur_ssize != 524288"
7289         echo "done."
7290
7291         # File currently set to -S 512K -c 1
7292
7293         if [ "$OSTCOUNT" -gt 1 ]; then
7294                 echo -n "Verifying explicit stripe count can be set..."
7295                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7296                         error "migrate failed"
7297                 cur_scount=$($LFS getstripe -c "$file1")
7298                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7299                 echo "done."
7300         fi
7301
7302         # File currently set to -S 512K -c 1 or -S 512K -c 2
7303
7304         # Ensure parent striping is used if -R is set, and no stripe
7305         # count or size is specified
7306         echo -n "Setting stripe for parent directory..."
7307         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7308                 error "cannot set stripe '-S 2M -c 1'"
7309         echo "done."
7310
7311         echo -n "Verifying restripe option uses parent stripe settings..."
7312         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7313         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7314         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7315                 error "migrate failed"
7316         cur_ssize=$($LFS getstripe -S "$file1")
7317         [ $cur_ssize -eq $parent_ssize ] ||
7318                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7319         cur_scount=$($LFS getstripe -c "$file1")
7320         [ $cur_scount -eq $parent_scount ] ||
7321                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7322         echo "done."
7323
7324         # File currently set to -S 1M -c 1
7325
7326         # Ensure striping is preserved if -R is not set, and no stripe
7327         # count or size is specified
7328         echo -n "Verifying striping size preserved when not specified..."
7329         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7330         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7331                 error "cannot set stripe on parent directory"
7332         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7333                 error "migrate failed"
7334         cur_ssize=$($LFS getstripe -S "$file1")
7335         [ $cur_ssize -eq $orig_ssize ] ||
7336                 error "migrate by default $cur_ssize != $orig_ssize"
7337         echo "done."
7338
7339         # Ensure file name properly detected when final option has no argument
7340         echo -n "Verifying file name properly detected..."
7341         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7342                 error "file name interpreted as option argument"
7343         echo "done."
7344
7345         # Clean up
7346         rm -f "$file1"
7347 }
7348 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7349
7350 test_56wd() {
7351         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7352
7353         local file1=$DIR/$tdir/file1
7354
7355         echo -n "Creating test dir..."
7356         test_mkdir $DIR/$tdir || error "cannot create dir"
7357         echo "done."
7358
7359         echo -n "Creating test file..."
7360         touch $file1
7361         echo "done."
7362
7363         # Ensure 'lfs migrate' will fail by using a non-existent option,
7364         # and make sure rsync is not called to recover
7365         echo -n "Make sure --no-rsync option works..."
7366         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7367                 grep -q 'refusing to fall back to rsync' ||
7368                 error "rsync was called with --no-rsync set"
7369         echo "done."
7370
7371         # Ensure rsync is called without trying 'lfs migrate' first
7372         echo -n "Make sure --rsync option works..."
7373         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7374                 grep -q 'falling back to rsync' &&
7375                 error "lfs migrate was called with --rsync set"
7376         echo "done."
7377
7378         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7379         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7380                 grep -q 'at the same time' ||
7381                 error "--rsync and --no-rsync accepted concurrently"
7382         echo "done."
7383
7384         # Clean up
7385         rm -f $file1
7386 }
7387 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7388
7389 test_56we() {
7390         local td=$DIR/$tdir
7391         local tf=$td/$tfile
7392
7393         test_mkdir $td || error "cannot create $td"
7394         touch $tf || error "cannot touch $tf"
7395
7396         echo -n "Make sure --non-direct|-D works..."
7397         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7398                 grep -q "lfs migrate --non-direct" ||
7399                 error "--non-direct option cannot work correctly"
7400         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7401                 grep -q "lfs migrate -D" ||
7402                 error "-D option cannot work correctly"
7403         echo "done."
7404 }
7405 run_test 56we "check lfs_migrate --non-direct|-D support"
7406
7407 test_56x() {
7408         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7409         check_swap_layouts_support
7410
7411         local dir=$DIR/$tdir
7412         local ref1=/etc/passwd
7413         local file1=$dir/file1
7414
7415         test_mkdir $dir || error "creating dir $dir"
7416         $LFS setstripe -c 2 $file1
7417         cp $ref1 $file1
7418         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7419         stripe=$($LFS getstripe -c $file1)
7420         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7421         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7422
7423         # clean up
7424         rm -f $file1
7425 }
7426 run_test 56x "lfs migration support"
7427
7428 test_56xa() {
7429         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7430         check_swap_layouts_support
7431
7432         local dir=$DIR/$tdir/$testnum
7433
7434         test_mkdir -p $dir
7435
7436         local ref1=/etc/passwd
7437         local file1=$dir/file1
7438
7439         $LFS setstripe -c 2 $file1
7440         cp $ref1 $file1
7441         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7442
7443         local stripe=$($LFS getstripe -c $file1)
7444
7445         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7446         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7447
7448         # clean up
7449         rm -f $file1
7450 }
7451 run_test 56xa "lfs migration --block support"
7452
7453 check_migrate_links() {
7454         local dir="$1"
7455         local file1="$dir/file1"
7456         local begin="$2"
7457         local count="$3"
7458         local runas="$4"
7459         local total_count=$(($begin + $count - 1))
7460         local symlink_count=10
7461         local uniq_count=10
7462
7463         if [ ! -f "$file1" ]; then
7464                 echo -n "creating initial file..."
7465                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7466                         error "cannot setstripe initial file"
7467                 echo "done"
7468
7469                 echo -n "creating symlinks..."
7470                 for s in $(seq 1 $symlink_count); do
7471                         ln -s "$file1" "$dir/slink$s" ||
7472                                 error "cannot create symlinks"
7473                 done
7474                 echo "done"
7475
7476                 echo -n "creating nonlinked files..."
7477                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7478                         error "cannot create nonlinked files"
7479                 echo "done"
7480         fi
7481
7482         # create hard links
7483         if [ ! -f "$dir/file$total_count" ]; then
7484                 echo -n "creating hard links $begin:$total_count..."
7485                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7486                         /dev/null || error "cannot create hard links"
7487                 echo "done"
7488         fi
7489
7490         echo -n "checking number of hard links listed in xattrs..."
7491         local fid=$($LFS getstripe -F "$file1")
7492         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7493
7494         echo "${#paths[*]}"
7495         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7496                         skip "hard link list has unexpected size, skipping test"
7497         fi
7498         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7499                         error "link names should exceed xattrs size"
7500         fi
7501
7502         echo -n "migrating files..."
7503         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7504         local rc=$?
7505         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7506         echo "done"
7507
7508         # make sure all links have been properly migrated
7509         echo -n "verifying files..."
7510         fid=$($LFS getstripe -F "$file1") ||
7511                 error "cannot get fid for file $file1"
7512         for i in $(seq 2 $total_count); do
7513                 local fid2=$($LFS getstripe -F $dir/file$i)
7514
7515                 [ "$fid2" == "$fid" ] ||
7516                         error "migrated hard link has mismatched FID"
7517         done
7518
7519         # make sure hard links were properly detected, and migration was
7520         # performed only once for the entire link set; nonlinked files should
7521         # also be migrated
7522         local actual=$(grep -c 'done' <<< "$migrate_out")
7523         local expected=$(($uniq_count + 1))
7524
7525         [ "$actual" -eq  "$expected" ] ||
7526                 error "hard links individually migrated ($actual != $expected)"
7527
7528         # make sure the correct number of hard links are present
7529         local hardlinks=$(stat -c '%h' "$file1")
7530
7531         [ $hardlinks -eq $total_count ] ||
7532                 error "num hard links $hardlinks != $total_count"
7533         echo "done"
7534
7535         return 0
7536 }
7537
7538 test_56xb() {
7539         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7540                 skip "Need MDS version at least 2.10.55"
7541
7542         local dir="$DIR/$tdir"
7543
7544         test_mkdir "$dir" || error "cannot create dir $dir"
7545
7546         echo "testing lfs migrate mode when all links fit within xattrs"
7547         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7548
7549         echo "testing rsync mode when all links fit within xattrs"
7550         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7551
7552         echo "testing lfs migrate mode when all links do not fit within xattrs"
7553         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7554
7555         echo "testing rsync mode when all links do not fit within xattrs"
7556         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7557
7558         chown -R $RUNAS_ID $dir
7559         echo "testing non-root lfs migrate mode when not all links are in xattr"
7560         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7561
7562         # clean up
7563         rm -rf $dir
7564 }
7565 run_test 56xb "lfs migration hard link support"
7566
7567 test_56xc() {
7568         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7569
7570         local dir="$DIR/$tdir"
7571
7572         test_mkdir "$dir" || error "cannot create dir $dir"
7573
7574         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7575         echo -n "Setting initial stripe for 20MB test file..."
7576         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7577                 error "cannot setstripe 20MB file"
7578         echo "done"
7579         echo -n "Sizing 20MB test file..."
7580         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7581         echo "done"
7582         echo -n "Verifying small file autostripe count is 1..."
7583         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7584                 error "cannot migrate 20MB file"
7585         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7586                 error "cannot get stripe for $dir/20mb"
7587         [ $stripe_count -eq 1 ] ||
7588                 error "unexpected stripe count $stripe_count for 20MB file"
7589         rm -f "$dir/20mb"
7590         echo "done"
7591
7592         # Test 2: File is small enough to fit within the available space on
7593         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7594         # have at least an additional 1KB for each desired stripe for test 3
7595         echo -n "Setting stripe for 1GB test file..."
7596         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7597         echo "done"
7598         echo -n "Sizing 1GB test file..."
7599         # File size is 1GB + 3KB
7600         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7601         echo "done"
7602
7603         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7604         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7605         if (( avail > 524288 * OSTCOUNT )); then
7606                 echo -n "Migrating 1GB file..."
7607                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7608                         error "cannot migrate 1GB file"
7609                 echo "done"
7610                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7611                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7612                         error "cannot getstripe for 1GB file"
7613                 [ $stripe_count -eq 2 ] ||
7614                         error "unexpected stripe count $stripe_count != 2"
7615                 echo "done"
7616         fi
7617
7618         # Test 3: File is too large to fit within the available space on
7619         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7620         if [ $OSTCOUNT -ge 3 ]; then
7621                 # The required available space is calculated as
7622                 # file size (1GB + 3KB) / OST count (3).
7623                 local kb_per_ost=349526
7624
7625                 echo -n "Migrating 1GB file with limit..."
7626                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7627                         error "cannot migrate 1GB file with limit"
7628                 echo "done"
7629
7630                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7631                 echo -n "Verifying 1GB autostripe count with limited space..."
7632                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7633                         error "unexpected stripe count $stripe_count (min 3)"
7634                 echo "done"
7635         fi
7636
7637         # clean up
7638         rm -rf $dir
7639 }
7640 run_test 56xc "lfs migration autostripe"
7641
7642 test_56xd() {
7643         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7644
7645         local dir=$DIR/$tdir
7646         local f_mgrt=$dir/$tfile.mgrt
7647         local f_yaml=$dir/$tfile.yaml
7648         local f_copy=$dir/$tfile.copy
7649         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7650         local layout_copy="-c 2 -S 2M -i 1"
7651         local yamlfile=$dir/yamlfile
7652         local layout_before;
7653         local layout_after;
7654
7655         test_mkdir "$dir" || error "cannot create dir $dir"
7656         $LFS setstripe $layout_yaml $f_yaml ||
7657                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7658         $LFS getstripe --yaml $f_yaml > $yamlfile
7659         $LFS setstripe $layout_copy $f_copy ||
7660                 error "cannot setstripe $f_copy with layout $layout_copy"
7661         touch $f_mgrt
7662         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7663
7664         # 1. test option --yaml
7665         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7666                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7667         layout_before=$(get_layout_param $f_yaml)
7668         layout_after=$(get_layout_param $f_mgrt)
7669         [ "$layout_after" == "$layout_before" ] ||
7670                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7671
7672         # 2. test option --copy
7673         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7674                 error "cannot migrate $f_mgrt with --copy $f_copy"
7675         layout_before=$(get_layout_param $f_copy)
7676         layout_after=$(get_layout_param $f_mgrt)
7677         [ "$layout_after" == "$layout_before" ] ||
7678                 error "lfs_migrate --copy: $layout_after != $layout_before"
7679 }
7680 run_test 56xd "check lfs_migrate --yaml and --copy support"
7681
7682 test_56xe() {
7683         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7684
7685         local dir=$DIR/$tdir
7686         local f_comp=$dir/$tfile
7687         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7688         local layout_before=""
7689         local layout_after=""
7690
7691         test_mkdir "$dir" || error "cannot create dir $dir"
7692         $LFS setstripe $layout $f_comp ||
7693                 error "cannot setstripe $f_comp with layout $layout"
7694         layout_before=$(get_layout_param $f_comp)
7695         dd if=/dev/zero of=$f_comp bs=1M count=4
7696
7697         # 1. migrate a comp layout file by lfs_migrate
7698         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7699         layout_after=$(get_layout_param $f_comp)
7700         [ "$layout_before" == "$layout_after" ] ||
7701                 error "lfs_migrate: $layout_before != $layout_after"
7702
7703         # 2. migrate a comp layout file by lfs migrate
7704         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7705         layout_after=$(get_layout_param $f_comp)
7706         [ "$layout_before" == "$layout_after" ] ||
7707                 error "lfs migrate: $layout_before != $layout_after"
7708 }
7709 run_test 56xe "migrate a composite layout file"
7710
7711 test_56xf() {
7712         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7713
7714         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7715                 skip "Need server version at least 2.13.53"
7716
7717         local dir=$DIR/$tdir
7718         local f_comp=$dir/$tfile
7719         local layout="-E 1M -c1 -E -1 -c2"
7720         local fid_before=""
7721         local fid_after=""
7722
7723         test_mkdir "$dir" || error "cannot create dir $dir"
7724         $LFS setstripe $layout $f_comp ||
7725                 error "cannot setstripe $f_comp with layout $layout"
7726         fid_before=$($LFS getstripe --fid $f_comp)
7727         dd if=/dev/zero of=$f_comp bs=1M count=4
7728
7729         # 1. migrate a comp layout file to a comp layout
7730         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7731         fid_after=$($LFS getstripe --fid $f_comp)
7732         [ "$fid_before" == "$fid_after" ] ||
7733                 error "comp-to-comp migrate: $fid_before != $fid_after"
7734
7735         # 2. migrate a comp layout file to a plain layout
7736         $LFS migrate -c2 $f_comp ||
7737                 error "cannot migrate $f_comp by lfs migrate"
7738         fid_after=$($LFS getstripe --fid $f_comp)
7739         [ "$fid_before" == "$fid_after" ] ||
7740                 error "comp-to-plain migrate: $fid_before != $fid_after"
7741
7742         # 3. migrate a plain layout file to a comp layout
7743         $LFS migrate $layout $f_comp ||
7744                 error "cannot migrate $f_comp by lfs migrate"
7745         fid_after=$($LFS getstripe --fid $f_comp)
7746         [ "$fid_before" == "$fid_after" ] ||
7747                 error "plain-to-comp migrate: $fid_before != $fid_after"
7748 }
7749 run_test 56xf "FID is not lost during migration of a composite layout file"
7750
7751 check_file_ost_range() {
7752         local file="$1"
7753         shift
7754         local range="$*"
7755         local -a file_range
7756         local idx
7757
7758         file_range=($($LFS getstripe -y "$file" |
7759                 awk '/l_ost_idx:/ { print $NF }'))
7760
7761         if [[ "${#file_range[@]}" = 0 ]]; then
7762                 echo "No osts found for $file"
7763                 return 1
7764         fi
7765
7766         for idx in "${file_range[@]}"; do
7767                 [[ " $range " =~ " $idx " ]] ||
7768                         return 1
7769         done
7770
7771         return 0
7772 }
7773
7774 sub_test_56xg() {
7775         local stripe_opt="$1"
7776         local pool="$2"
7777         shift 2
7778         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7779
7780         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7781                 error "Fail to migrate $tfile on $pool"
7782         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7783                 error "$tfile is not in pool $pool"
7784         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7785                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7786 }
7787
7788 test_56xg() {
7789         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7790         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7791         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7792                 skip "Need MDS version newer than 2.14.52"
7793
7794         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7795         local -a pool_ranges=("0 0" "1 1" "0 1")
7796
7797         # init pools
7798         for i in "${!pool_names[@]}"; do
7799                 pool_add ${pool_names[$i]} ||
7800                         error "pool_add failed (pool: ${pool_names[$i]})"
7801                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7802                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7803         done
7804
7805         # init the file to migrate
7806         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7807                 error "Unable to create $tfile on OST1"
7808         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7809                 error "Unable to write on $tfile"
7810
7811         echo "1. migrate $tfile on pool ${pool_names[0]}"
7812         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7813
7814         echo "2. migrate $tfile on pool ${pool_names[2]}"
7815         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7816
7817         echo "3. migrate $tfile on pool ${pool_names[1]}"
7818         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7819
7820         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7821         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7822         echo
7823
7824         # Clean pools
7825         destroy_test_pools ||
7826                 error "pool_destroy failed"
7827 }
7828 run_test 56xg "lfs migrate pool support"
7829
7830 test_56y() {
7831         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7832                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7833
7834         local res=""
7835         local dir=$DIR/$tdir
7836         local f1=$dir/file1
7837         local f2=$dir/file2
7838
7839         test_mkdir -p $dir || error "creating dir $dir"
7840         touch $f1 || error "creating std file $f1"
7841         $MULTIOP $f2 H2c || error "creating released file $f2"
7842
7843         # a directory can be raid0, so ask only for files
7844         res=$($LFS find $dir -L raid0 -type f | wc -l)
7845         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7846
7847         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7848         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7849
7850         # only files can be released, so no need to force file search
7851         res=$($LFS find $dir -L released)
7852         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7853
7854         res=$($LFS find $dir -type f \! -L released)
7855         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7856 }
7857 run_test 56y "lfs find -L raid0|released"
7858
7859 test_56z() { # LU-4824
7860         # This checks to make sure 'lfs find' continues after errors
7861         # There are two classes of errors that should be caught:
7862         # - If multiple paths are provided, all should be searched even if one
7863         #   errors out
7864         # - If errors are encountered during the search, it should not terminate
7865         #   early
7866         local dir=$DIR/$tdir
7867         local i
7868
7869         test_mkdir $dir
7870         for i in d{0..9}; do
7871                 test_mkdir $dir/$i
7872                 touch $dir/$i/$tfile
7873         done
7874         $LFS find $DIR/non_existent_dir $dir &&
7875                 error "$LFS find did not return an error"
7876         # Make a directory unsearchable. This should NOT be the last entry in
7877         # directory order.  Arbitrarily pick the 6th entry
7878         chmod 700 $($LFS find $dir -type d | sed '6!d')
7879
7880         $RUNAS $LFS find $DIR/non_existent $dir
7881         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7882
7883         # The user should be able to see 10 directories and 9 files
7884         (( count == 19 )) ||
7885                 error "$LFS find found $count != 19 entries after error"
7886 }
7887 run_test 56z "lfs find should continue after an error"
7888
7889 test_56aa() { # LU-5937
7890         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7891
7892         local dir=$DIR/$tdir
7893
7894         mkdir $dir
7895         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7896
7897         createmany -o $dir/striped_dir/${tfile}- 1024
7898         local dirs=$($LFS find --size +8k $dir/)
7899
7900         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7901 }
7902 run_test 56aa "lfs find --size under striped dir"
7903
7904 test_56ab() { # LU-10705
7905         test_mkdir $DIR/$tdir
7906         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7907         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7908         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7909         # Flush writes to ensure valid blocks.  Need to be more thorough for
7910         # ZFS, since blocks are not allocated/returned to client immediately.
7911         sync_all_data
7912         wait_zfs_commit ost1 2
7913         cancel_lru_locks osc
7914         ls -ls $DIR/$tdir
7915
7916         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7917
7918         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7919
7920         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7921         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7922
7923         rm -f $DIR/$tdir/$tfile.[123]
7924 }
7925 run_test 56ab "lfs find --blocks"
7926
7927 # LU-11188
7928 test_56aca() {
7929         local dir="$DIR/$tdir"
7930         local perms=(001 002 003 004 005 006 007
7931                      010 020 030 040 050 060 070
7932                      100 200 300 400 500 600 700
7933                      111 222 333 444 555 666 777)
7934         local perm_minus=(8 8 4 8 4 4 2
7935                           8 8 4 8 4 4 2
7936                           8 8 4 8 4 4 2
7937                           4 4 2 4 2 2 1)
7938         local perm_slash=(8  8 12  8 12 12 14
7939                           8  8 12  8 12 12 14
7940                           8  8 12  8 12 12 14
7941                          16 16 24 16 24 24 28)
7942
7943         test_mkdir "$dir"
7944         for perm in ${perms[*]}; do
7945                 touch "$dir/$tfile.$perm"
7946                 chmod $perm "$dir/$tfile.$perm"
7947         done
7948
7949         for ((i = 0; i < ${#perms[*]}; i++)); do
7950                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7951                 (( $num == 1 )) ||
7952                         error "lfs find -perm ${perms[i]}:"\
7953                               "$num != 1"
7954
7955                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7956                 (( $num == ${perm_minus[i]} )) ||
7957                         error "lfs find -perm -${perms[i]}:"\
7958                               "$num != ${perm_minus[i]}"
7959
7960                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7961                 (( $num == ${perm_slash[i]} )) ||
7962                         error "lfs find -perm /${perms[i]}:"\
7963                               "$num != ${perm_slash[i]}"
7964         done
7965 }
7966 run_test 56aca "check lfs find -perm with octal representation"
7967
7968 test_56acb() {
7969         local dir=$DIR/$tdir
7970         # p is the permission of write and execute for user, group and other
7971         # without the umask. It is used to test +wx.
7972         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7973         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7974         local symbolic=(+t  a+t u+t g+t o+t
7975                         g+s u+s o+s +s o+sr
7976                         o=r,ug+o,u+w
7977                         u+ g+ o+ a+ ugo+
7978                         u- g- o- a- ugo-
7979                         u= g= o= a= ugo=
7980                         o=r,ug+o,u+w u=r,a+u,u+w
7981                         g=r,ugo=g,u+w u+x,+X +X
7982                         u+x,u+X u+X u+x,g+X o+r,+X
7983                         u+x,go+X +wx +rwx)
7984
7985         test_mkdir $dir
7986         for perm in ${perms[*]}; do
7987                 touch "$dir/$tfile.$perm"
7988                 chmod $perm "$dir/$tfile.$perm"
7989         done
7990
7991         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7992                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7993
7994                 (( $num == 1 )) ||
7995                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7996         done
7997 }
7998 run_test 56acb "check lfs find -perm with symbolic representation"
7999
8000 test_56acc() {
8001         local dir=$DIR/$tdir
8002         local tests="17777 787 789 abcd
8003                 ug=uu ug=a ug=gu uo=ou urw
8004                 u+xg+x a=r,u+x,"
8005
8006         test_mkdir $dir
8007         for err in $tests; do
8008                 if $LFS find $dir -perm $err 2>/dev/null; then
8009                         error "lfs find -perm $err: parsing should have failed"
8010                 fi
8011         done
8012 }
8013 run_test 56acc "check parsing error for lfs find -perm"
8014
8015 test_56ba() {
8016         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8017                 skip "Need MDS version at least 2.10.50"
8018
8019         # Create composite files with one component
8020         local dir=$DIR/$tdir
8021
8022         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8023         # Create composite files with three components
8024         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8025         # Create non-composite files
8026         createmany -o $dir/${tfile}- 10
8027
8028         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8029
8030         [[ $nfiles == 10 ]] ||
8031                 error "lfs find -E 1M found $nfiles != 10 files"
8032
8033         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8034         [[ $nfiles == 25 ]] ||
8035                 error "lfs find ! -E 1M found $nfiles != 25 files"
8036
8037         # All files have a component that starts at 0
8038         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8039         [[ $nfiles == 35 ]] ||
8040                 error "lfs find --component-start 0 - $nfiles != 35 files"
8041
8042         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8043         [[ $nfiles == 15 ]] ||
8044                 error "lfs find --component-start 2M - $nfiles != 15 files"
8045
8046         # All files created here have a componenet that does not starts at 2M
8047         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8048         [[ $nfiles == 35 ]] ||
8049                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8050
8051         # Find files with a specified number of components
8052         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8053         [[ $nfiles == 15 ]] ||
8054                 error "lfs find --component-count 3 - $nfiles != 15 files"
8055
8056         # Remember non-composite files have a component count of zero
8057         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8058         [[ $nfiles == 10 ]] ||
8059                 error "lfs find --component-count 0 - $nfiles != 10 files"
8060
8061         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8062         [[ $nfiles == 20 ]] ||
8063                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8064
8065         # All files have a flag called "init"
8066         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8067         [[ $nfiles == 35 ]] ||
8068                 error "lfs find --component-flags init - $nfiles != 35 files"
8069
8070         # Multi-component files will have a component not initialized
8071         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8072         [[ $nfiles == 15 ]] ||
8073                 error "lfs find !--component-flags init - $nfiles != 15 files"
8074
8075         rm -rf $dir
8076
8077 }
8078 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8079
8080 test_56ca() {
8081         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8082                 skip "Need MDS version at least 2.10.57"
8083
8084         local td=$DIR/$tdir
8085         local tf=$td/$tfile
8086         local dir
8087         local nfiles
8088         local cmd
8089         local i
8090         local j
8091
8092         # create mirrored directories and mirrored files
8093         mkdir $td || error "mkdir $td failed"
8094         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8095         createmany -o $tf- 10 || error "create $tf- failed"
8096
8097         for i in $(seq 2); do
8098                 dir=$td/dir$i
8099                 mkdir $dir || error "mkdir $dir failed"
8100                 $LFS mirror create -N$((3 + i)) $dir ||
8101                         error "create mirrored dir $dir failed"
8102                 createmany -o $dir/$tfile- 10 ||
8103                         error "create $dir/$tfile- failed"
8104         done
8105
8106         # change the states of some mirrored files
8107         echo foo > $tf-6
8108         for i in $(seq 2); do
8109                 dir=$td/dir$i
8110                 for j in $(seq 4 9); do
8111                         echo foo > $dir/$tfile-$j
8112                 done
8113         done
8114
8115         # find mirrored files with specific mirror count
8116         cmd="$LFS find --mirror-count 3 --type f $td"
8117         nfiles=$($cmd | wc -l)
8118         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8119
8120         cmd="$LFS find ! --mirror-count 3 --type f $td"
8121         nfiles=$($cmd | wc -l)
8122         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8123
8124         cmd="$LFS find --mirror-count +2 --type f $td"
8125         nfiles=$($cmd | wc -l)
8126         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8127
8128         cmd="$LFS find --mirror-count -6 --type f $td"
8129         nfiles=$($cmd | wc -l)
8130         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8131
8132         # find mirrored files with specific file state
8133         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8134         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8135
8136         cmd="$LFS find --mirror-state=ro --type f $td"
8137         nfiles=$($cmd | wc -l)
8138         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8139
8140         cmd="$LFS find ! --mirror-state=ro --type f $td"
8141         nfiles=$($cmd | wc -l)
8142         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8143
8144         cmd="$LFS find --mirror-state=wp --type f $td"
8145         nfiles=$($cmd | wc -l)
8146         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8147
8148         cmd="$LFS find ! --mirror-state=sp --type f $td"
8149         nfiles=$($cmd | wc -l)
8150         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8151 }
8152 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8153
8154 test_56da() { # LU-14179
8155         local path=$DIR/$tdir
8156
8157         test_mkdir $path
8158         cd $path
8159
8160         local longdir=$(str_repeat 'a' 255)
8161
8162         for i in {1..15}; do
8163                 path=$path/$longdir
8164                 test_mkdir $longdir
8165                 cd $longdir
8166         done
8167
8168         local len=${#path}
8169         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8170
8171         test_mkdir $lastdir
8172         cd $lastdir
8173         # PATH_MAX-1
8174         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8175
8176         # NAME_MAX
8177         touch $(str_repeat 'f' 255)
8178
8179         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8180                 error "lfs find reported an error"
8181
8182         rm -rf $DIR/$tdir
8183 }
8184 run_test 56da "test lfs find with long paths"
8185
8186 test_56ea() { #LU-10378
8187         local path=$DIR/$tdir
8188         local pool=$TESTNAME
8189
8190         # Create ost pool
8191         pool_add $pool || error "pool_add $pool failed"
8192         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8193                 error "adding targets to $pool failed"
8194
8195         # Set default pool on directory before creating file
8196         mkdir $path || error "mkdir $path failed"
8197         $LFS setstripe -p $pool $path ||
8198                 error "set OST pool on $pool failed"
8199         touch $path/$tfile || error "touch $path/$tfile failed"
8200
8201         # Compare basic file attributes from -printf and stat
8202         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8203         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8204
8205         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8206                 error "Attrs from lfs find and stat don't match"
8207
8208         # Compare Lustre attributes from lfs find and lfs getstripe
8209         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8210         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8211         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8212         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8213         local fpool=$($LFS getstripe --pool $path/$tfile)
8214         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8215
8216         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8217                 error "Attrs from lfs find and lfs getstripe don't match"
8218
8219         # Verify behavior for unknown escape/format sequences
8220         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8221
8222         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8223                 error "Escape/format codes don't match"
8224 }
8225 run_test 56ea "test lfs find -printf option"
8226
8227 test_57a() {
8228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8229         # note test will not do anything if MDS is not local
8230         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8231                 skip_env "ldiskfs only test"
8232         fi
8233         remote_mds_nodsh && skip "remote MDS with nodsh"
8234
8235         local MNTDEV="osd*.*MDT*.mntdev"
8236         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8237         [ -z "$DEV" ] && error "can't access $MNTDEV"
8238         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8239                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8240                         error "can't access $DEV"
8241                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8242                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8243                 rm $TMP/t57a.dump
8244         done
8245 }
8246 run_test 57a "verify MDS filesystem created with large inodes =="
8247
8248 test_57b() {
8249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8250         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8251                 skip_env "ldiskfs only test"
8252         fi
8253         remote_mds_nodsh && skip "remote MDS with nodsh"
8254
8255         local dir=$DIR/$tdir
8256         local filecount=100
8257         local file1=$dir/f1
8258         local fileN=$dir/f$filecount
8259
8260         rm -rf $dir || error "removing $dir"
8261         test_mkdir -c1 $dir
8262         local mdtidx=$($LFS getstripe -m $dir)
8263         local mdtname=MDT$(printf %04x $mdtidx)
8264         local facet=mds$((mdtidx + 1))
8265
8266         echo "mcreating $filecount files"
8267         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8268
8269         # verify that files do not have EAs yet
8270         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8271                 error "$file1 has an EA"
8272         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8273                 error "$fileN has an EA"
8274
8275         sync
8276         sleep 1
8277         df $dir  #make sure we get new statfs data
8278         local mdsfree=$(do_facet $facet \
8279                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8280         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8281         local file
8282
8283         echo "opening files to create objects/EAs"
8284         for file in $(seq -f $dir/f%g 1 $filecount); do
8285                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8286                         error "opening $file"
8287         done
8288
8289         # verify that files have EAs now
8290         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8291         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8292
8293         sleep 1  #make sure we get new statfs data
8294         df $dir
8295         local mdsfree2=$(do_facet $facet \
8296                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8297         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8298
8299         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8300                 if [ "$mdsfree" != "$mdsfree2" ]; then
8301                         error "MDC before $mdcfree != after $mdcfree2"
8302                 else
8303                         echo "MDC before $mdcfree != after $mdcfree2"
8304                         echo "unable to confirm if MDS has large inodes"
8305                 fi
8306         fi
8307         rm -rf $dir
8308 }
8309 run_test 57b "default LOV EAs are stored inside large inodes ==="
8310
8311 test_58() {
8312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8313         [ -z "$(which wiretest 2>/dev/null)" ] &&
8314                         skip_env "could not find wiretest"
8315
8316         wiretest
8317 }
8318 run_test 58 "verify cross-platform wire constants =============="
8319
8320 test_59() {
8321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8322
8323         echo "touch 130 files"
8324         createmany -o $DIR/f59- 130
8325         echo "rm 130 files"
8326         unlinkmany $DIR/f59- 130
8327         sync
8328         # wait for commitment of removal
8329         wait_delete_completed
8330 }
8331 run_test 59 "verify cancellation of llog records async ========="
8332
8333 TEST60_HEAD="test_60 run $RANDOM"
8334 test_60a() {
8335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8336         remote_mgs_nodsh && skip "remote MGS with nodsh"
8337         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8338                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8339                         skip_env "missing subtest run-llog.sh"
8340
8341         log "$TEST60_HEAD - from kernel mode"
8342         do_facet mgs "$LCTL dk > /dev/null"
8343         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8344         do_facet mgs $LCTL dk > $TMP/$tfile
8345
8346         # LU-6388: test llog_reader
8347         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8348         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8349         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8350                         skip_env "missing llog_reader"
8351         local fstype=$(facet_fstype mgs)
8352         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8353                 skip_env "Only for ldiskfs or zfs type mgs"
8354
8355         local mntpt=$(facet_mntpt mgs)
8356         local mgsdev=$(mgsdevname 1)
8357         local fid_list
8358         local fid
8359         local rec_list
8360         local rec
8361         local rec_type
8362         local obj_file
8363         local path
8364         local seq
8365         local oid
8366         local pass=true
8367
8368         #get fid and record list
8369         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8370                 tail -n 4))
8371         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8372                 tail -n 4))
8373         #remount mgs as ldiskfs or zfs type
8374         stop mgs || error "stop mgs failed"
8375         mount_fstype mgs || error "remount mgs failed"
8376         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8377                 fid=${fid_list[i]}
8378                 rec=${rec_list[i]}
8379                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8380                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8381                 oid=$((16#$oid))
8382
8383                 case $fstype in
8384                         ldiskfs )
8385                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8386                         zfs )
8387                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8388                 esac
8389                 echo "obj_file is $obj_file"
8390                 do_facet mgs $llog_reader $obj_file
8391
8392                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8393                         awk '{ print $3 }' | sed -e "s/^type=//g")
8394                 if [ $rec_type != $rec ]; then
8395                         echo "FAILED test_60a wrong record type $rec_type," \
8396                               "should be $rec"
8397                         pass=false
8398                         break
8399                 fi
8400
8401                 #check obj path if record type is LLOG_LOGID_MAGIC
8402                 if [ "$rec" == "1064553b" ]; then
8403                         path=$(do_facet mgs $llog_reader $obj_file |
8404                                 grep "path=" | awk '{ print $NF }' |
8405                                 sed -e "s/^path=//g")
8406                         if [ $obj_file != $mntpt/$path ]; then
8407                                 echo "FAILED test_60a wrong obj path" \
8408                                       "$montpt/$path, should be $obj_file"
8409                                 pass=false
8410                                 break
8411                         fi
8412                 fi
8413         done
8414         rm -f $TMP/$tfile
8415         #restart mgs before "error", otherwise it will block the next test
8416         stop mgs || error "stop mgs failed"
8417         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8418         $pass || error "test failed, see FAILED test_60a messages for specifics"
8419 }
8420 run_test 60a "llog_test run from kernel module and test llog_reader"
8421
8422 test_60b() { # bug 6411
8423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8424
8425         dmesg > $DIR/$tfile
8426         LLOG_COUNT=$(do_facet mgs dmesg |
8427                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8428                           /llog_[a-z]*.c:[0-9]/ {
8429                                 if (marker)
8430                                         from_marker++
8431                                 from_begin++
8432                           }
8433                           END {
8434                                 if (marker)
8435                                         print from_marker
8436                                 else
8437                                         print from_begin
8438                           }")
8439
8440         [[ $LLOG_COUNT -gt 120 ]] &&
8441                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8442 }
8443 run_test 60b "limit repeated messages from CERROR/CWARN"
8444
8445 test_60c() {
8446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8447
8448         echo "create 5000 files"
8449         createmany -o $DIR/f60c- 5000
8450 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8451         lctl set_param fail_loc=0x80000137
8452         unlinkmany $DIR/f60c- 5000
8453         lctl set_param fail_loc=0
8454 }
8455 run_test 60c "unlink file when mds full"
8456
8457 test_60d() {
8458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8459
8460         SAVEPRINTK=$(lctl get_param -n printk)
8461         # verify "lctl mark" is even working"
8462         MESSAGE="test message ID $RANDOM $$"
8463         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8464         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8465
8466         lctl set_param printk=0 || error "set lnet.printk failed"
8467         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8468         MESSAGE="new test message ID $RANDOM $$"
8469         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8470         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8471         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8472
8473         lctl set_param -n printk="$SAVEPRINTK"
8474 }
8475 run_test 60d "test printk console message masking"
8476
8477 test_60e() {
8478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8479         remote_mds_nodsh && skip "remote MDS with nodsh"
8480
8481         touch $DIR/$tfile
8482 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8483         do_facet mds1 lctl set_param fail_loc=0x15b
8484         rm $DIR/$tfile
8485 }
8486 run_test 60e "no space while new llog is being created"
8487
8488 test_60f() {
8489         local old_path=$($LCTL get_param -n debug_path)
8490
8491         stack_trap "$LCTL set_param debug_path=$old_path"
8492         stack_trap "rm -f $TMP/$tfile*"
8493         rm -f $TMP/$tfile* 2> /dev/null
8494         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8495         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8496         test_mkdir $DIR/$tdir
8497         # retry in case the open is cached and not released
8498         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8499                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8500                 sleep 0.1
8501         done
8502         ls $TMP/$tfile*
8503         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8504 }
8505 run_test 60f "change debug_path works"
8506
8507 test_60g() {
8508         local pid
8509         local i
8510
8511         test_mkdir -c $MDSCOUNT $DIR/$tdir
8512
8513         (
8514                 local index=0
8515                 while true; do
8516                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8517                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8518                                 2>/dev/null
8519                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8520                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8521                         index=$((index + 1))
8522                 done
8523         ) &
8524
8525         pid=$!
8526
8527         for i in {0..100}; do
8528                 # define OBD_FAIL_OSD_TXN_START    0x19a
8529                 local index=$((i % MDSCOUNT + 1))
8530
8531                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8532                         > /dev/null
8533                 sleep 0.01
8534         done
8535
8536         kill -9 $pid
8537
8538         for i in $(seq $MDSCOUNT); do
8539                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8540         done
8541
8542         mkdir $DIR/$tdir/new || error "mkdir failed"
8543         rmdir $DIR/$tdir/new || error "rmdir failed"
8544
8545         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8546                 -t namespace
8547         for i in $(seq $MDSCOUNT); do
8548                 wait_update_facet mds$i "$LCTL get_param -n \
8549                         mdd.$(facet_svc mds$i).lfsck_namespace |
8550                         awk '/^status/ { print \\\$2 }'" "completed"
8551         done
8552
8553         ls -R $DIR/$tdir
8554         rm -rf $DIR/$tdir || error "rmdir failed"
8555 }
8556 run_test 60g "transaction abort won't cause MDT hung"
8557
8558 test_60h() {
8559         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8560                 skip "Need MDS version at least 2.12.52"
8561         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8562
8563         local f
8564
8565         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8566         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8567         for fail_loc in 0x80000188 0x80000189; do
8568                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8569                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8570                         error "mkdir $dir-$fail_loc failed"
8571                 for i in {0..10}; do
8572                         # create may fail on missing stripe
8573                         echo $i > $DIR/$tdir-$fail_loc/$i
8574                 done
8575                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8576                         error "getdirstripe $tdir-$fail_loc failed"
8577                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8578                         error "migrate $tdir-$fail_loc failed"
8579                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8580                         error "getdirstripe $tdir-$fail_loc failed"
8581                 pushd $DIR/$tdir-$fail_loc
8582                 for f in *; do
8583                         echo $f | cmp $f - || error "$f data mismatch"
8584                 done
8585                 popd
8586                 rm -rf $DIR/$tdir-$fail_loc
8587         done
8588 }
8589 run_test 60h "striped directory with missing stripes can be accessed"
8590
8591 function t60i_load() {
8592         mkdir $DIR/$tdir
8593         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8594         $LCTL set_param fail_loc=0x131c fail_val=1
8595         for ((i=0; i<5000; i++)); do
8596                 touch $DIR/$tdir/f$i
8597         done
8598 }
8599
8600 test_60i() {
8601         changelog_register || error "changelog_register failed"
8602         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8603         changelog_users $SINGLEMDS | grep -q $cl_user ||
8604                 error "User $cl_user not found in changelog_users"
8605         changelog_chmask "ALL"
8606         t60i_load &
8607         local PID=$!
8608         for((i=0; i<100; i++)); do
8609                 changelog_dump >/dev/null ||
8610                         error "can't read changelog"
8611         done
8612         kill $PID
8613         wait $PID
8614         changelog_deregister || error "changelog_deregister failed"
8615         $LCTL set_param fail_loc=0
8616 }
8617 run_test 60i "llog: new record vs reader race"
8618
8619 test_61a() {
8620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8621
8622         f="$DIR/f61"
8623         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8624         cancel_lru_locks osc
8625         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8626         sync
8627 }
8628 run_test 61a "mmap() writes don't make sync hang ================"
8629
8630 test_61b() {
8631         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8632 }
8633 run_test 61b "mmap() of unstriped file is successful"
8634
8635 # bug 2330 - insufficient obd_match error checking causes LBUG
8636 test_62() {
8637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8638
8639         f="$DIR/f62"
8640         echo foo > $f
8641         cancel_lru_locks osc
8642         lctl set_param fail_loc=0x405
8643         cat $f && error "cat succeeded, expect -EIO"
8644         lctl set_param fail_loc=0
8645 }
8646 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8647 # match every page all of the time.
8648 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8649
8650 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8651 # Though this test is irrelevant anymore, it helped to reveal some
8652 # other grant bugs (LU-4482), let's keep it.
8653 test_63a() {   # was test_63
8654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8655
8656         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8657
8658         for i in `seq 10` ; do
8659                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8660                 sleep 5
8661                 kill $!
8662                 sleep 1
8663         done
8664
8665         rm -f $DIR/f63 || true
8666 }
8667 run_test 63a "Verify oig_wait interruption does not crash ======="
8668
8669 # bug 2248 - async write errors didn't return to application on sync
8670 # bug 3677 - async write errors left page locked
8671 test_63b() {
8672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8673
8674         debugsave
8675         lctl set_param debug=-1
8676
8677         # ensure we have a grant to do async writes
8678         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8679         rm $DIR/$tfile
8680
8681         sync    # sync lest earlier test intercept the fail_loc
8682
8683         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8684         lctl set_param fail_loc=0x80000406
8685         $MULTIOP $DIR/$tfile Owy && \
8686                 error "sync didn't return ENOMEM"
8687         sync; sleep 2; sync     # do a real sync this time to flush page
8688         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8689                 error "locked page left in cache after async error" || true
8690         debugrestore
8691 }
8692 run_test 63b "async write errors should be returned to fsync ==="
8693
8694 test_64a () {
8695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8696
8697         lfs df $DIR
8698         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8699 }
8700 run_test 64a "verify filter grant calculations (in kernel) ====="
8701
8702 test_64b () {
8703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8704
8705         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8706 }
8707 run_test 64b "check out-of-space detection on client"
8708
8709 test_64c() {
8710         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8711 }
8712 run_test 64c "verify grant shrink"
8713
8714 import_param() {
8715         local tgt=$1
8716         local param=$2
8717
8718         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8719 }
8720
8721 # this does exactly what osc_request.c:osc_announce_cached() does in
8722 # order to calculate max amount of grants to ask from server
8723 want_grant() {
8724         local tgt=$1
8725
8726         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8727         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8728
8729         ((rpc_in_flight++));
8730         nrpages=$((nrpages * rpc_in_flight))
8731
8732         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8733
8734         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8735
8736         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8737         local undirty=$((nrpages * PAGE_SIZE))
8738
8739         local max_extent_pages
8740         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8741         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8742         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8743         local grant_extent_tax
8744         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8745
8746         undirty=$((undirty + nrextents * grant_extent_tax))
8747
8748         echo $undirty
8749 }
8750
8751 # this is size of unit for grant allocation. It should be equal to
8752 # what tgt_grant.c:tgt_grant_chunk() calculates
8753 grant_chunk() {
8754         local tgt=$1
8755         local max_brw_size
8756         local grant_extent_tax
8757
8758         max_brw_size=$(import_param $tgt max_brw_size)
8759
8760         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8761
8762         echo $(((max_brw_size + grant_extent_tax) * 2))
8763 }
8764
8765 test_64d() {
8766         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8767                 skip "OST < 2.10.55 doesn't limit grants enough"
8768
8769         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8770
8771         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8772                 skip "no grant_param connect flag"
8773
8774         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8775
8776         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8777         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8778
8779
8780         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8781         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8782
8783         $LFS setstripe $DIR/$tfile -i 0 -c 1
8784         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8785         ddpid=$!
8786
8787         while kill -0 $ddpid; do
8788                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8789
8790                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8791                         kill $ddpid
8792                         error "cur_grant $cur_grant > $max_cur_granted"
8793                 fi
8794
8795                 sleep 1
8796         done
8797 }
8798 run_test 64d "check grant limit exceed"
8799
8800 check_grants() {
8801         local tgt=$1
8802         local expected=$2
8803         local msg=$3
8804         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8805
8806         ((cur_grants == expected)) ||
8807                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8808 }
8809
8810 round_up_p2() {
8811         echo $((($1 + $2 - 1) & ~($2 - 1)))
8812 }
8813
8814 test_64e() {
8815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8816         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8817                 skip "Need OSS version at least 2.11.56"
8818
8819         # Remount client to reset grant
8820         remount_client $MOUNT || error "failed to remount client"
8821         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8822
8823         local init_grants=$(import_param $osc_tgt initial_grant)
8824
8825         check_grants $osc_tgt $init_grants "init grants"
8826
8827         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8828         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8829         local gbs=$(import_param $osc_tgt grant_block_size)
8830
8831         # write random number of bytes from max_brw_size / 4 to max_brw_size
8832         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8833         # align for direct io
8834         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8835         # round to grant consumption unit
8836         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8837
8838         local grants=$((wb_round_up + extent_tax))
8839
8840         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8841
8842         # define OBD_FAIL_TGT_NO_GRANT 0x725
8843         # make the server not grant more back
8844         do_facet ost1 $LCTL set_param fail_loc=0x725
8845         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8846
8847         do_facet ost1 $LCTL set_param fail_loc=0
8848
8849         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8850
8851         rm -f $DIR/$tfile || error "rm failed"
8852
8853         # Remount client to reset grant
8854         remount_client $MOUNT || error "failed to remount client"
8855         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8856
8857         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8858
8859         # define OBD_FAIL_TGT_NO_GRANT 0x725
8860         # make the server not grant more back
8861         do_facet ost1 $LCTL set_param fail_loc=0x725
8862         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8863         do_facet ost1 $LCTL set_param fail_loc=0
8864
8865         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8866 }
8867 run_test 64e "check grant consumption (no grant allocation)"
8868
8869 test_64f() {
8870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8871
8872         # Remount client to reset grant
8873         remount_client $MOUNT || error "failed to remount client"
8874         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8875
8876         local init_grants=$(import_param $osc_tgt initial_grant)
8877         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8878         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8879         local gbs=$(import_param $osc_tgt grant_block_size)
8880         local chunk=$(grant_chunk $osc_tgt)
8881
8882         # write random number of bytes from max_brw_size / 4 to max_brw_size
8883         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8884         # align for direct io
8885         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8886         # round to grant consumption unit
8887         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8888
8889         local grants=$((wb_round_up + extent_tax))
8890
8891         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8892         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8893                 error "error writing to $DIR/$tfile"
8894
8895         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8896                 "direct io with grant allocation"
8897
8898         rm -f $DIR/$tfile || error "rm failed"
8899
8900         # Remount client to reset grant
8901         remount_client $MOUNT || error "failed to remount client"
8902         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8903
8904         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8905
8906         local cmd="oO_WRONLY:w${write_bytes}_yc"
8907
8908         $MULTIOP $DIR/$tfile $cmd &
8909         MULTIPID=$!
8910         sleep 1
8911
8912         check_grants $osc_tgt $((init_grants - grants)) \
8913                 "buffered io, not write rpc"
8914
8915         kill -USR1 $MULTIPID
8916         wait
8917
8918         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8919                 "buffered io, one RPC"
8920 }
8921 run_test 64f "check grant consumption (with grant allocation)"
8922
8923 test_64g() {
8924         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
8925                 skip "Need MDS version at least 2.14.56"
8926
8927         local mdts=$(comma_list $(mdts_nodes))
8928
8929         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8930                         tr '\n' ' ')
8931         stack_trap "$LCTL set_param $old"
8932
8933         # generate dirty pages and increase dirty granted on MDT
8934         stack_trap "rm -f $DIR/$tfile-*"
8935         for (( i = 0; i < 10; i++)); do
8936                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8937                         error "can't set stripe"
8938                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8939                         error "can't dd"
8940                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8941                         $LFS getstripe $DIR/$tfile-$i
8942                         error "not DoM file"
8943                 }
8944         done
8945
8946         # flush dirty pages
8947         sync
8948
8949         # wait until grant shrink reset grant dirty on MDTs
8950         for ((i = 0; i < 120; i++)); do
8951                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8952                         awk '{sum=sum+$1} END {print sum}')
8953                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8954                 echo "$grant_dirty grants, $vm_dirty pages"
8955                 (( grant_dirty + vm_dirty == 0 )) && break
8956                 (( i == 3 )) && sync &&
8957                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8958                 sleep 1
8959         done
8960
8961         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8962                 awk '{sum=sum+$1} END {print sum}')
8963         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8964 }
8965 run_test 64g "grant shrink on MDT"
8966
8967 test_64h() {
8968         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
8969                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
8970
8971         local instance=$($LFS getname -i $DIR)
8972         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8973         local num_exps=$(do_facet ost1 \
8974             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8975         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8976         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8977         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8978
8979         # 10MiB is for file to be written, max_brw_size * 16 *
8980         # num_exps is space reserve so that tgt_grant_shrink() decided
8981         # to not shrink
8982         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8983         (( avail * 1024 < expect )) &&
8984                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8985
8986         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8987         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
8988         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
8989         $LCTL set_param osc.*OST0000*.grant_shrink=1
8990         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
8991
8992         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8993         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
8994
8995         # drop cache so that coming read would do rpc
8996         cancel_lru_locks osc
8997
8998         # shrink interval is set to 10, pause for 7 seconds so that
8999         # grant thread did not wake up yet but coming read entered
9000         # shrink mode for rpc (osc_should_shrink_grant())
9001         sleep 7
9002
9003         declare -a cur_grant_bytes
9004         declare -a tot_granted
9005         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9006         tot_granted[0]=$(do_facet ost1 \
9007             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9008
9009         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9010
9011         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9012         tot_granted[1]=$(do_facet ost1 \
9013             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9014
9015         # grant change should be equal on both sides
9016         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9017                 tot_granted[0] - tot_granted[1])) ||
9018                 error "grant change mismatch, "                                \
9019                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9020                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9021 }
9022 run_test 64h "grant shrink on read"
9023
9024 test_64i() {
9025         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9026                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9027
9028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9029         remote_ost_nodsh && skip "remote OSTs with nodsh"
9030
9031         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9032
9033         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9034
9035         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9036         local instance=$($LFS getname -i $DIR)
9037
9038         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9039         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9040
9041         # shrink grants and simulate rpc loss
9042         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9043         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9044         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9045
9046         fail ost1
9047
9048         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9049
9050         local testid=$(echo $TESTNAME | tr '_' ' ')
9051
9052         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9053                 grep "GRANT, real grant" &&
9054                 error "client has more grants then it owns" || true
9055 }
9056 run_test 64i "shrink on reconnect"
9057
9058 # bug 1414 - set/get directories' stripe info
9059 test_65a() {
9060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9061
9062         test_mkdir $DIR/$tdir
9063         touch $DIR/$tdir/f1
9064         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9065 }
9066 run_test 65a "directory with no stripe info"
9067
9068 test_65b() {
9069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9070
9071         test_mkdir $DIR/$tdir
9072         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9073
9074         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9075                                                 error "setstripe"
9076         touch $DIR/$tdir/f2
9077         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9078 }
9079 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9080
9081 test_65c() {
9082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9083         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9084
9085         test_mkdir $DIR/$tdir
9086         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9087
9088         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9089                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9090         touch $DIR/$tdir/f3
9091         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9092 }
9093 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9094
9095 test_65d() {
9096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9097
9098         test_mkdir $DIR/$tdir
9099         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9100         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9101
9102         if [[ $STRIPECOUNT -le 0 ]]; then
9103                 sc=1
9104         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9105                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9106                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9107         else
9108                 sc=$(($STRIPECOUNT - 1))
9109         fi
9110         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9111         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9112         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9113                 error "lverify failed"
9114 }
9115 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9116
9117 test_65e() {
9118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9119
9120         test_mkdir $DIR/$tdir
9121
9122         $LFS setstripe $DIR/$tdir || error "setstripe"
9123         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9124                                         error "no stripe info failed"
9125         touch $DIR/$tdir/f6
9126         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9127 }
9128 run_test 65e "directory setstripe defaults"
9129
9130 test_65f() {
9131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9132
9133         test_mkdir $DIR/${tdir}f
9134         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9135                 error "setstripe succeeded" || true
9136 }
9137 run_test 65f "dir setstripe permission (should return error) ==="
9138
9139 test_65g() {
9140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9141
9142         test_mkdir $DIR/$tdir
9143         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9144
9145         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9146                 error "setstripe -S failed"
9147         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9148         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9149                 error "delete default stripe failed"
9150 }
9151 run_test 65g "directory setstripe -d"
9152
9153 test_65h() {
9154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9155
9156         test_mkdir $DIR/$tdir
9157         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9158
9159         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9160                 error "setstripe -S failed"
9161         test_mkdir $DIR/$tdir/dd1
9162         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9163                 error "stripe info inherit failed"
9164 }
9165 run_test 65h "directory stripe info inherit ===================="
9166
9167 test_65i() {
9168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9169
9170         save_layout_restore_at_exit $MOUNT
9171
9172         # bug6367: set non-default striping on root directory
9173         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9174
9175         # bug12836: getstripe on -1 default directory striping
9176         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9177
9178         # bug12836: getstripe -v on -1 default directory striping
9179         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9180
9181         # bug12836: new find on -1 default directory striping
9182         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9183 }
9184 run_test 65i "various tests to set root directory striping"
9185
9186 test_65j() { # bug6367
9187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9188
9189         sync; sleep 1
9190
9191         # if we aren't already remounting for each test, do so for this test
9192         if [ "$I_MOUNTED" = "yes" ]; then
9193                 cleanup || error "failed to unmount"
9194                 setup
9195         fi
9196
9197         save_layout_restore_at_exit $MOUNT
9198
9199         $LFS setstripe -d $MOUNT || error "setstripe failed"
9200 }
9201 run_test 65j "set default striping on root directory (bug 6367)="
9202
9203 cleanup_65k() {
9204         rm -rf $DIR/$tdir
9205         wait_delete_completed
9206         do_facet $SINGLEMDS "lctl set_param -n \
9207                 osp.$ost*MDT0000.max_create_count=$max_count"
9208         do_facet $SINGLEMDS "lctl set_param -n \
9209                 osp.$ost*MDT0000.create_count=$count"
9210         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9211         echo $INACTIVE_OSC "is Activate"
9212
9213         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9214 }
9215
9216 test_65k() { # bug11679
9217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9218         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9219         remote_mds_nodsh && skip "remote MDS with nodsh"
9220
9221         local disable_precreate=true
9222         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9223                 disable_precreate=false
9224
9225         echo "Check OST status: "
9226         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9227                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9228
9229         for OSC in $MDS_OSCS; do
9230                 echo $OSC "is active"
9231                 do_facet $SINGLEMDS lctl --device %$OSC activate
9232         done
9233
9234         for INACTIVE_OSC in $MDS_OSCS; do
9235                 local ost=$(osc_to_ost $INACTIVE_OSC)
9236                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9237                                lov.*md*.target_obd |
9238                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9239
9240                 mkdir -p $DIR/$tdir
9241                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9242                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9243
9244                 echo "Deactivate: " $INACTIVE_OSC
9245                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9246
9247                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9248                               osp.$ost*MDT0000.create_count")
9249                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9250                                   osp.$ost*MDT0000.max_create_count")
9251                 $disable_precreate &&
9252                         do_facet $SINGLEMDS "lctl set_param -n \
9253                                 osp.$ost*MDT0000.max_create_count=0"
9254
9255                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9256                         [ -f $DIR/$tdir/$idx ] && continue
9257                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9258                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9259                                 { cleanup_65k;
9260                                   error "setstripe $idx should succeed"; }
9261                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9262                 done
9263                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9264                 rmdir $DIR/$tdir
9265
9266                 do_facet $SINGLEMDS "lctl set_param -n \
9267                         osp.$ost*MDT0000.max_create_count=$max_count"
9268                 do_facet $SINGLEMDS "lctl set_param -n \
9269                         osp.$ost*MDT0000.create_count=$count"
9270                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9271                 echo $INACTIVE_OSC "is Activate"
9272
9273                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9274         done
9275 }
9276 run_test 65k "validate manual striping works properly with deactivated OSCs"
9277
9278 test_65l() { # bug 12836
9279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9280
9281         test_mkdir -p $DIR/$tdir/test_dir
9282         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9283         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9284 }
9285 run_test 65l "lfs find on -1 stripe dir ========================"
9286
9287 test_65m() {
9288         local layout=$(save_layout $MOUNT)
9289         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9290                 restore_layout $MOUNT $layout
9291                 error "setstripe should fail by non-root users"
9292         }
9293         true
9294 }
9295 run_test 65m "normal user can't set filesystem default stripe"
9296
9297 test_65n() {
9298         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9299         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9300                 skip "Need MDS version at least 2.12.50"
9301         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9302
9303         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9304         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9305         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9306
9307         save_layout_restore_at_exit $MOUNT
9308
9309         # new subdirectory under root directory should not inherit
9310         # the default layout from root
9311         local dir1=$MOUNT/$tdir-1
9312         mkdir $dir1 || error "mkdir $dir1 failed"
9313         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9314                 error "$dir1 shouldn't have LOV EA"
9315
9316         # delete the default layout on root directory
9317         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9318
9319         local dir2=$MOUNT/$tdir-2
9320         mkdir $dir2 || error "mkdir $dir2 failed"
9321         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9322                 error "$dir2 shouldn't have LOV EA"
9323
9324         # set a new striping pattern on root directory
9325         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9326         local new_def_stripe_size=$((def_stripe_size * 2))
9327         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9328                 error "set stripe size on $MOUNT failed"
9329
9330         # new file created in $dir2 should inherit the new stripe size from
9331         # the filesystem default
9332         local file2=$dir2/$tfile-2
9333         touch $file2 || error "touch $file2 failed"
9334
9335         local file2_stripe_size=$($LFS getstripe -S $file2)
9336         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9337         {
9338                 echo "file2_stripe_size: '$file2_stripe_size'"
9339                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9340                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9341         }
9342
9343         local dir3=$MOUNT/$tdir-3
9344         mkdir $dir3 || error "mkdir $dir3 failed"
9345         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9346         # the root layout, which is the actual default layout that will be used
9347         # when new files are created in $dir3.
9348         local dir3_layout=$(get_layout_param $dir3)
9349         local root_dir_layout=$(get_layout_param $MOUNT)
9350         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9351         {
9352                 echo "dir3_layout: '$dir3_layout'"
9353                 echo "root_dir_layout: '$root_dir_layout'"
9354                 error "$dir3 should show the default layout from $MOUNT"
9355         }
9356
9357         # set OST pool on root directory
9358         local pool=$TESTNAME
9359         pool_add $pool || error "add $pool failed"
9360         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9361                 error "add targets to $pool failed"
9362
9363         $LFS setstripe -p $pool $MOUNT ||
9364                 error "set OST pool on $MOUNT failed"
9365
9366         # new file created in $dir3 should inherit the pool from
9367         # the filesystem default
9368         local file3=$dir3/$tfile-3
9369         touch $file3 || error "touch $file3 failed"
9370
9371         local file3_pool=$($LFS getstripe -p $file3)
9372         [[ "$file3_pool" = "$pool" ]] ||
9373                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9374
9375         local dir4=$MOUNT/$tdir-4
9376         mkdir $dir4 || error "mkdir $dir4 failed"
9377         local dir4_layout=$(get_layout_param $dir4)
9378         root_dir_layout=$(get_layout_param $MOUNT)
9379         echo "$LFS getstripe -d $dir4"
9380         $LFS getstripe -d $dir4
9381         echo "$LFS getstripe -d $MOUNT"
9382         $LFS getstripe -d $MOUNT
9383         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9384         {
9385                 echo "dir4_layout: '$dir4_layout'"
9386                 echo "root_dir_layout: '$root_dir_layout'"
9387                 error "$dir4 should show the default layout from $MOUNT"
9388         }
9389
9390         # new file created in $dir4 should inherit the pool from
9391         # the filesystem default
9392         local file4=$dir4/$tfile-4
9393         touch $file4 || error "touch $file4 failed"
9394
9395         local file4_pool=$($LFS getstripe -p $file4)
9396         [[ "$file4_pool" = "$pool" ]] ||
9397                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9398
9399         # new subdirectory under non-root directory should inherit
9400         # the default layout from its parent directory
9401         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9402                 error "set directory layout on $dir4 failed"
9403
9404         local dir5=$dir4/$tdir-5
9405         mkdir $dir5 || error "mkdir $dir5 failed"
9406
9407         dir4_layout=$(get_layout_param $dir4)
9408         local dir5_layout=$(get_layout_param $dir5)
9409         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9410         {
9411                 echo "dir4_layout: '$dir4_layout'"
9412                 echo "dir5_layout: '$dir5_layout'"
9413                 error "$dir5 should inherit the default layout from $dir4"
9414         }
9415
9416         # though subdir under ROOT doesn't inherit default layout, but
9417         # its sub dir/file should be created with default layout.
9418         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9419         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9420                 skip "Need MDS version at least 2.12.59"
9421
9422         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9423         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9424         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9425
9426         if [ $default_lmv_hash == "none" ]; then
9427                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9428         else
9429                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9430                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9431         fi
9432
9433         $LFS setdirstripe -D -c 2 $MOUNT ||
9434                 error "setdirstripe -D -c 2 failed"
9435         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9436         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9437         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9438
9439         # $dir4 layout includes pool
9440         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9441         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9442                 error "pool lost on setstripe"
9443         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9444         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9445                 error "pool lost on compound layout setstripe"
9446 }
9447 run_test 65n "don't inherit default layout from root for new subdirectories"
9448
9449 # bug 2543 - update blocks count on client
9450 test_66() {
9451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9452
9453         COUNT=${COUNT:-8}
9454         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9455         sync; sync_all_data; sync; sync_all_data
9456         cancel_lru_locks osc
9457         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9458         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9459 }
9460 run_test 66 "update inode blocks count on client ==============="
9461
9462 meminfo() {
9463         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9464 }
9465
9466 swap_used() {
9467         swapon -s | awk '($1 == "'$1'") { print $4 }'
9468 }
9469
9470 # bug5265, obdfilter oa2dentry return -ENOENT
9471 # #define OBD_FAIL_SRV_ENOENT 0x217
9472 test_69() {
9473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9474         remote_ost_nodsh && skip "remote OST with nodsh"
9475
9476         f="$DIR/$tfile"
9477         $LFS setstripe -c 1 -i 0 $f
9478
9479         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9480
9481         do_facet ost1 lctl set_param fail_loc=0x217
9482         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9483         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9484
9485         do_facet ost1 lctl set_param fail_loc=0
9486         $DIRECTIO write $f 0 2 || error "write error"
9487
9488         cancel_lru_locks osc
9489         $DIRECTIO read $f 0 1 || error "read error"
9490
9491         do_facet ost1 lctl set_param fail_loc=0x217
9492         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9493
9494         do_facet ost1 lctl set_param fail_loc=0
9495         rm -f $f
9496 }
9497 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9498
9499 test_71() {
9500         test_mkdir $DIR/$tdir
9501         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9502         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9503 }
9504 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9505
9506 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9508         [ "$RUNAS_ID" = "$UID" ] &&
9509                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9510         # Check that testing environment is properly set up. Skip if not
9511         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9512                 skip_env "User $RUNAS_ID does not exist - skipping"
9513
9514         touch $DIR/$tfile
9515         chmod 777 $DIR/$tfile
9516         chmod ug+s $DIR/$tfile
9517         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9518                 error "$RUNAS dd $DIR/$tfile failed"
9519         # See if we are still setuid/sgid
9520         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9521                 error "S/gid is not dropped on write"
9522         # Now test that MDS is updated too
9523         cancel_lru_locks mdc
9524         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9525                 error "S/gid is not dropped on MDS"
9526         rm -f $DIR/$tfile
9527 }
9528 run_test 72a "Test that remove suid works properly (bug5695) ===="
9529
9530 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9531         local perm
9532
9533         [ "$RUNAS_ID" = "$UID" ] &&
9534                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9535         [ "$RUNAS_ID" -eq 0 ] &&
9536                 skip_env "RUNAS_ID = 0 -- skipping"
9537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9538         # Check that testing environment is properly set up. Skip if not
9539         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9540                 skip_env "User $RUNAS_ID does not exist - skipping"
9541
9542         touch $DIR/${tfile}-f{g,u}
9543         test_mkdir $DIR/${tfile}-dg
9544         test_mkdir $DIR/${tfile}-du
9545         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9546         chmod g+s $DIR/${tfile}-{f,d}g
9547         chmod u+s $DIR/${tfile}-{f,d}u
9548         for perm in 777 2777 4777; do
9549                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9550                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9551                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9552                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9553         done
9554         true
9555 }
9556 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9557
9558 # bug 3462 - multiple simultaneous MDC requests
9559 test_73() {
9560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9561
9562         test_mkdir $DIR/d73-1
9563         test_mkdir $DIR/d73-2
9564         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9565         pid1=$!
9566
9567         lctl set_param fail_loc=0x80000129
9568         $MULTIOP $DIR/d73-1/f73-2 Oc &
9569         sleep 1
9570         lctl set_param fail_loc=0
9571
9572         $MULTIOP $DIR/d73-2/f73-3 Oc &
9573         pid3=$!
9574
9575         kill -USR1 $pid1
9576         wait $pid1 || return 1
9577
9578         sleep 25
9579
9580         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9581         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9582         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9583
9584         rm -rf $DIR/d73-*
9585 }
9586 run_test 73 "multiple MDC requests (should not deadlock)"
9587
9588 test_74a() { # bug 6149, 6184
9589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9590
9591         touch $DIR/f74a
9592         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9593         #
9594         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9595         # will spin in a tight reconnection loop
9596         $LCTL set_param fail_loc=0x8000030e
9597         # get any lock that won't be difficult - lookup works.
9598         ls $DIR/f74a
9599         $LCTL set_param fail_loc=0
9600         rm -f $DIR/f74a
9601         true
9602 }
9603 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9604
9605 test_74b() { # bug 13310
9606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9607
9608         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9609         #
9610         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9611         # will spin in a tight reconnection loop
9612         $LCTL set_param fail_loc=0x8000030e
9613         # get a "difficult" lock
9614         touch $DIR/f74b
9615         $LCTL set_param fail_loc=0
9616         rm -f $DIR/f74b
9617         true
9618 }
9619 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9620
9621 test_74c() {
9622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9623
9624         #define OBD_FAIL_LDLM_NEW_LOCK
9625         $LCTL set_param fail_loc=0x319
9626         touch $DIR/$tfile && error "touch successful"
9627         $LCTL set_param fail_loc=0
9628         true
9629 }
9630 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9631
9632 slab_lic=/sys/kernel/slab/lustre_inode_cache
9633 num_objects() {
9634         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9635         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9636                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9637 }
9638
9639 test_76a() { # Now for b=20433, added originally in b=1443
9640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9641
9642         cancel_lru_locks osc
9643         # there may be some slab objects cached per core
9644         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9645         local before=$(num_objects)
9646         local count=$((512 * cpus))
9647         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9648         local margin=$((count / 10))
9649         if [[ -f $slab_lic/aliases ]]; then
9650                 local aliases=$(cat $slab_lic/aliases)
9651                 (( aliases > 0 )) && margin=$((margin * aliases))
9652         fi
9653
9654         echo "before slab objects: $before"
9655         for i in $(seq $count); do
9656                 touch $DIR/$tfile
9657                 rm -f $DIR/$tfile
9658         done
9659         cancel_lru_locks osc
9660         local after=$(num_objects)
9661         echo "created: $count, after slab objects: $after"
9662         # shared slab counts are not very accurate, allow significant margin
9663         # the main goal is that the cache growth is not permanently > $count
9664         while (( after > before + margin )); do
9665                 sleep 1
9666                 after=$(num_objects)
9667                 wait=$((wait + 1))
9668                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9669                 if (( wait > 60 )); then
9670                         error "inode slab grew from $before+$margin to $after"
9671                 fi
9672         done
9673 }
9674 run_test 76a "confirm clients recycle inodes properly ===="
9675
9676 test_76b() {
9677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9678         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9679
9680         local count=512
9681         local before=$(num_objects)
9682
9683         for i in $(seq $count); do
9684                 mkdir $DIR/$tdir
9685                 rmdir $DIR/$tdir
9686         done
9687
9688         local after=$(num_objects)
9689         local wait=0
9690
9691         while (( after > before )); do
9692                 sleep 1
9693                 after=$(num_objects)
9694                 wait=$((wait + 1))
9695                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9696                 if (( wait > 60 )); then
9697                         error "inode slab grew from $before to $after"
9698                 fi
9699         done
9700
9701         echo "slab objects before: $before, after: $after"
9702 }
9703 run_test 76b "confirm clients recycle directory inodes properly ===="
9704
9705 export ORIG_CSUM=""
9706 set_checksums()
9707 {
9708         # Note: in sptlrpc modes which enable its own bulk checksum, the
9709         # original crc32_le bulk checksum will be automatically disabled,
9710         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9711         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9712         # In this case set_checksums() will not be no-op, because sptlrpc
9713         # bulk checksum will be enabled all through the test.
9714
9715         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9716         lctl set_param -n osc.*.checksums $1
9717         return 0
9718 }
9719
9720 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9721                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9722 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9723                              tr -d [] | head -n1)}
9724 set_checksum_type()
9725 {
9726         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9727         rc=$?
9728         log "set checksum type to $1, rc = $rc"
9729         return $rc
9730 }
9731
9732 get_osc_checksum_type()
9733 {
9734         # arugment 1: OST name, like OST0000
9735         ost=$1
9736         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9737                         sed 's/.*\[\(.*\)\].*/\1/g')
9738         rc=$?
9739         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9740         echo $checksum_type
9741 }
9742
9743 F77_TMP=$TMP/f77-temp
9744 F77SZ=8
9745 setup_f77() {
9746         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9747                 error "error writing to $F77_TMP"
9748 }
9749
9750 test_77a() { # bug 10889
9751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9752         $GSS && skip_env "could not run with gss"
9753
9754         [ ! -f $F77_TMP ] && setup_f77
9755         set_checksums 1
9756         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9757         set_checksums 0
9758         rm -f $DIR/$tfile
9759 }
9760 run_test 77a "normal checksum read/write operation"
9761
9762 test_77b() { # bug 10889
9763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9764         $GSS && skip_env "could not run with gss"
9765
9766         [ ! -f $F77_TMP ] && setup_f77
9767         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9768         $LCTL set_param fail_loc=0x80000409
9769         set_checksums 1
9770
9771         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9772                 error "dd error: $?"
9773         $LCTL set_param fail_loc=0
9774
9775         for algo in $CKSUM_TYPES; do
9776                 cancel_lru_locks osc
9777                 set_checksum_type $algo
9778                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9779                 $LCTL set_param fail_loc=0x80000408
9780                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9781                 $LCTL set_param fail_loc=0
9782         done
9783         set_checksums 0
9784         set_checksum_type $ORIG_CSUM_TYPE
9785         rm -f $DIR/$tfile
9786 }
9787 run_test 77b "checksum error on client write, read"
9788
9789 cleanup_77c() {
9790         trap 0
9791         set_checksums 0
9792         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9793         $check_ost &&
9794                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9795         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9796         $check_ost && [ -n "$ost_file_prefix" ] &&
9797                 do_facet ost1 rm -f ${ost_file_prefix}\*
9798 }
9799
9800 test_77c() {
9801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9802         $GSS && skip_env "could not run with gss"
9803         remote_ost_nodsh && skip "remote OST with nodsh"
9804
9805         local bad1
9806         local osc_file_prefix
9807         local osc_file
9808         local check_ost=false
9809         local ost_file_prefix
9810         local ost_file
9811         local orig_cksum
9812         local dump_cksum
9813         local fid
9814
9815         # ensure corruption will occur on first OSS/OST
9816         $LFS setstripe -i 0 $DIR/$tfile
9817
9818         [ ! -f $F77_TMP ] && setup_f77
9819         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9820                 error "dd write error: $?"
9821         fid=$($LFS path2fid $DIR/$tfile)
9822
9823         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9824         then
9825                 check_ost=true
9826                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9827                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9828         else
9829                 echo "OSS do not support bulk pages dump upon error"
9830         fi
9831
9832         osc_file_prefix=$($LCTL get_param -n debug_path)
9833         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9834
9835         trap cleanup_77c EXIT
9836
9837         set_checksums 1
9838         # enable bulk pages dump upon error on Client
9839         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9840         # enable bulk pages dump upon error on OSS
9841         $check_ost &&
9842                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9843
9844         # flush Client cache to allow next read to reach OSS
9845         cancel_lru_locks osc
9846
9847         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9848         $LCTL set_param fail_loc=0x80000408
9849         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9850         $LCTL set_param fail_loc=0
9851
9852         rm -f $DIR/$tfile
9853
9854         # check cksum dump on Client
9855         osc_file=$(ls ${osc_file_prefix}*)
9856         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9857         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9858         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9859         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9860         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9861                      cksum)
9862         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9863         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9864                 error "dump content does not match on Client"
9865
9866         $check_ost || skip "No need to check cksum dump on OSS"
9867
9868         # check cksum dump on OSS
9869         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9870         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9871         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9872         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9873         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9874                 error "dump content does not match on OSS"
9875
9876         cleanup_77c
9877 }
9878 run_test 77c "checksum error on client read with debug"
9879
9880 test_77d() { # bug 10889
9881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9882         $GSS && skip_env "could not run with gss"
9883
9884         stack_trap "rm -f $DIR/$tfile"
9885         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9886         $LCTL set_param fail_loc=0x80000409
9887         set_checksums 1
9888         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9889                 error "direct write: rc=$?"
9890         $LCTL set_param fail_loc=0
9891         set_checksums 0
9892
9893         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9894         $LCTL set_param fail_loc=0x80000408
9895         set_checksums 1
9896         cancel_lru_locks osc
9897         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9898                 error "direct read: rc=$?"
9899         $LCTL set_param fail_loc=0
9900         set_checksums 0
9901 }
9902 run_test 77d "checksum error on OST direct write, read"
9903
9904 test_77f() { # bug 10889
9905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9906         $GSS && skip_env "could not run with gss"
9907
9908         set_checksums 1
9909         stack_trap "rm -f $DIR/$tfile"
9910         for algo in $CKSUM_TYPES; do
9911                 cancel_lru_locks osc
9912                 set_checksum_type $algo
9913                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9914                 $LCTL set_param fail_loc=0x409
9915                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9916                         error "direct write succeeded"
9917                 $LCTL set_param fail_loc=0
9918         done
9919         set_checksum_type $ORIG_CSUM_TYPE
9920         set_checksums 0
9921 }
9922 run_test 77f "repeat checksum error on write (expect error)"
9923
9924 test_77g() { # bug 10889
9925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9926         $GSS && skip_env "could not run with gss"
9927         remote_ost_nodsh && skip "remote OST with nodsh"
9928
9929         [ ! -f $F77_TMP ] && setup_f77
9930
9931         local file=$DIR/$tfile
9932         stack_trap "rm -f $file" EXIT
9933
9934         $LFS setstripe -c 1 -i 0 $file
9935         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9936         do_facet ost1 lctl set_param fail_loc=0x8000021a
9937         set_checksums 1
9938         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9939                 error "write error: rc=$?"
9940         do_facet ost1 lctl set_param fail_loc=0
9941         set_checksums 0
9942
9943         cancel_lru_locks osc
9944         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9945         do_facet ost1 lctl set_param fail_loc=0x8000021b
9946         set_checksums 1
9947         cmp $F77_TMP $file || error "file compare failed"
9948         do_facet ost1 lctl set_param fail_loc=0
9949         set_checksums 0
9950 }
9951 run_test 77g "checksum error on OST write, read"
9952
9953 test_77k() { # LU-10906
9954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9955         $GSS && skip_env "could not run with gss"
9956
9957         local cksum_param="osc.$FSNAME*.checksums"
9958         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9959         local checksum
9960         local i
9961
9962         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9963         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9964         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9965
9966         for i in 0 1; do
9967                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9968                         error "failed to set checksum=$i on MGS"
9969                 wait_update $HOSTNAME "$get_checksum" $i
9970                 #remount
9971                 echo "remount client, checksum should be $i"
9972                 remount_client $MOUNT || error "failed to remount client"
9973                 checksum=$(eval $get_checksum)
9974                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9975         done
9976         # remove persistent param to avoid races with checksum mountopt below
9977         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9978                 error "failed to delete checksum on MGS"
9979
9980         for opt in "checksum" "nochecksum"; do
9981                 #remount with mount option
9982                 echo "remount client with option $opt, checksum should be $i"
9983                 umount_client $MOUNT || error "failed to umount client"
9984                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9985                         error "failed to mount client with option '$opt'"
9986                 checksum=$(eval $get_checksum)
9987                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9988                 i=$((i - 1))
9989         done
9990
9991         remount_client $MOUNT || error "failed to remount client"
9992 }
9993 run_test 77k "enable/disable checksum correctly"
9994
9995 test_77l() {
9996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9997         $GSS && skip_env "could not run with gss"
9998
9999         set_checksums 1
10000         stack_trap "set_checksums $ORIG_CSUM" EXIT
10001         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10002
10003         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10004
10005         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10006         for algo in $CKSUM_TYPES; do
10007                 set_checksum_type $algo || error "fail to set checksum type $algo"
10008                 osc_algo=$(get_osc_checksum_type OST0000)
10009                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10010
10011                 # no locks, no reqs to let the connection idle
10012                 cancel_lru_locks osc
10013                 lru_resize_disable osc
10014                 wait_osc_import_state client ost1 IDLE
10015
10016                 # ensure ost1 is connected
10017                 stat $DIR/$tfile >/dev/null || error "can't stat"
10018                 wait_osc_import_state client ost1 FULL
10019
10020                 osc_algo=$(get_osc_checksum_type OST0000)
10021                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10022         done
10023         return 0
10024 }
10025 run_test 77l "preferred checksum type is remembered after reconnected"
10026
10027 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10028 rm -f $F77_TMP
10029 unset F77_TMP
10030
10031 test_77m() {
10032         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10033                 skip "Need at least version 2.14.52"
10034         local param=checksum_speed
10035
10036         $LCTL get_param $param || error "reading $param failed"
10037
10038         csum_speeds=$($LCTL get_param -n $param)
10039
10040         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10041                 error "known checksum types are missing"
10042 }
10043 run_test 77m "Verify checksum_speed is correctly read"
10044
10045 check_filefrag_77n() {
10046         local nr_ext=0
10047         local starts=()
10048         local ends=()
10049
10050         while read extidx a b start end rest; do
10051                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10052                         nr_ext=$(( $nr_ext + 1 ))
10053                         starts+=( ${start%..} )
10054                         ends+=( ${end%:} )
10055                 fi
10056         done < <( filefrag -sv $1 )
10057
10058         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10059         return 1
10060 }
10061
10062 test_77n() {
10063         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10064
10065         touch $DIR/$tfile
10066         $TRUNCATE $DIR/$tfile 0
10067         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10068         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10069         check_filefrag_77n $DIR/$tfile ||
10070                 skip "$tfile blocks not contiguous around hole"
10071
10072         set_checksums 1
10073         stack_trap "set_checksums $ORIG_CSUM" EXIT
10074         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10075         stack_trap "rm -f $DIR/$tfile"
10076
10077         for algo in $CKSUM_TYPES; do
10078                 if [[ "$algo" =~ ^t10 ]]; then
10079                         set_checksum_type $algo ||
10080                                 error "fail to set checksum type $algo"
10081                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10082                                 error "fail to read $tfile with $algo"
10083                 fi
10084         done
10085         rm -f $DIR/$tfile
10086         return 0
10087 }
10088 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10089
10090 test_77o() {
10091         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10092                 skip "Need MDS version at least 2.14.55"
10093         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10094                 skip "Need OST version at least 2.14.55"
10095         local ofd=obdfilter
10096         local mdt=mdt
10097
10098         # print OST checksum_type
10099         echo "$ofd.$FSNAME-*.checksum_type:"
10100         do_nodes $(comma_list $(osts_nodes)) \
10101                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10102
10103         # print MDT checksum_type
10104         echo "$mdt.$FSNAME-*.checksum_type:"
10105         do_nodes $(comma_list $(mdts_nodes)) \
10106                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10107
10108         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10109                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10110
10111         (( $o_count == $OSTCOUNT )) ||
10112                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10113
10114         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10115                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10116
10117         (( $m_count == $MDSCOUNT )) ||
10118                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10119 }
10120 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10121
10122 cleanup_test_78() {
10123         trap 0
10124         rm -f $DIR/$tfile
10125 }
10126
10127 test_78() { # bug 10901
10128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10129         remote_ost || skip_env "local OST"
10130
10131         NSEQ=5
10132         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10133         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10134         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10135         echo "MemTotal: $MEMTOTAL"
10136
10137         # reserve 256MB of memory for the kernel and other running processes,
10138         # and then take 1/2 of the remaining memory for the read/write buffers.
10139         if [ $MEMTOTAL -gt 512 ] ;then
10140                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10141         else
10142                 # for those poor memory-starved high-end clusters...
10143                 MEMTOTAL=$((MEMTOTAL / 2))
10144         fi
10145         echo "Mem to use for directio: $MEMTOTAL"
10146
10147         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10148         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10149         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10150         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10151                 head -n1)
10152         echo "Smallest OST: $SMALLESTOST"
10153         [[ $SMALLESTOST -lt 10240 ]] &&
10154                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10155
10156         trap cleanup_test_78 EXIT
10157
10158         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10159                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10160
10161         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10162         echo "File size: $F78SIZE"
10163         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10164         for i in $(seq 1 $NSEQ); do
10165                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10166                 echo directIO rdwr round $i of $NSEQ
10167                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10168         done
10169
10170         cleanup_test_78
10171 }
10172 run_test 78 "handle large O_DIRECT writes correctly ============"
10173
10174 test_79() { # bug 12743
10175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10176
10177         wait_delete_completed
10178
10179         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10180         BKFREE=$(calc_osc_kbytes kbytesfree)
10181         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10182
10183         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10184         DFTOTAL=`echo $STRING | cut -d, -f1`
10185         DFUSED=`echo $STRING  | cut -d, -f2`
10186         DFAVAIL=`echo $STRING | cut -d, -f3`
10187         DFFREE=$(($DFTOTAL - $DFUSED))
10188
10189         ALLOWANCE=$((64 * $OSTCOUNT))
10190
10191         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10192            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10193                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10194         fi
10195         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10196            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10197                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10198         fi
10199         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10200            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10201                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10202         fi
10203 }
10204 run_test 79 "df report consistency check ======================="
10205
10206 test_80() { # bug 10718
10207         remote_ost_nodsh && skip "remote OST with nodsh"
10208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10209
10210         # relax strong synchronous semantics for slow backends like ZFS
10211         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10212                 local soc="obdfilter.*.sync_lock_cancel"
10213                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10214
10215                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10216                 if [ -z "$save" ]; then
10217                         soc="obdfilter.*.sync_on_lock_cancel"
10218                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10219                 fi
10220
10221                 if [ "$save" != "never" ]; then
10222                         local hosts=$(comma_list $(osts_nodes))
10223
10224                         do_nodes $hosts $LCTL set_param $soc=never
10225                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10226                 fi
10227         fi
10228
10229         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10230         sync; sleep 1; sync
10231         local before=$(date +%s)
10232         cancel_lru_locks osc
10233         local after=$(date +%s)
10234         local diff=$((after - before))
10235         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10236
10237         rm -f $DIR/$tfile
10238 }
10239 run_test 80 "Page eviction is equally fast at high offsets too"
10240
10241 test_81a() { # LU-456
10242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10243         remote_ost_nodsh && skip "remote OST with nodsh"
10244
10245         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10246         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10247         do_facet ost1 lctl set_param fail_loc=0x80000228
10248
10249         # write should trigger a retry and success
10250         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10251         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10252         RC=$?
10253         if [ $RC -ne 0 ] ; then
10254                 error "write should success, but failed for $RC"
10255         fi
10256 }
10257 run_test 81a "OST should retry write when get -ENOSPC ==============="
10258
10259 test_81b() { # LU-456
10260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10261         remote_ost_nodsh && skip "remote OST with nodsh"
10262
10263         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10264         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10265         do_facet ost1 lctl set_param fail_loc=0x228
10266
10267         # write should retry several times and return -ENOSPC finally
10268         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10269         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10270         RC=$?
10271         ENOSPC=28
10272         if [ $RC -ne $ENOSPC ] ; then
10273                 error "dd should fail for -ENOSPC, but succeed."
10274         fi
10275 }
10276 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10277
10278 test_99() {
10279         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10280
10281         test_mkdir $DIR/$tdir.cvsroot
10282         chown $RUNAS_ID $DIR/$tdir.cvsroot
10283
10284         cd $TMP
10285         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10286
10287         cd /etc/init.d
10288         # some versions of cvs import exit(1) when asked to import links or
10289         # files they can't read.  ignore those files.
10290         local toignore=$(find . -type l -printf '-I %f\n' -o \
10291                          ! -perm /4 -printf '-I %f\n')
10292         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10293                 $tdir.reposname vtag rtag
10294
10295         cd $DIR
10296         test_mkdir $DIR/$tdir.reposname
10297         chown $RUNAS_ID $DIR/$tdir.reposname
10298         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10299
10300         cd $DIR/$tdir.reposname
10301         $RUNAS touch foo99
10302         $RUNAS cvs add -m 'addmsg' foo99
10303         $RUNAS cvs update
10304         $RUNAS cvs commit -m 'nomsg' foo99
10305         rm -fr $DIR/$tdir.cvsroot
10306 }
10307 run_test 99 "cvs strange file/directory operations"
10308
10309 test_100() {
10310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10311         [[ "$NETTYPE" =~ tcp ]] ||
10312                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10313         remote_ost_nodsh && skip "remote OST with nodsh"
10314         remote_mds_nodsh && skip "remote MDS with nodsh"
10315         remote_servers ||
10316                 skip "useless for local single node setup"
10317
10318         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10319                 [ "$PROT" != "tcp" ] && continue
10320                 RPORT=$(echo $REMOTE | cut -d: -f2)
10321                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10322
10323                 rc=0
10324                 LPORT=`echo $LOCAL | cut -d: -f2`
10325                 if [ $LPORT -ge 1024 ]; then
10326                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10327                         netstat -tna
10328                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10329                 fi
10330         done
10331         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10332 }
10333 run_test 100 "check local port using privileged port ==========="
10334
10335 function get_named_value()
10336 {
10337     local tag=$1
10338
10339     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10340 }
10341
10342 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10343                    awk '/^max_cached_mb/ { print $2 }')
10344
10345 cleanup_101a() {
10346         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10347         trap 0
10348 }
10349
10350 test_101a() {
10351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10352
10353         local s
10354         local discard
10355         local nreads=10000
10356         local cache_limit=32
10357
10358         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10359         trap cleanup_101a EXIT
10360         $LCTL set_param -n llite.*.read_ahead_stats=0
10361         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10362
10363         #
10364         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10365         #
10366         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10367         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10368
10369         discard=0
10370         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10371                    get_named_value 'read.but.discarded'); do
10372                         discard=$(($discard + $s))
10373         done
10374         cleanup_101a
10375
10376         $LCTL get_param osc.*-osc*.rpc_stats
10377         $LCTL get_param llite.*.read_ahead_stats
10378
10379         # Discard is generally zero, but sometimes a few random reads line up
10380         # and trigger larger readahead, which is wasted & leads to discards.
10381         if [[ $(($discard)) -gt $nreads ]]; then
10382                 error "too many ($discard) discarded pages"
10383         fi
10384         rm -f $DIR/$tfile || true
10385 }
10386 run_test 101a "check read-ahead for random reads"
10387
10388 setup_test101bc() {
10389         test_mkdir $DIR/$tdir
10390         local ssize=$1
10391         local FILE_LENGTH=$2
10392         STRIPE_OFFSET=0
10393
10394         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10395
10396         local list=$(comma_list $(osts_nodes))
10397         set_osd_param $list '' read_cache_enable 0
10398         set_osd_param $list '' writethrough_cache_enable 0
10399
10400         trap cleanup_test101bc EXIT
10401         # prepare the read-ahead file
10402         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10403
10404         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10405                                 count=$FILE_SIZE_MB 2> /dev/null
10406
10407 }
10408
10409 cleanup_test101bc() {
10410         trap 0
10411         rm -rf $DIR/$tdir
10412         rm -f $DIR/$tfile
10413
10414         local list=$(comma_list $(osts_nodes))
10415         set_osd_param $list '' read_cache_enable 1
10416         set_osd_param $list '' writethrough_cache_enable 1
10417 }
10418
10419 calc_total() {
10420         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10421 }
10422
10423 ra_check_101() {
10424         local read_size=$1
10425         local stripe_size=$2
10426         local stride_length=$((stripe_size / read_size))
10427         local stride_width=$((stride_length * OSTCOUNT))
10428         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10429                                 (stride_width - stride_length) ))
10430         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10431                   get_named_value 'read.but.discarded' | calc_total)
10432
10433         if [[ $discard -gt $discard_limit ]]; then
10434                 $LCTL get_param llite.*.read_ahead_stats
10435                 error "($discard) discarded pages with size (${read_size})"
10436         else
10437                 echo "Read-ahead success for size ${read_size}"
10438         fi
10439 }
10440
10441 test_101b() {
10442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10443         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10444
10445         local STRIPE_SIZE=1048576
10446         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10447
10448         if [ $SLOW == "yes" ]; then
10449                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10450         else
10451                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10452         fi
10453
10454         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10455
10456         # prepare the read-ahead file
10457         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10458         cancel_lru_locks osc
10459         for BIDX in 2 4 8 16 32 64 128 256
10460         do
10461                 local BSIZE=$((BIDX*4096))
10462                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10463                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10464                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10465                 $LCTL set_param -n llite.*.read_ahead_stats=0
10466                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10467                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10468                 cancel_lru_locks osc
10469                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10470         done
10471         cleanup_test101bc
10472         true
10473 }
10474 run_test 101b "check stride-io mode read-ahead ================="
10475
10476 test_101c() {
10477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10478
10479         local STRIPE_SIZE=1048576
10480         local FILE_LENGTH=$((STRIPE_SIZE*100))
10481         local nreads=10000
10482         local rsize=65536
10483         local osc_rpc_stats
10484
10485         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10486
10487         cancel_lru_locks osc
10488         $LCTL set_param osc.*.rpc_stats=0
10489         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10490         $LCTL get_param osc.*.rpc_stats
10491         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10492                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10493                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10494                 local size
10495
10496                 if [ $lines -le 20 ]; then
10497                         echo "continue debug"
10498                         continue
10499                 fi
10500                 for size in 1 2 4 8; do
10501                         local rpc=$(echo "$stats" |
10502                                     awk '($1 == "'$size':") {print $2; exit; }')
10503                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10504                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10505                 done
10506                 echo "$osc_rpc_stats check passed!"
10507         done
10508         cleanup_test101bc
10509         true
10510 }
10511 run_test 101c "check stripe_size aligned read-ahead"
10512
10513 test_101d() {
10514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10515
10516         local file=$DIR/$tfile
10517         local sz_MB=${FILESIZE_101d:-80}
10518         local ra_MB=${READAHEAD_MB:-40}
10519
10520         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10521         [ $free_MB -lt $sz_MB ] &&
10522                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10523
10524         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10525         $LFS setstripe -c -1 $file || error "setstripe failed"
10526
10527         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10528         echo Cancel LRU locks on lustre client to flush the client cache
10529         cancel_lru_locks osc
10530
10531         echo Disable read-ahead
10532         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10533         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10534         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10535         $LCTL get_param -n llite.*.max_read_ahead_mb
10536
10537         echo "Reading the test file $file with read-ahead disabled"
10538         local sz_KB=$((sz_MB * 1024 / 4))
10539         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10540         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10541         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10542                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10543
10544         echo "Cancel LRU locks on lustre client to flush the client cache"
10545         cancel_lru_locks osc
10546         echo Enable read-ahead with ${ra_MB}MB
10547         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10548
10549         echo "Reading the test file $file with read-ahead enabled"
10550         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10551                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10552
10553         echo "read-ahead disabled time read $raOFF"
10554         echo "read-ahead enabled time read $raON"
10555
10556         rm -f $file
10557         wait_delete_completed
10558
10559         # use awk for this check instead of bash because it handles decimals
10560         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10561                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10562 }
10563 run_test 101d "file read with and without read-ahead enabled"
10564
10565 test_101e() {
10566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10567
10568         local file=$DIR/$tfile
10569         local size_KB=500  #KB
10570         local count=100
10571         local bsize=1024
10572
10573         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10574         local need_KB=$((count * size_KB))
10575         [[ $free_KB -le $need_KB ]] &&
10576                 skip_env "Need free space $need_KB, have $free_KB"
10577
10578         echo "Creating $count ${size_KB}K test files"
10579         for ((i = 0; i < $count; i++)); do
10580                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10581         done
10582
10583         echo "Cancel LRU locks on lustre client to flush the client cache"
10584         cancel_lru_locks $OSC
10585
10586         echo "Reset readahead stats"
10587         $LCTL set_param -n llite.*.read_ahead_stats=0
10588
10589         for ((i = 0; i < $count; i++)); do
10590                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10591         done
10592
10593         $LCTL get_param llite.*.max_cached_mb
10594         $LCTL get_param llite.*.read_ahead_stats
10595         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10596                      get_named_value 'misses' | calc_total)
10597
10598         for ((i = 0; i < $count; i++)); do
10599                 rm -rf $file.$i 2>/dev/null
10600         done
10601
10602         #10000 means 20% reads are missing in readahead
10603         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10604 }
10605 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10606
10607 test_101f() {
10608         which iozone || skip_env "no iozone installed"
10609
10610         local old_debug=$($LCTL get_param debug)
10611         old_debug=${old_debug#*=}
10612         $LCTL set_param debug="reada mmap"
10613
10614         # create a test file
10615         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10616
10617         echo Cancel LRU locks on lustre client to flush the client cache
10618         cancel_lru_locks osc
10619
10620         echo Reset readahead stats
10621         $LCTL set_param -n llite.*.read_ahead_stats=0
10622
10623         echo mmap read the file with small block size
10624         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10625                 > /dev/null 2>&1
10626
10627         echo checking missing pages
10628         $LCTL get_param llite.*.read_ahead_stats
10629         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10630                         get_named_value 'misses' | calc_total)
10631
10632         $LCTL set_param debug="$old_debug"
10633         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10634         rm -f $DIR/$tfile
10635 }
10636 run_test 101f "check mmap read performance"
10637
10638 test_101g_brw_size_test() {
10639         local mb=$1
10640         local pages=$((mb * 1048576 / PAGE_SIZE))
10641         local file=$DIR/$tfile
10642
10643         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10644                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10645         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10646                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10647                         return 2
10648         done
10649
10650         stack_trap "rm -f $file" EXIT
10651         $LCTL set_param -n osc.*.rpc_stats=0
10652
10653         # 10 RPCs should be enough for the test
10654         local count=10
10655         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10656                 { error "dd write ${mb} MB blocks failed"; return 3; }
10657         cancel_lru_locks osc
10658         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10659                 { error "dd write ${mb} MB blocks failed"; return 4; }
10660
10661         # calculate number of full-sized read and write RPCs
10662         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10663                 sed -n '/pages per rpc/,/^$/p' |
10664                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10665                 END { print reads,writes }'))
10666         # allow one extra full-sized read RPC for async readahead
10667         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10668                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10669         [[ ${rpcs[1]} == $count ]] ||
10670                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10671 }
10672
10673 test_101g() {
10674         remote_ost_nodsh && skip "remote OST with nodsh"
10675
10676         local rpcs
10677         local osts=$(get_facets OST)
10678         local list=$(comma_list $(osts_nodes))
10679         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10680         local brw_size="obdfilter.*.brw_size"
10681
10682         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10683
10684         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10685
10686         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10687                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10688                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10689            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10690                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10691                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10692
10693                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10694                         suffix="M"
10695
10696                 if [[ $orig_mb -lt 16 ]]; then
10697                         save_lustre_params $osts "$brw_size" > $p
10698                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10699                                 error "set 16MB RPC size failed"
10700
10701                         echo "remount client to enable new RPC size"
10702                         remount_client $MOUNT || error "remount_client failed"
10703                 fi
10704
10705                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10706                 # should be able to set brw_size=12, but no rpc_stats for that
10707                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10708         fi
10709
10710         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10711
10712         if [[ $orig_mb -lt 16 ]]; then
10713                 restore_lustre_params < $p
10714                 remount_client $MOUNT || error "remount_client restore failed"
10715         fi
10716
10717         rm -f $p $DIR/$tfile
10718 }
10719 run_test 101g "Big bulk(4/16 MiB) readahead"
10720
10721 test_101h() {
10722         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10723
10724         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10725                 error "dd 70M file failed"
10726         echo Cancel LRU locks on lustre client to flush the client cache
10727         cancel_lru_locks osc
10728
10729         echo "Reset readahead stats"
10730         $LCTL set_param -n llite.*.read_ahead_stats 0
10731
10732         echo "Read 10M of data but cross 64M bundary"
10733         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10734         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10735                      get_named_value 'misses' | calc_total)
10736         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10737         rm -f $p $DIR/$tfile
10738 }
10739 run_test 101h "Readahead should cover current read window"
10740
10741 test_101i() {
10742         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10743                 error "dd 10M file failed"
10744
10745         local max_per_file_mb=$($LCTL get_param -n \
10746                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10747         cancel_lru_locks osc
10748         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10749         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10750                 error "set max_read_ahead_per_file_mb to 1 failed"
10751
10752         echo "Reset readahead stats"
10753         $LCTL set_param llite.*.read_ahead_stats=0
10754
10755         dd if=$DIR/$tfile of=/dev/null bs=2M
10756
10757         $LCTL get_param llite.*.read_ahead_stats
10758         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10759                      awk '/misses/ { print $2 }')
10760         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10761         rm -f $DIR/$tfile
10762 }
10763 run_test 101i "allow current readahead to exceed reservation"
10764
10765 test_101j() {
10766         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10767                 error "setstripe $DIR/$tfile failed"
10768         local file_size=$((1048576 * 16))
10769         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10770         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10771
10772         echo Disable read-ahead
10773         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10774
10775         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10776         for blk in $PAGE_SIZE 1048576 $file_size; do
10777                 cancel_lru_locks osc
10778                 echo "Reset readahead stats"
10779                 $LCTL set_param -n llite.*.read_ahead_stats=0
10780                 local count=$(($file_size / $blk))
10781                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10782                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10783                              get_named_value 'failed.to.fast.read' | calc_total)
10784                 $LCTL get_param -n llite.*.read_ahead_stats
10785                 [ $miss -eq $count ] || error "expected $count got $miss"
10786         done
10787
10788         rm -f $p $DIR/$tfile
10789 }
10790 run_test 101j "A complete read block should be submitted when no RA"
10791
10792 setup_test102() {
10793         test_mkdir $DIR/$tdir
10794         chown $RUNAS_ID $DIR/$tdir
10795         STRIPE_SIZE=65536
10796         STRIPE_OFFSET=1
10797         STRIPE_COUNT=$OSTCOUNT
10798         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10799
10800         trap cleanup_test102 EXIT
10801         cd $DIR
10802         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10803         cd $DIR/$tdir
10804         for num in 1 2 3 4; do
10805                 for count in $(seq 1 $STRIPE_COUNT); do
10806                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10807                                 local size=`expr $STRIPE_SIZE \* $num`
10808                                 local file=file"$num-$idx-$count"
10809                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10810                         done
10811                 done
10812         done
10813
10814         cd $DIR
10815         $1 tar cf $TMP/f102.tar $tdir --xattrs
10816 }
10817
10818 cleanup_test102() {
10819         trap 0
10820         rm -f $TMP/f102.tar
10821         rm -rf $DIR/d0.sanity/d102
10822 }
10823
10824 test_102a() {
10825         [ "$UID" != 0 ] && skip "must run as root"
10826         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10827                 skip_env "must have user_xattr"
10828
10829         [ -z "$(which setfattr 2>/dev/null)" ] &&
10830                 skip_env "could not find setfattr"
10831
10832         local testfile=$DIR/$tfile
10833
10834         touch $testfile
10835         echo "set/get xattr..."
10836         setfattr -n trusted.name1 -v value1 $testfile ||
10837                 error "setfattr -n trusted.name1=value1 $testfile failed"
10838         getfattr -n trusted.name1 $testfile 2> /dev/null |
10839           grep "trusted.name1=.value1" ||
10840                 error "$testfile missing trusted.name1=value1"
10841
10842         setfattr -n user.author1 -v author1 $testfile ||
10843                 error "setfattr -n user.author1=author1 $testfile failed"
10844         getfattr -n user.author1 $testfile 2> /dev/null |
10845           grep "user.author1=.author1" ||
10846                 error "$testfile missing trusted.author1=author1"
10847
10848         echo "listxattr..."
10849         setfattr -n trusted.name2 -v value2 $testfile ||
10850                 error "$testfile unable to set trusted.name2"
10851         setfattr -n trusted.name3 -v value3 $testfile ||
10852                 error "$testfile unable to set trusted.name3"
10853         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10854             grep "trusted.name" | wc -l) -eq 3 ] ||
10855                 error "$testfile missing 3 trusted.name xattrs"
10856
10857         setfattr -n user.author2 -v author2 $testfile ||
10858                 error "$testfile unable to set user.author2"
10859         setfattr -n user.author3 -v author3 $testfile ||
10860                 error "$testfile unable to set user.author3"
10861         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10862             grep "user.author" | wc -l) -eq 3 ] ||
10863                 error "$testfile missing 3 user.author xattrs"
10864
10865         echo "remove xattr..."
10866         setfattr -x trusted.name1 $testfile ||
10867                 error "$testfile error deleting trusted.name1"
10868         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10869                 error "$testfile did not delete trusted.name1 xattr"
10870
10871         setfattr -x user.author1 $testfile ||
10872                 error "$testfile error deleting user.author1"
10873         echo "set lustre special xattr ..."
10874         $LFS setstripe -c1 $testfile
10875         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10876                 awk -F "=" '/trusted.lov/ { print $2 }' )
10877         setfattr -n "trusted.lov" -v $lovea $testfile ||
10878                 error "$testfile doesn't ignore setting trusted.lov again"
10879         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10880                 error "$testfile allow setting invalid trusted.lov"
10881         rm -f $testfile
10882 }
10883 run_test 102a "user xattr test =================================="
10884
10885 check_102b_layout() {
10886         local layout="$*"
10887         local testfile=$DIR/$tfile
10888
10889         echo "test layout '$layout'"
10890         $LFS setstripe $layout $testfile || error "setstripe failed"
10891         $LFS getstripe -y $testfile
10892
10893         echo "get/set/list trusted.lov xattr ..." # b=10930
10894         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10895         [[ "$value" =~ "trusted.lov" ]] ||
10896                 error "can't get trusted.lov from $testfile"
10897         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10898                 error "getstripe failed"
10899
10900         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10901
10902         value=$(cut -d= -f2 <<<$value)
10903         # LU-13168: truncated xattr should fail if short lov_user_md header
10904         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10905                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10906         for len in $lens; do
10907                 echo "setfattr $len $testfile.2"
10908                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10909                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10910         done
10911         local stripe_size=$($LFS getstripe -S $testfile.2)
10912         local stripe_count=$($LFS getstripe -c $testfile.2)
10913         [[ $stripe_size -eq 65536 ]] ||
10914                 error "stripe size $stripe_size != 65536"
10915         [[ $stripe_count -eq $stripe_count_orig ]] ||
10916                 error "stripe count $stripe_count != $stripe_count_orig"
10917         rm $testfile $testfile.2
10918 }
10919
10920 test_102b() {
10921         [ -z "$(which setfattr 2>/dev/null)" ] &&
10922                 skip_env "could not find setfattr"
10923         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10924
10925         # check plain layout
10926         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10927
10928         # and also check composite layout
10929         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10930
10931 }
10932 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10933
10934 test_102c() {
10935         [ -z "$(which setfattr 2>/dev/null)" ] &&
10936                 skip_env "could not find setfattr"
10937         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10938
10939         # b10930: get/set/list lustre.lov xattr
10940         echo "get/set/list lustre.lov xattr ..."
10941         test_mkdir $DIR/$tdir
10942         chown $RUNAS_ID $DIR/$tdir
10943         local testfile=$DIR/$tdir/$tfile
10944         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10945                 error "setstripe failed"
10946         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10947                 error "getstripe failed"
10948         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10949         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10950
10951         local testfile2=${testfile}2
10952         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10953                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10954
10955         $RUNAS $MCREATE $testfile2
10956         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10957         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10958         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10959         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10960         [ $stripe_count -eq $STRIPECOUNT ] ||
10961                 error "stripe count $stripe_count != $STRIPECOUNT"
10962 }
10963 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10964
10965 compare_stripe_info1() {
10966         local stripe_index_all_zero=true
10967
10968         for num in 1 2 3 4; do
10969                 for count in $(seq 1 $STRIPE_COUNT); do
10970                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10971                                 local size=$((STRIPE_SIZE * num))
10972                                 local file=file"$num-$offset-$count"
10973                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10974                                 [[ $stripe_size -ne $size ]] &&
10975                                     error "$file: size $stripe_size != $size"
10976                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10977                                 # allow fewer stripes to be created, ORI-601
10978                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10979                                     error "$file: count $stripe_count != $count"
10980                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10981                                 [[ $stripe_index -ne 0 ]] &&
10982                                         stripe_index_all_zero=false
10983                         done
10984                 done
10985         done
10986         $stripe_index_all_zero &&
10987                 error "all files are being extracted starting from OST index 0"
10988         return 0
10989 }
10990
10991 have_xattrs_include() {
10992         tar --help | grep -q xattrs-include &&
10993                 echo --xattrs-include="lustre.*"
10994 }
10995
10996 test_102d() {
10997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10998         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10999
11000         XINC=$(have_xattrs_include)
11001         setup_test102
11002         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11003         cd $DIR/$tdir/$tdir
11004         compare_stripe_info1
11005 }
11006 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11007
11008 test_102f() {
11009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11010         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11011
11012         XINC=$(have_xattrs_include)
11013         setup_test102
11014         test_mkdir $DIR/$tdir.restore
11015         cd $DIR
11016         tar cf - --xattrs $tdir | tar xf - \
11017                 -C $DIR/$tdir.restore --xattrs $XINC
11018         cd $DIR/$tdir.restore/$tdir
11019         compare_stripe_info1
11020 }
11021 run_test 102f "tar copy files, not keep osts"
11022
11023 grow_xattr() {
11024         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11025                 skip "must have user_xattr"
11026         [ -z "$(which setfattr 2>/dev/null)" ] &&
11027                 skip_env "could not find setfattr"
11028         [ -z "$(which getfattr 2>/dev/null)" ] &&
11029                 skip_env "could not find getfattr"
11030
11031         local xsize=${1:-1024}  # in bytes
11032         local file=$DIR/$tfile
11033         local value="$(generate_string $xsize)"
11034         local xbig=trusted.big
11035         local toobig=$2
11036
11037         touch $file
11038         log "save $xbig on $file"
11039         if [ -z "$toobig" ]
11040         then
11041                 setfattr -n $xbig -v $value $file ||
11042                         error "saving $xbig on $file failed"
11043         else
11044                 setfattr -n $xbig -v $value $file &&
11045                         error "saving $xbig on $file succeeded"
11046                 return 0
11047         fi
11048
11049         local orig=$(get_xattr_value $xbig $file)
11050         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11051
11052         local xsml=trusted.sml
11053         log "save $xsml on $file"
11054         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11055
11056         local new=$(get_xattr_value $xbig $file)
11057         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11058
11059         log "grow $xsml on $file"
11060         setfattr -n $xsml -v "$value" $file ||
11061                 error "growing $xsml on $file failed"
11062
11063         new=$(get_xattr_value $xbig $file)
11064         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11065         log "$xbig still valid after growing $xsml"
11066
11067         rm -f $file
11068 }
11069
11070 test_102h() { # bug 15777
11071         grow_xattr 1024
11072 }
11073 run_test 102h "grow xattr from inside inode to external block"
11074
11075 test_102ha() {
11076         large_xattr_enabled || skip_env "ea_inode feature disabled"
11077
11078         echo "setting xattr of max xattr size: $(max_xattr_size)"
11079         grow_xattr $(max_xattr_size)
11080
11081         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11082         echo "This should fail:"
11083         grow_xattr $(($(max_xattr_size) + 10)) 1
11084 }
11085 run_test 102ha "grow xattr from inside inode to external inode"
11086
11087 test_102i() { # bug 17038
11088         [ -z "$(which getfattr 2>/dev/null)" ] &&
11089                 skip "could not find getfattr"
11090
11091         touch $DIR/$tfile
11092         ln -s $DIR/$tfile $DIR/${tfile}link
11093         getfattr -n trusted.lov $DIR/$tfile ||
11094                 error "lgetxattr on $DIR/$tfile failed"
11095         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11096                 grep -i "no such attr" ||
11097                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11098         rm -f $DIR/$tfile $DIR/${tfile}link
11099 }
11100 run_test 102i "lgetxattr test on symbolic link ============"
11101
11102 test_102j() {
11103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11104         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11105
11106         XINC=$(have_xattrs_include)
11107         setup_test102 "$RUNAS"
11108         chown $RUNAS_ID $DIR/$tdir
11109         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11110         cd $DIR/$tdir/$tdir
11111         compare_stripe_info1 "$RUNAS"
11112 }
11113 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11114
11115 test_102k() {
11116         [ -z "$(which setfattr 2>/dev/null)" ] &&
11117                 skip "could not find setfattr"
11118
11119         touch $DIR/$tfile
11120         # b22187 just check that does not crash for regular file.
11121         setfattr -n trusted.lov $DIR/$tfile
11122         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11123         local test_kdir=$DIR/$tdir
11124         test_mkdir $test_kdir
11125         local default_size=$($LFS getstripe -S $test_kdir)
11126         local default_count=$($LFS getstripe -c $test_kdir)
11127         local default_offset=$($LFS getstripe -i $test_kdir)
11128         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11129                 error 'dir setstripe failed'
11130         setfattr -n trusted.lov $test_kdir
11131         local stripe_size=$($LFS getstripe -S $test_kdir)
11132         local stripe_count=$($LFS getstripe -c $test_kdir)
11133         local stripe_offset=$($LFS getstripe -i $test_kdir)
11134         [ $stripe_size -eq $default_size ] ||
11135                 error "stripe size $stripe_size != $default_size"
11136         [ $stripe_count -eq $default_count ] ||
11137                 error "stripe count $stripe_count != $default_count"
11138         [ $stripe_offset -eq $default_offset ] ||
11139                 error "stripe offset $stripe_offset != $default_offset"
11140         rm -rf $DIR/$tfile $test_kdir
11141 }
11142 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11143
11144 test_102l() {
11145         [ -z "$(which getfattr 2>/dev/null)" ] &&
11146                 skip "could not find getfattr"
11147
11148         # LU-532 trusted. xattr is invisible to non-root
11149         local testfile=$DIR/$tfile
11150
11151         touch $testfile
11152
11153         echo "listxattr as user..."
11154         chown $RUNAS_ID $testfile
11155         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11156             grep -q "trusted" &&
11157                 error "$testfile trusted xattrs are user visible"
11158
11159         return 0;
11160 }
11161 run_test 102l "listxattr size test =================================="
11162
11163 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11164         local path=$DIR/$tfile
11165         touch $path
11166
11167         listxattr_size_check $path || error "listattr_size_check $path failed"
11168 }
11169 run_test 102m "Ensure listxattr fails on small bufffer ========"
11170
11171 cleanup_test102
11172
11173 getxattr() { # getxattr path name
11174         # Return the base64 encoding of the value of xattr name on path.
11175         local path=$1
11176         local name=$2
11177
11178         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11179         # file: $path
11180         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11181         #
11182         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11183
11184         getfattr --absolute-names --encoding=base64 --name=$name $path |
11185                 awk -F= -v name=$name '$1 == name {
11186                         print substr($0, index($0, "=") + 1);
11187         }'
11188 }
11189
11190 test_102n() { # LU-4101 mdt: protect internal xattrs
11191         [ -z "$(which setfattr 2>/dev/null)" ] &&
11192                 skip "could not find setfattr"
11193         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11194         then
11195                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11196         fi
11197
11198         local file0=$DIR/$tfile.0
11199         local file1=$DIR/$tfile.1
11200         local xattr0=$TMP/$tfile.0
11201         local xattr1=$TMP/$tfile.1
11202         local namelist="lov lma lmv link fid version som hsm"
11203         local name
11204         local value
11205
11206         rm -rf $file0 $file1 $xattr0 $xattr1
11207         touch $file0 $file1
11208
11209         # Get 'before' xattrs of $file1.
11210         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11211
11212         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11213                 namelist+=" lfsck_namespace"
11214         for name in $namelist; do
11215                 # Try to copy xattr from $file0 to $file1.
11216                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11217
11218                 setfattr --name=trusted.$name --value="$value" $file1 ||
11219                         error "setxattr 'trusted.$name' failed"
11220
11221                 # Try to set a garbage xattr.
11222                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11223
11224                 if [[ x$name == "xlov" ]]; then
11225                         setfattr --name=trusted.lov --value="$value" $file1 &&
11226                         error "setxattr invalid 'trusted.lov' success"
11227                 else
11228                         setfattr --name=trusted.$name --value="$value" $file1 ||
11229                                 error "setxattr invalid 'trusted.$name' failed"
11230                 fi
11231
11232                 # Try to remove the xattr from $file1. We don't care if this
11233                 # appears to succeed or fail, we just don't want there to be
11234                 # any changes or crashes.
11235                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11236         done
11237
11238         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11239         then
11240                 name="lfsck_ns"
11241                 # Try to copy xattr from $file0 to $file1.
11242                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11243
11244                 setfattr --name=trusted.$name --value="$value" $file1 ||
11245                         error "setxattr 'trusted.$name' failed"
11246
11247                 # Try to set a garbage xattr.
11248                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11249
11250                 setfattr --name=trusted.$name --value="$value" $file1 ||
11251                         error "setxattr 'trusted.$name' failed"
11252
11253                 # Try to remove the xattr from $file1. We don't care if this
11254                 # appears to succeed or fail, we just don't want there to be
11255                 # any changes or crashes.
11256                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11257         fi
11258
11259         # Get 'after' xattrs of file1.
11260         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11261
11262         if ! diff $xattr0 $xattr1; then
11263                 error "before and after xattrs of '$file1' differ"
11264         fi
11265
11266         rm -rf $file0 $file1 $xattr0 $xattr1
11267
11268         return 0
11269 }
11270 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11271
11272 test_102p() { # LU-4703 setxattr did not check ownership
11273         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11274                 skip "MDS needs to be at least 2.5.56"
11275
11276         local testfile=$DIR/$tfile
11277
11278         touch $testfile
11279
11280         echo "setfacl as user..."
11281         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11282         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11283
11284         echo "setfattr as user..."
11285         setfacl -m "u:$RUNAS_ID:---" $testfile
11286         $RUNAS setfattr -x system.posix_acl_access $testfile
11287         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11288 }
11289 run_test 102p "check setxattr(2) correctly fails without permission"
11290
11291 test_102q() {
11292         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11293                 skip "MDS needs to be at least 2.6.92"
11294
11295         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11296 }
11297 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11298
11299 test_102r() {
11300         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11301                 skip "MDS needs to be at least 2.6.93"
11302
11303         touch $DIR/$tfile || error "touch"
11304         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11305         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11306         rm $DIR/$tfile || error "rm"
11307
11308         #normal directory
11309         mkdir -p $DIR/$tdir || error "mkdir"
11310         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11311         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11312         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11313                 error "$testfile error deleting user.author1"
11314         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11315                 grep "user.$(basename $tdir)" &&
11316                 error "$tdir did not delete user.$(basename $tdir)"
11317         rmdir $DIR/$tdir || error "rmdir"
11318
11319         #striped directory
11320         test_mkdir $DIR/$tdir
11321         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11322         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11323         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11324                 error "$testfile error deleting user.author1"
11325         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11326                 grep "user.$(basename $tdir)" &&
11327                 error "$tdir did not delete user.$(basename $tdir)"
11328         rmdir $DIR/$tdir || error "rm striped dir"
11329 }
11330 run_test 102r "set EAs with empty values"
11331
11332 test_102s() {
11333         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11334                 skip "MDS needs to be at least 2.11.52"
11335
11336         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11337
11338         save_lustre_params client "llite.*.xattr_cache" > $save
11339
11340         for cache in 0 1; do
11341                 lctl set_param llite.*.xattr_cache=$cache
11342
11343                 rm -f $DIR/$tfile
11344                 touch $DIR/$tfile || error "touch"
11345                 for prefix in lustre security system trusted user; do
11346                         # Note getxattr() may fail with 'Operation not
11347                         # supported' or 'No such attribute' depending
11348                         # on prefix and cache.
11349                         getfattr -n $prefix.n102s $DIR/$tfile &&
11350                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11351                 done
11352         done
11353
11354         restore_lustre_params < $save
11355 }
11356 run_test 102s "getting nonexistent xattrs should fail"
11357
11358 test_102t() {
11359         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11360                 skip "MDS needs to be at least 2.11.52"
11361
11362         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11363
11364         save_lustre_params client "llite.*.xattr_cache" > $save
11365
11366         for cache in 0 1; do
11367                 lctl set_param llite.*.xattr_cache=$cache
11368
11369                 for buf_size in 0 256; do
11370                         rm -f $DIR/$tfile
11371                         touch $DIR/$tfile || error "touch"
11372                         setfattr -n user.multiop $DIR/$tfile
11373                         $MULTIOP $DIR/$tfile oa$buf_size ||
11374                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11375                 done
11376         done
11377
11378         restore_lustre_params < $save
11379 }
11380 run_test 102t "zero length xattr values handled correctly"
11381
11382 run_acl_subtest()
11383 {
11384     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11385     return $?
11386 }
11387
11388 test_103a() {
11389         [ "$UID" != 0 ] && skip "must run as root"
11390         $GSS && skip_env "could not run under gss"
11391         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11392                 skip_env "must have acl enabled"
11393         [ -z "$(which setfacl 2>/dev/null)" ] &&
11394                 skip_env "could not find setfacl"
11395         remote_mds_nodsh && skip "remote MDS with nodsh"
11396
11397         gpasswd -a daemon bin                           # LU-5641
11398         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11399
11400         declare -a identity_old
11401
11402         for num in $(seq $MDSCOUNT); do
11403                 switch_identity $num true || identity_old[$num]=$?
11404         done
11405
11406         SAVE_UMASK=$(umask)
11407         umask 0022
11408         mkdir -p $DIR/$tdir
11409         cd $DIR/$tdir
11410
11411         echo "performing cp ..."
11412         run_acl_subtest cp || error "run_acl_subtest cp failed"
11413         echo "performing getfacl-noacl..."
11414         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11415         echo "performing misc..."
11416         run_acl_subtest misc || error  "misc test failed"
11417         echo "performing permissions..."
11418         run_acl_subtest permissions || error "permissions failed"
11419         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11420         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11421                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11422                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11423         then
11424                 echo "performing permissions xattr..."
11425                 run_acl_subtest permissions_xattr ||
11426                         error "permissions_xattr failed"
11427         fi
11428         echo "performing setfacl..."
11429         run_acl_subtest setfacl || error  "setfacl test failed"
11430
11431         # inheritance test got from HP
11432         echo "performing inheritance..."
11433         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11434         chmod +x make-tree || error "chmod +x failed"
11435         run_acl_subtest inheritance || error "inheritance test failed"
11436         rm -f make-tree
11437
11438         echo "LU-974 ignore umask when acl is enabled..."
11439         run_acl_subtest 974 || error "LU-974 umask test failed"
11440         if [ $MDSCOUNT -ge 2 ]; then
11441                 run_acl_subtest 974_remote ||
11442                         error "LU-974 umask test failed under remote dir"
11443         fi
11444
11445         echo "LU-2561 newly created file is same size as directory..."
11446         if [ "$mds1_FSTYPE" != "zfs" ]; then
11447                 run_acl_subtest 2561 || error "LU-2561 test failed"
11448         else
11449                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11450         fi
11451
11452         run_acl_subtest 4924 || error "LU-4924 test failed"
11453
11454         cd $SAVE_PWD
11455         umask $SAVE_UMASK
11456
11457         for num in $(seq $MDSCOUNT); do
11458                 if [ "${identity_old[$num]}" = 1 ]; then
11459                         switch_identity $num false || identity_old[$num]=$?
11460                 fi
11461         done
11462 }
11463 run_test 103a "acl test"
11464
11465 test_103b() {
11466         declare -a pids
11467         local U
11468
11469         for U in {0..511}; do
11470                 {
11471                 local O=$(printf "%04o" $U)
11472
11473                 umask $(printf "%04o" $((511 ^ $O)))
11474                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11475                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11476
11477                 (( $S == ($O & 0666) )) ||
11478                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11479
11480                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11481                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11482                 (( $S == ($O & 0666) )) ||
11483                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11484
11485                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11486                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11487                 (( $S == ($O & 0666) )) ||
11488                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11489                 rm -f $DIR/$tfile.[smp]$0
11490                 } &
11491                 local pid=$!
11492
11493                 # limit the concurrently running threads to 64. LU-11878
11494                 local idx=$((U % 64))
11495                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11496                 pids[idx]=$pid
11497         done
11498         wait
11499 }
11500 run_test 103b "umask lfs setstripe"
11501
11502 test_103c() {
11503         mkdir -p $DIR/$tdir
11504         cp -rp $DIR/$tdir $DIR/$tdir.bak
11505
11506         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11507                 error "$DIR/$tdir shouldn't contain default ACL"
11508         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11509                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11510         true
11511 }
11512 run_test 103c "'cp -rp' won't set empty acl"
11513
11514 test_103e() {
11515         local numacl
11516         local fileacl
11517         local saved_debug=$($LCTL get_param -n debug)
11518
11519         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11520                 skip "MDS needs to be at least 2.14.52"
11521
11522         large_xattr_enabled || skip_env "ea_inode feature disabled"
11523
11524         mkdir -p $DIR/$tdir
11525         # add big LOV EA to cause reply buffer overflow earlier
11526         $LFS setstripe -C 1000 $DIR/$tdir
11527         lctl set_param mdc.*-mdc*.stats=clear
11528
11529         $LCTL set_param debug=0
11530         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11531         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11532
11533         # add a large number of default ACLs (expect 8000+ for 2.13+)
11534         for U in {2..7000}; do
11535                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11536                         error "Able to add just $U default ACLs"
11537         done
11538         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11539         echo "$numacl default ACLs created"
11540
11541         stat $DIR/$tdir || error "Cannot stat directory"
11542         # check file creation
11543         touch $DIR/$tdir/$tfile ||
11544                 error "failed to create $tfile with $numacl default ACLs"
11545         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11546         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11547         echo "$fileacl ACLs were inherited"
11548         (( $fileacl == $numacl )) ||
11549                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11550         # check that new ACLs creation adds new ACLs to inherited ACLs
11551         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11552                 error "Cannot set new ACL"
11553         numacl=$((numacl + 1))
11554         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11555         (( $fileacl == $numacl )) ||
11556                 error "failed to add new ACL: $fileacl != $numacl as expected"
11557         # adds more ACLs to a file to reach their maximum at 8000+
11558         numacl=0
11559         for U in {20000..25000}; do
11560                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11561                 numacl=$((numacl + 1))
11562         done
11563         echo "Added $numacl more ACLs to the file"
11564         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11565         echo "Total $fileacl ACLs in file"
11566         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11567         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11568         rmdir $DIR/$tdir || error "Cannot remove directory"
11569 }
11570 run_test 103e "inheritance of big amount of default ACLs"
11571
11572 test_103f() {
11573         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11574                 skip "MDS needs to be at least 2.14.51"
11575
11576         large_xattr_enabled || skip_env "ea_inode feature disabled"
11577
11578         # enable changelog to consume more internal MDD buffers
11579         changelog_register
11580
11581         mkdir -p $DIR/$tdir
11582         # add big LOV EA
11583         $LFS setstripe -C 1000 $DIR/$tdir
11584         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11585         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11586         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11587         rmdir $DIR/$tdir || error "Cannot remove directory"
11588 }
11589 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11590
11591 test_104a() {
11592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11593
11594         touch $DIR/$tfile
11595         lfs df || error "lfs df failed"
11596         lfs df -ih || error "lfs df -ih failed"
11597         lfs df -h $DIR || error "lfs df -h $DIR failed"
11598         lfs df -i $DIR || error "lfs df -i $DIR failed"
11599         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11600         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11601
11602         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11603         lctl --device %$OSC deactivate
11604         lfs df || error "lfs df with deactivated OSC failed"
11605         lctl --device %$OSC activate
11606         # wait the osc back to normal
11607         wait_osc_import_ready client ost
11608
11609         lfs df || error "lfs df with reactivated OSC failed"
11610         rm -f $DIR/$tfile
11611 }
11612 run_test 104a "lfs df [-ih] [path] test ========================="
11613
11614 test_104b() {
11615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11616         [ $RUNAS_ID -eq $UID ] &&
11617                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11618
11619         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11620                         grep "Permission denied" | wc -l)))
11621         if [ $denied_cnt -ne 0 ]; then
11622                 error "lfs check servers test failed"
11623         fi
11624 }
11625 run_test 104b "$RUNAS lfs check servers test ===================="
11626
11627 #
11628 # Verify $1 is within range of $2.
11629 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11630 # $1 is <= 2% of $2. Else Fail.
11631 #
11632 value_in_range() {
11633         # Strip all units (M, G, T)
11634         actual=$(echo $1 | tr -d A-Z)
11635         expect=$(echo $2 | tr -d A-Z)
11636
11637         expect_lo=$(($expect * 98 / 100)) # 2% below
11638         expect_hi=$(($expect * 102 / 100)) # 2% above
11639
11640         # permit 2% drift above and below
11641         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11642 }
11643
11644 test_104c() {
11645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11646         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11647
11648         local ost_param="osd-zfs.$FSNAME-OST0000."
11649         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11650         local ofacets=$(get_facets OST)
11651         local mfacets=$(get_facets MDS)
11652         local saved_ost_blocks=
11653         local saved_mdt_blocks=
11654
11655         echo "Before recordsize change"
11656         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11657         df=($(df -h | grep "$MOUNT"$))
11658
11659         # For checking.
11660         echo "lfs output : ${lfs_df[*]}"
11661         echo "df  output : ${df[*]}"
11662
11663         for facet in ${ofacets//,/ }; do
11664                 if [ -z $saved_ost_blocks ]; then
11665                         saved_ost_blocks=$(do_facet $facet \
11666                                 lctl get_param -n $ost_param.blocksize)
11667                         echo "OST Blocksize: $saved_ost_blocks"
11668                 fi
11669                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11670                 do_facet $facet zfs set recordsize=32768 $ost
11671         done
11672
11673         # BS too small. Sufficient for functional testing.
11674         for facet in ${mfacets//,/ }; do
11675                 if [ -z $saved_mdt_blocks ]; then
11676                         saved_mdt_blocks=$(do_facet $facet \
11677                                 lctl get_param -n $mdt_param.blocksize)
11678                         echo "MDT Blocksize: $saved_mdt_blocks"
11679                 fi
11680                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11681                 do_facet $facet zfs set recordsize=32768 $mdt
11682         done
11683
11684         # Give new values chance to reflect change
11685         sleep 2
11686
11687         echo "After recordsize change"
11688         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11689         df_after=($(df -h | grep "$MOUNT"$))
11690
11691         # For checking.
11692         echo "lfs output : ${lfs_df_after[*]}"
11693         echo "df  output : ${df_after[*]}"
11694
11695         # Verify lfs df
11696         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11697                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11698         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11699                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11700         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11701                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11702
11703         # Verify df
11704         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11705                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11706         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11707                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11708         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11709                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11710
11711         # Restore MDT recordize back to original
11712         for facet in ${mfacets//,/ }; do
11713                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11714                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11715         done
11716
11717         # Restore OST recordize back to original
11718         for facet in ${ofacets//,/ }; do
11719                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11720                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11721         done
11722
11723         return 0
11724 }
11725 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11726
11727 test_105a() {
11728         # doesn't work on 2.4 kernels
11729         touch $DIR/$tfile
11730         if $(flock_is_enabled); then
11731                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11732         else
11733                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11734         fi
11735         rm -f $DIR/$tfile
11736 }
11737 run_test 105a "flock when mounted without -o flock test ========"
11738
11739 test_105b() {
11740         touch $DIR/$tfile
11741         if $(flock_is_enabled); then
11742                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11743         else
11744                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11745         fi
11746         rm -f $DIR/$tfile
11747 }
11748 run_test 105b "fcntl when mounted without -o flock test ========"
11749
11750 test_105c() {
11751         touch $DIR/$tfile
11752         if $(flock_is_enabled); then
11753                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11754         else
11755                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11756         fi
11757         rm -f $DIR/$tfile
11758 }
11759 run_test 105c "lockf when mounted without -o flock test"
11760
11761 test_105d() { # bug 15924
11762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11763
11764         test_mkdir $DIR/$tdir
11765         flock_is_enabled || skip_env "mount w/o flock enabled"
11766         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11767         $LCTL set_param fail_loc=0x80000315
11768         flocks_test 2 $DIR/$tdir
11769 }
11770 run_test 105d "flock race (should not freeze) ========"
11771
11772 test_105e() { # bug 22660 && 22040
11773         flock_is_enabled || skip_env "mount w/o flock enabled"
11774
11775         touch $DIR/$tfile
11776         flocks_test 3 $DIR/$tfile
11777 }
11778 run_test 105e "Two conflicting flocks from same process"
11779
11780 test_106() { #bug 10921
11781         test_mkdir $DIR/$tdir
11782         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11783         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11784 }
11785 run_test 106 "attempt exec of dir followed by chown of that dir"
11786
11787 test_107() {
11788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11789
11790         CDIR=`pwd`
11791         local file=core
11792
11793         cd $DIR
11794         rm -f $file
11795
11796         local save_pattern=$(sysctl -n kernel.core_pattern)
11797         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11798         sysctl -w kernel.core_pattern=$file
11799         sysctl -w kernel.core_uses_pid=0
11800
11801         ulimit -c unlimited
11802         sleep 60 &
11803         SLEEPPID=$!
11804
11805         sleep 1
11806
11807         kill -s 11 $SLEEPPID
11808         wait $SLEEPPID
11809         if [ -e $file ]; then
11810                 size=`stat -c%s $file`
11811                 [ $size -eq 0 ] && error "Fail to create core file $file"
11812         else
11813                 error "Fail to create core file $file"
11814         fi
11815         rm -f $file
11816         sysctl -w kernel.core_pattern=$save_pattern
11817         sysctl -w kernel.core_uses_pid=$save_uses_pid
11818         cd $CDIR
11819 }
11820 run_test 107 "Coredump on SIG"
11821
11822 test_110() {
11823         test_mkdir $DIR/$tdir
11824         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11825         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11826                 error "mkdir with 256 char should fail, but did not"
11827         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11828                 error "create with 255 char failed"
11829         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11830                 error "create with 256 char should fail, but did not"
11831
11832         ls -l $DIR/$tdir
11833         rm -rf $DIR/$tdir
11834 }
11835 run_test 110 "filename length checking"
11836
11837 #
11838 # Purpose: To verify dynamic thread (OSS) creation.
11839 #
11840 test_115() {
11841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11842         remote_ost_nodsh && skip "remote OST with nodsh"
11843
11844         # Lustre does not stop service threads once they are started.
11845         # Reset number of running threads to default.
11846         stopall
11847         setupall
11848
11849         local OSTIO_pre
11850         local save_params="$TMP/sanity-$TESTNAME.parameters"
11851
11852         # Get ll_ost_io count before I/O
11853         OSTIO_pre=$(do_facet ost1 \
11854                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11855         # Exit if lustre is not running (ll_ost_io not running).
11856         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11857
11858         echo "Starting with $OSTIO_pre threads"
11859         local thread_max=$((OSTIO_pre * 2))
11860         local rpc_in_flight=$((thread_max * 2))
11861         # this is limited to OSC_MAX_RIF_MAX (256)
11862         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
11863         thread_max=$((rpc_in_flight / 2))
11864         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
11865                 return
11866
11867         # Number of I/O Process proposed to be started.
11868         local nfiles
11869         local facets=$(get_facets OST)
11870
11871         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11872         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11873
11874         # Set in_flight to $rpc_in_flight
11875         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11876                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11877         nfiles=${rpc_in_flight}
11878         # Set ost thread_max to $thread_max
11879         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11880
11881         # 5 Minutes should be sufficient for max number of OSS
11882         # threads(thread_max) to be created.
11883         local timeout=300
11884
11885         # Start I/O.
11886         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11887         test_mkdir $DIR/$tdir
11888         for i in $(seq $nfiles); do
11889                 local file=$DIR/$tdir/${tfile}-$i
11890                 $LFS setstripe -c -1 -i 0 $file
11891                 ($WTL $file $timeout)&
11892         done
11893
11894         # I/O Started - Wait for thread_started to reach thread_max or report
11895         # error if thread_started is more than thread_max.
11896         echo "Waiting for thread_started to reach thread_max"
11897         local thread_started=0
11898         local end_time=$((SECONDS + timeout))
11899
11900         while [ $SECONDS -le $end_time ] ; do
11901                 echo -n "."
11902                 # Get ost i/o thread_started count.
11903                 thread_started=$(do_facet ost1 \
11904                         "$LCTL get_param \
11905                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11906                 # Break out if thread_started is equal/greater than thread_max
11907                 if [[ $thread_started -ge $thread_max ]]; then
11908                         echo ll_ost_io thread_started $thread_started, \
11909                                 equal/greater than thread_max $thread_max
11910                         break
11911                 fi
11912                 sleep 1
11913         done
11914
11915         # Cleanup - We have the numbers, Kill i/o jobs if running.
11916         jobcount=($(jobs -p))
11917         for i in $(seq 0 $((${#jobcount[@]}-1)))
11918         do
11919                 kill -9 ${jobcount[$i]}
11920                 if [ $? -ne 0 ] ; then
11921                         echo Warning: \
11922                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11923                 fi
11924         done
11925
11926         # Cleanup files left by WTL binary.
11927         for i in $(seq $nfiles); do
11928                 local file=$DIR/$tdir/${tfile}-$i
11929                 rm -rf $file
11930                 if [ $? -ne 0 ] ; then
11931                         echo "Warning: Failed to delete file $file"
11932                 fi
11933         done
11934
11935         restore_lustre_params <$save_params
11936         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11937
11938         # Error out if no new thread has started or Thread started is greater
11939         # than thread max.
11940         if [[ $thread_started -le $OSTIO_pre ||
11941                         $thread_started -gt $thread_max ]]; then
11942                 error "ll_ost_io: thread_started $thread_started" \
11943                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11944                       "No new thread started or thread started greater " \
11945                       "than thread_max."
11946         fi
11947 }
11948 run_test 115 "verify dynamic thread creation===================="
11949
11950 test_116a() { # was previously test_116()
11951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11952         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11953         remote_mds_nodsh && skip "remote MDS with nodsh"
11954
11955         echo -n "Free space priority "
11956         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11957                 head -n1
11958         declare -a AVAIL
11959         free_min_max
11960
11961         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11962         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11963         stack_trap simple_cleanup_common
11964
11965         # Check if we need to generate uneven OSTs
11966         test_mkdir -p $DIR/$tdir/OST${MINI}
11967         local FILL=$((MINV / 4))
11968         local DIFF=$((MAXV - MINV))
11969         local DIFF2=$((DIFF * 100 / MINV))
11970
11971         local threshold=$(do_facet $SINGLEMDS \
11972                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11973         threshold=${threshold%%%}
11974         echo -n "Check for uneven OSTs: "
11975         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11976
11977         if [[ $DIFF2 -gt $threshold ]]; then
11978                 echo "ok"
11979                 echo "Don't need to fill OST$MINI"
11980         else
11981                 # generate uneven OSTs. Write 2% over the QOS threshold value
11982                 echo "no"
11983                 DIFF=$((threshold - DIFF2 + 2))
11984                 DIFF2=$((MINV * DIFF / 100))
11985                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11986                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11987                         error "setstripe failed"
11988                 DIFF=$((DIFF2 / 2048))
11989                 i=0
11990                 while [ $i -lt $DIFF ]; do
11991                         i=$((i + 1))
11992                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11993                                 bs=2M count=1 2>/dev/null
11994                         echo -n .
11995                 done
11996                 echo .
11997                 sync
11998                 sleep_maxage
11999                 free_min_max
12000         fi
12001
12002         DIFF=$((MAXV - MINV))
12003         DIFF2=$((DIFF * 100 / MINV))
12004         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12005         if [ $DIFF2 -gt $threshold ]; then
12006                 echo "ok"
12007         else
12008                 skip "QOS imbalance criteria not met"
12009         fi
12010
12011         MINI1=$MINI
12012         MINV1=$MINV
12013         MAXI1=$MAXI
12014         MAXV1=$MAXV
12015
12016         # now fill using QOS
12017         $LFS setstripe -c 1 $DIR/$tdir
12018         FILL=$((FILL / 200))
12019         if [ $FILL -gt 600 ]; then
12020                 FILL=600
12021         fi
12022         echo "writing $FILL files to QOS-assigned OSTs"
12023         i=0
12024         while [ $i -lt $FILL ]; do
12025                 i=$((i + 1))
12026                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12027                         count=1 2>/dev/null
12028                 echo -n .
12029         done
12030         echo "wrote $i 200k files"
12031         sync
12032         sleep_maxage
12033
12034         echo "Note: free space may not be updated, so measurements might be off"
12035         free_min_max
12036         DIFF2=$((MAXV - MINV))
12037         echo "free space delta: orig $DIFF final $DIFF2"
12038         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12039         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12040         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12041         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12042         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12043         if [[ $DIFF -gt 0 ]]; then
12044                 FILL=$((DIFF2 * 100 / DIFF - 100))
12045                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12046         fi
12047
12048         # Figure out which files were written where
12049         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12050                awk '/'$MINI1': / {print $2; exit}')
12051         echo $UUID
12052         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12053         echo "$MINC files created on smaller OST $MINI1"
12054         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12055                awk '/'$MAXI1': / {print $2; exit}')
12056         echo $UUID
12057         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12058         echo "$MAXC files created on larger OST $MAXI1"
12059         if [[ $MINC -gt 0 ]]; then
12060                 FILL=$((MAXC * 100 / MINC - 100))
12061                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12062         fi
12063         [[ $MAXC -gt $MINC ]] ||
12064                 error_ignore LU-9 "stripe QOS didn't balance free space"
12065 }
12066 run_test 116a "stripe QOS: free space balance ==================="
12067
12068 test_116b() { # LU-2093
12069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12070         remote_mds_nodsh && skip "remote MDS with nodsh"
12071
12072 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12073         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12074                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12075         [ -z "$old_rr" ] && skip "no QOS"
12076         do_facet $SINGLEMDS lctl set_param \
12077                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12078         mkdir -p $DIR/$tdir
12079         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12080         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12081         do_facet $SINGLEMDS lctl set_param fail_loc=0
12082         rm -rf $DIR/$tdir
12083         do_facet $SINGLEMDS lctl set_param \
12084                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12085 }
12086 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12087
12088 test_117() # bug 10891
12089 {
12090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12091
12092         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12093         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12094         lctl set_param fail_loc=0x21e
12095         > $DIR/$tfile || error "truncate failed"
12096         lctl set_param fail_loc=0
12097         echo "Truncate succeeded."
12098         rm -f $DIR/$tfile
12099 }
12100 run_test 117 "verify osd extend =========="
12101
12102 NO_SLOW_RESENDCOUNT=4
12103 export OLD_RESENDCOUNT=""
12104 set_resend_count () {
12105         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12106         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12107         lctl set_param -n $PROC_RESENDCOUNT $1
12108         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12109 }
12110
12111 # for reduce test_118* time (b=14842)
12112 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12113
12114 # Reset async IO behavior after error case
12115 reset_async() {
12116         FILE=$DIR/reset_async
12117
12118         # Ensure all OSCs are cleared
12119         $LFS setstripe -c -1 $FILE
12120         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12121         sync
12122         rm $FILE
12123 }
12124
12125 test_118a() #bug 11710
12126 {
12127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12128
12129         reset_async
12130
12131         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12132         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12133         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12134
12135         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12136                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12137                 return 1;
12138         fi
12139         rm -f $DIR/$tfile
12140 }
12141 run_test 118a "verify O_SYNC works =========="
12142
12143 test_118b()
12144 {
12145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12146         remote_ost_nodsh && skip "remote OST with nodsh"
12147
12148         reset_async
12149
12150         #define OBD_FAIL_SRV_ENOENT 0x217
12151         set_nodes_failloc "$(osts_nodes)" 0x217
12152         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12153         RC=$?
12154         set_nodes_failloc "$(osts_nodes)" 0
12155         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12156         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12157                     grep -c writeback)
12158
12159         if [[ $RC -eq 0 ]]; then
12160                 error "Must return error due to dropped pages, rc=$RC"
12161                 return 1;
12162         fi
12163
12164         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12165                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12166                 return 1;
12167         fi
12168
12169         echo "Dirty pages not leaked on ENOENT"
12170
12171         # Due to the above error the OSC will issue all RPCs syncronously
12172         # until a subsequent RPC completes successfully without error.
12173         $MULTIOP $DIR/$tfile Ow4096yc
12174         rm -f $DIR/$tfile
12175
12176         return 0
12177 }
12178 run_test 118b "Reclaim dirty pages on fatal error =========="
12179
12180 test_118c()
12181 {
12182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12183
12184         # for 118c, restore the original resend count, LU-1940
12185         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12186                                 set_resend_count $OLD_RESENDCOUNT
12187         remote_ost_nodsh && skip "remote OST with nodsh"
12188
12189         reset_async
12190
12191         #define OBD_FAIL_OST_EROFS               0x216
12192         set_nodes_failloc "$(osts_nodes)" 0x216
12193
12194         # multiop should block due to fsync until pages are written
12195         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12196         MULTIPID=$!
12197         sleep 1
12198
12199         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12200                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12201         fi
12202
12203         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12204                     grep -c writeback)
12205         if [[ $WRITEBACK -eq 0 ]]; then
12206                 error "No page in writeback, writeback=$WRITEBACK"
12207         fi
12208
12209         set_nodes_failloc "$(osts_nodes)" 0
12210         wait $MULTIPID
12211         RC=$?
12212         if [[ $RC -ne 0 ]]; then
12213                 error "Multiop fsync failed, rc=$RC"
12214         fi
12215
12216         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12217         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12218                     grep -c writeback)
12219         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12220                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12221         fi
12222
12223         rm -f $DIR/$tfile
12224         echo "Dirty pages flushed via fsync on EROFS"
12225         return 0
12226 }
12227 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12228
12229 # continue to use small resend count to reduce test_118* time (b=14842)
12230 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12231
12232 test_118d()
12233 {
12234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12235         remote_ost_nodsh && skip "remote OST with nodsh"
12236
12237         reset_async
12238
12239         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12240         set_nodes_failloc "$(osts_nodes)" 0x214
12241         # multiop should block due to fsync until pages are written
12242         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12243         MULTIPID=$!
12244         sleep 1
12245
12246         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12247                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12248         fi
12249
12250         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12251                     grep -c writeback)
12252         if [[ $WRITEBACK -eq 0 ]]; then
12253                 error "No page in writeback, writeback=$WRITEBACK"
12254         fi
12255
12256         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12257         set_nodes_failloc "$(osts_nodes)" 0
12258
12259         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12260         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12261                     grep -c writeback)
12262         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12263                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12264         fi
12265
12266         rm -f $DIR/$tfile
12267         echo "Dirty pages gaurenteed flushed via fsync"
12268         return 0
12269 }
12270 run_test 118d "Fsync validation inject a delay of the bulk =========="
12271
12272 test_118f() {
12273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12274
12275         reset_async
12276
12277         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12278         lctl set_param fail_loc=0x8000040a
12279
12280         # Should simulate EINVAL error which is fatal
12281         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12282         RC=$?
12283         if [[ $RC -eq 0 ]]; then
12284                 error "Must return error due to dropped pages, rc=$RC"
12285         fi
12286
12287         lctl set_param fail_loc=0x0
12288
12289         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12290         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12291         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12292                     grep -c writeback)
12293         if [[ $LOCKED -ne 0 ]]; then
12294                 error "Locked pages remain in cache, locked=$LOCKED"
12295         fi
12296
12297         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12298                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12299         fi
12300
12301         rm -f $DIR/$tfile
12302         echo "No pages locked after fsync"
12303
12304         reset_async
12305         return 0
12306 }
12307 run_test 118f "Simulate unrecoverable OSC side error =========="
12308
12309 test_118g() {
12310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12311
12312         reset_async
12313
12314         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12315         lctl set_param fail_loc=0x406
12316
12317         # simulate local -ENOMEM
12318         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12319         RC=$?
12320
12321         lctl set_param fail_loc=0
12322         if [[ $RC -eq 0 ]]; then
12323                 error "Must return error due to dropped pages, rc=$RC"
12324         fi
12325
12326         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12327         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12328         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12329                         grep -c writeback)
12330         if [[ $LOCKED -ne 0 ]]; then
12331                 error "Locked pages remain in cache, locked=$LOCKED"
12332         fi
12333
12334         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12335                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12336         fi
12337
12338         rm -f $DIR/$tfile
12339         echo "No pages locked after fsync"
12340
12341         reset_async
12342         return 0
12343 }
12344 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12345
12346 test_118h() {
12347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12348         remote_ost_nodsh && skip "remote OST with nodsh"
12349
12350         reset_async
12351
12352         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12353         set_nodes_failloc "$(osts_nodes)" 0x20e
12354         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12355         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12356         RC=$?
12357
12358         set_nodes_failloc "$(osts_nodes)" 0
12359         if [[ $RC -eq 0 ]]; then
12360                 error "Must return error due to dropped pages, rc=$RC"
12361         fi
12362
12363         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12364         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12365         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12366                     grep -c writeback)
12367         if [[ $LOCKED -ne 0 ]]; then
12368                 error "Locked pages remain in cache, locked=$LOCKED"
12369         fi
12370
12371         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12372                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12373         fi
12374
12375         rm -f $DIR/$tfile
12376         echo "No pages locked after fsync"
12377
12378         return 0
12379 }
12380 run_test 118h "Verify timeout in handling recoverables errors  =========="
12381
12382 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12383
12384 test_118i() {
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
12393         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12394         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12395         PID=$!
12396         sleep 5
12397         set_nodes_failloc "$(osts_nodes)" 0
12398
12399         wait $PID
12400         RC=$?
12401         if [[ $RC -ne 0 ]]; then
12402                 error "got error, but should be not, rc=$RC"
12403         fi
12404
12405         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12406         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12407         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12408         if [[ $LOCKED -ne 0 ]]; then
12409                 error "Locked pages remain in cache, locked=$LOCKED"
12410         fi
12411
12412         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12413                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12414         fi
12415
12416         rm -f $DIR/$tfile
12417         echo "No pages locked after fsync"
12418
12419         return 0
12420 }
12421 run_test 118i "Fix error before timeout in recoverable error  =========="
12422
12423 [ "$SLOW" = "no" ] && set_resend_count 4
12424
12425 test_118j() {
12426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12427         remote_ost_nodsh && skip "remote OST with nodsh"
12428
12429         reset_async
12430
12431         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12432         set_nodes_failloc "$(osts_nodes)" 0x220
12433
12434         # return -EIO from OST
12435         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12436         RC=$?
12437         set_nodes_failloc "$(osts_nodes)" 0x0
12438         if [[ $RC -eq 0 ]]; then
12439                 error "Must return error due to dropped pages, rc=$RC"
12440         fi
12441
12442         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12443         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12444         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12445         if [[ $LOCKED -ne 0 ]]; then
12446                 error "Locked pages remain in cache, locked=$LOCKED"
12447         fi
12448
12449         # in recoverable error on OST we want resend and stay until it finished
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 118j "Simulate unrecoverable OST side error =========="
12460
12461 test_118k()
12462 {
12463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12464         remote_ost_nodsh && skip "remote OSTs with nodsh"
12465
12466         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12467         set_nodes_failloc "$(osts_nodes)" 0x20e
12468         test_mkdir $DIR/$tdir
12469
12470         for ((i=0;i<10;i++)); do
12471                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12472                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12473                 SLEEPPID=$!
12474                 sleep 0.500s
12475                 kill $SLEEPPID
12476                 wait $SLEEPPID
12477         done
12478
12479         set_nodes_failloc "$(osts_nodes)" 0
12480         rm -rf $DIR/$tdir
12481 }
12482 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12483
12484 test_118l() # LU-646
12485 {
12486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12487
12488         test_mkdir $DIR/$tdir
12489         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12490         rm -rf $DIR/$tdir
12491 }
12492 run_test 118l "fsync dir"
12493
12494 test_118m() # LU-3066
12495 {
12496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12497
12498         test_mkdir $DIR/$tdir
12499         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12500         rm -rf $DIR/$tdir
12501 }
12502 run_test 118m "fdatasync dir ========="
12503
12504 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12505
12506 test_118n()
12507 {
12508         local begin
12509         local end
12510
12511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12512         remote_ost_nodsh && skip "remote OSTs with nodsh"
12513
12514         # Sleep to avoid a cached response.
12515         #define OBD_STATFS_CACHE_SECONDS 1
12516         sleep 2
12517
12518         # Inject a 10 second delay in the OST_STATFS handler.
12519         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12520         set_nodes_failloc "$(osts_nodes)" 0x242
12521
12522         begin=$SECONDS
12523         stat --file-system $MOUNT > /dev/null
12524         end=$SECONDS
12525
12526         set_nodes_failloc "$(osts_nodes)" 0
12527
12528         if ((end - begin > 20)); then
12529             error "statfs took $((end - begin)) seconds, expected 10"
12530         fi
12531 }
12532 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12533
12534 test_119a() # bug 11737
12535 {
12536         BSIZE=$((512 * 1024))
12537         directio write $DIR/$tfile 0 1 $BSIZE
12538         # We ask to read two blocks, which is more than a file size.
12539         # directio will indicate an error when requested and actual
12540         # sizes aren't equeal (a normal situation in this case) and
12541         # print actual read amount.
12542         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12543         if [ "$NOB" != "$BSIZE" ]; then
12544                 error "read $NOB bytes instead of $BSIZE"
12545         fi
12546         rm -f $DIR/$tfile
12547 }
12548 run_test 119a "Short directIO read must return actual read amount"
12549
12550 test_119b() # bug 11737
12551 {
12552         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12553
12554         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12555         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12556         sync
12557         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12558                 error "direct read failed"
12559         rm -f $DIR/$tfile
12560 }
12561 run_test 119b "Sparse directIO read must return actual read amount"
12562
12563 test_119c() # bug 13099
12564 {
12565         BSIZE=1048576
12566         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12567         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12568         rm -f $DIR/$tfile
12569 }
12570 run_test 119c "Testing for direct read hitting hole"
12571
12572 test_119d() # bug 15950
12573 {
12574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12575
12576         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12577         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12578         BSIZE=1048576
12579         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12580         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12581         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12582         lctl set_param fail_loc=0x40d
12583         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12584         pid_dio=$!
12585         sleep 1
12586         cat $DIR/$tfile > /dev/null &
12587         lctl set_param fail_loc=0
12588         pid_reads=$!
12589         wait $pid_dio
12590         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12591         sleep 2
12592         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12593         error "the read rpcs have not completed in 2s"
12594         rm -f $DIR/$tfile
12595         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12596 }
12597 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12598
12599 test_120a() {
12600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12601         remote_mds_nodsh && skip "remote MDS with nodsh"
12602         test_mkdir -i0 -c1 $DIR/$tdir
12603         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12604                 skip_env "no early lock cancel on server"
12605
12606         lru_resize_disable mdc
12607         lru_resize_disable osc
12608         cancel_lru_locks mdc
12609         # asynchronous object destroy at MDT could cause bl ast to client
12610         cancel_lru_locks osc
12611
12612         stat $DIR/$tdir > /dev/null
12613         can1=$(do_facet mds1 \
12614                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12615                awk '/ldlm_cancel/ {print $2}')
12616         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12617                awk '/ldlm_bl_callback/ {print $2}')
12618         test_mkdir -i0 -c1 $DIR/$tdir/d1
12619         can2=$(do_facet mds1 \
12620                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12621                awk '/ldlm_cancel/ {print $2}')
12622         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12623                awk '/ldlm_bl_callback/ {print $2}')
12624         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12625         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12626         lru_resize_enable mdc
12627         lru_resize_enable osc
12628 }
12629 run_test 120a "Early Lock Cancel: mkdir test"
12630
12631 test_120b() {
12632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12633         remote_mds_nodsh && skip "remote MDS with nodsh"
12634         test_mkdir $DIR/$tdir
12635         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12636                 skip_env "no early lock cancel on server"
12637
12638         lru_resize_disable mdc
12639         lru_resize_disable osc
12640         cancel_lru_locks mdc
12641         stat $DIR/$tdir > /dev/null
12642         can1=$(do_facet $SINGLEMDS \
12643                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12644                awk '/ldlm_cancel/ {print $2}')
12645         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12646                awk '/ldlm_bl_callback/ {print $2}')
12647         touch $DIR/$tdir/f1
12648         can2=$(do_facet $SINGLEMDS \
12649                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12650                awk '/ldlm_cancel/ {print $2}')
12651         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12652                awk '/ldlm_bl_callback/ {print $2}')
12653         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12654         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12655         lru_resize_enable mdc
12656         lru_resize_enable osc
12657 }
12658 run_test 120b "Early Lock Cancel: create test"
12659
12660 test_120c() {
12661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12662         remote_mds_nodsh && skip "remote MDS with nodsh"
12663         test_mkdir -i0 -c1 $DIR/$tdir
12664         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12665                 skip "no early lock cancel on server"
12666
12667         lru_resize_disable mdc
12668         lru_resize_disable osc
12669         test_mkdir -i0 -c1 $DIR/$tdir/d1
12670         test_mkdir -i0 -c1 $DIR/$tdir/d2
12671         touch $DIR/$tdir/d1/f1
12672         cancel_lru_locks mdc
12673         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12674         can1=$(do_facet mds1 \
12675                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12676                awk '/ldlm_cancel/ {print $2}')
12677         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12678                awk '/ldlm_bl_callback/ {print $2}')
12679         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12680         can2=$(do_facet mds1 \
12681                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12682                awk '/ldlm_cancel/ {print $2}')
12683         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12684                awk '/ldlm_bl_callback/ {print $2}')
12685         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12686         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12687         lru_resize_enable mdc
12688         lru_resize_enable osc
12689 }
12690 run_test 120c "Early Lock Cancel: link test"
12691
12692 test_120d() {
12693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12694         remote_mds_nodsh && skip "remote MDS with nodsh"
12695         test_mkdir -i0 -c1 $DIR/$tdir
12696         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12697                 skip_env "no early lock cancel on server"
12698
12699         lru_resize_disable mdc
12700         lru_resize_disable osc
12701         touch $DIR/$tdir
12702         cancel_lru_locks mdc
12703         stat $DIR/$tdir > /dev/null
12704         can1=$(do_facet mds1 \
12705                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12706                awk '/ldlm_cancel/ {print $2}')
12707         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12708                awk '/ldlm_bl_callback/ {print $2}')
12709         chmod a+x $DIR/$tdir
12710         can2=$(do_facet mds1 \
12711                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12712                awk '/ldlm_cancel/ {print $2}')
12713         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12714                awk '/ldlm_bl_callback/ {print $2}')
12715         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12716         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12717         lru_resize_enable mdc
12718         lru_resize_enable osc
12719 }
12720 run_test 120d "Early Lock Cancel: setattr test"
12721
12722 test_120e() {
12723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12724         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12725                 skip_env "no early lock cancel on server"
12726         remote_mds_nodsh && skip "remote MDS with nodsh"
12727
12728         local dlmtrace_set=false
12729
12730         test_mkdir -i0 -c1 $DIR/$tdir
12731         lru_resize_disable mdc
12732         lru_resize_disable osc
12733         ! $LCTL get_param debug | grep -q dlmtrace &&
12734                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12735         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12736         cancel_lru_locks mdc
12737         cancel_lru_locks osc
12738         dd if=$DIR/$tdir/f1 of=/dev/null
12739         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12740         # XXX client can not do early lock cancel of OST lock
12741         # during unlink (LU-4206), so cancel osc lock now.
12742         sleep 2
12743         cancel_lru_locks osc
12744         can1=$(do_facet mds1 \
12745                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12746                awk '/ldlm_cancel/ {print $2}')
12747         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12748                awk '/ldlm_bl_callback/ {print $2}')
12749         unlink $DIR/$tdir/f1
12750         sleep 5
12751         can2=$(do_facet mds1 \
12752                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12753                awk '/ldlm_cancel/ {print $2}')
12754         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12755                awk '/ldlm_bl_callback/ {print $2}')
12756         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12757                 $LCTL dk $TMP/cancel.debug.txt
12758         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12759                 $LCTL dk $TMP/blocking.debug.txt
12760         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12761         lru_resize_enable mdc
12762         lru_resize_enable osc
12763 }
12764 run_test 120e "Early Lock Cancel: unlink test"
12765
12766 test_120f() {
12767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12768         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12769                 skip_env "no early lock cancel on server"
12770         remote_mds_nodsh && skip "remote MDS with nodsh"
12771
12772         test_mkdir -i0 -c1 $DIR/$tdir
12773         lru_resize_disable mdc
12774         lru_resize_disable osc
12775         test_mkdir -i0 -c1 $DIR/$tdir/d1
12776         test_mkdir -i0 -c1 $DIR/$tdir/d2
12777         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12778         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12779         cancel_lru_locks mdc
12780         cancel_lru_locks osc
12781         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12782         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12783         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12784         # XXX client can not do early lock cancel of OST lock
12785         # during rename (LU-4206), so cancel osc lock now.
12786         sleep 2
12787         cancel_lru_locks osc
12788         can1=$(do_facet mds1 \
12789                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12790                awk '/ldlm_cancel/ {print $2}')
12791         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12792                awk '/ldlm_bl_callback/ {print $2}')
12793         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12794         sleep 5
12795         can2=$(do_facet mds1 \
12796                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12797                awk '/ldlm_cancel/ {print $2}')
12798         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12799                awk '/ldlm_bl_callback/ {print $2}')
12800         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12801         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12802         lru_resize_enable mdc
12803         lru_resize_enable osc
12804 }
12805 run_test 120f "Early Lock Cancel: rename test"
12806
12807 test_120g() {
12808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12809         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12810                 skip_env "no early lock cancel on server"
12811         remote_mds_nodsh && skip "remote MDS with nodsh"
12812
12813         lru_resize_disable mdc
12814         lru_resize_disable osc
12815         count=10000
12816         echo create $count files
12817         test_mkdir $DIR/$tdir
12818         cancel_lru_locks mdc
12819         cancel_lru_locks osc
12820         t0=$(date +%s)
12821
12822         can0=$(do_facet $SINGLEMDS \
12823                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12824                awk '/ldlm_cancel/ {print $2}')
12825         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12826                awk '/ldlm_bl_callback/ {print $2}')
12827         createmany -o $DIR/$tdir/f $count
12828         sync
12829         can1=$(do_facet $SINGLEMDS \
12830                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12831                awk '/ldlm_cancel/ {print $2}')
12832         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12833                awk '/ldlm_bl_callback/ {print $2}')
12834         t1=$(date +%s)
12835         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12836         echo rm $count files
12837         rm -r $DIR/$tdir
12838         sync
12839         can2=$(do_facet $SINGLEMDS \
12840                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12841                awk '/ldlm_cancel/ {print $2}')
12842         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12843                awk '/ldlm_bl_callback/ {print $2}')
12844         t2=$(date +%s)
12845         echo total: $count removes in $((t2-t1))
12846         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12847         sleep 2
12848         # wait for commitment of removal
12849         lru_resize_enable mdc
12850         lru_resize_enable osc
12851 }
12852 run_test 120g "Early Lock Cancel: performance test"
12853
12854 test_121() { #bug #10589
12855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12856
12857         rm -rf $DIR/$tfile
12858         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12859 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12860         lctl set_param fail_loc=0x310
12861         cancel_lru_locks osc > /dev/null
12862         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12863         lctl set_param fail_loc=0
12864         [[ $reads -eq $writes ]] ||
12865                 error "read $reads blocks, must be $writes blocks"
12866 }
12867 run_test 121 "read cancel race ========="
12868
12869 test_123a_base() { # was test 123, statahead(bug 11401)
12870         local lsx="$1"
12871
12872         SLOWOK=0
12873         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12874                 log "testing UP system. Performance may be lower than expected."
12875                 SLOWOK=1
12876         fi
12877         running_in_vm && SLOWOK=1
12878
12879         rm -rf $DIR/$tdir
12880         test_mkdir $DIR/$tdir
12881         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12882         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12883         MULT=10
12884         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12885                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12886
12887                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12888                 lctl set_param -n llite.*.statahead_max 0
12889                 lctl get_param llite.*.statahead_max
12890                 cancel_lru_locks mdc
12891                 cancel_lru_locks osc
12892                 stime=$(date +%s)
12893                 time $lsx $DIR/$tdir | wc -l
12894                 etime=$(date +%s)
12895                 delta=$((etime - stime))
12896                 log "$lsx $i files without statahead: $delta sec"
12897                 lctl set_param llite.*.statahead_max=$max
12898
12899                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12900                         grep "statahead wrong:" | awk '{print $3}')
12901                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12902                 cancel_lru_locks mdc
12903                 cancel_lru_locks osc
12904                 stime=$(date +%s)
12905                 time $lsx $DIR/$tdir | wc -l
12906                 etime=$(date +%s)
12907                 delta_sa=$((etime - stime))
12908                 log "$lsx $i files with statahead: $delta_sa sec"
12909                 lctl get_param -n llite.*.statahead_stats
12910                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12911                         grep "statahead wrong:" | awk '{print $3}')
12912
12913                 [[ $swrong -lt $ewrong ]] &&
12914                         log "statahead was stopped, maybe too many locks held!"
12915                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12916
12917                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12918                         max=$(lctl get_param -n llite.*.statahead_max |
12919                                 head -n 1)
12920                         lctl set_param -n llite.*.statahead_max 0
12921                         lctl get_param llite.*.statahead_max
12922                         cancel_lru_locks mdc
12923                         cancel_lru_locks osc
12924                         stime=$(date +%s)
12925                         time $lsx $DIR/$tdir | wc -l
12926                         etime=$(date +%s)
12927                         delta=$((etime - stime))
12928                         log "$lsx $i files again without statahead: $delta sec"
12929                         lctl set_param llite.*.statahead_max=$max
12930                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12931                                 if [  $SLOWOK -eq 0 ]; then
12932                                         error "$lsx $i files is slower with statahead!"
12933                                 else
12934                                         log "$lsx $i files is slower with statahead!"
12935                                 fi
12936                                 break
12937                         fi
12938                 fi
12939
12940                 [ $delta -gt 20 ] && break
12941                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12942                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12943         done
12944         log "$lsx done"
12945
12946         stime=$(date +%s)
12947         rm -r $DIR/$tdir
12948         sync
12949         etime=$(date +%s)
12950         delta=$((etime - stime))
12951         log "rm -r $DIR/$tdir/: $delta seconds"
12952         log "rm done"
12953         lctl get_param -n llite.*.statahead_stats
12954 }
12955
12956 test_123aa() {
12957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12958
12959         test_123a_base "ls -l"
12960 }
12961 run_test 123aa "verify statahead work"
12962
12963 test_123ab() {
12964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12965
12966         statx_supported || skip_env "Test must be statx() syscall supported"
12967
12968         test_123a_base "$STATX -l"
12969 }
12970 run_test 123ab "verify statahead work by using statx"
12971
12972 test_123ac() {
12973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12974
12975         statx_supported || skip_env "Test must be statx() syscall supported"
12976
12977         local rpcs_before
12978         local rpcs_after
12979         local agl_before
12980         local agl_after
12981
12982         cancel_lru_locks $OSC
12983         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12984         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12985                 awk '/agl.total:/ {print $3}')
12986         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12987         test_123a_base "$STATX --cached=always -D"
12988         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12989                 awk '/agl.total:/ {print $3}')
12990         [ $agl_before -eq $agl_after ] ||
12991                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12992         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12993         [ $rpcs_after -eq $rpcs_before ] ||
12994                 error "$STATX should not send glimpse RPCs to $OSC"
12995 }
12996 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12997
12998 test_123b () { # statahead(bug 15027)
12999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13000
13001         test_mkdir $DIR/$tdir
13002         createmany -o $DIR/$tdir/$tfile-%d 1000
13003
13004         cancel_lru_locks mdc
13005         cancel_lru_locks osc
13006
13007 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13008         lctl set_param fail_loc=0x80000803
13009         ls -lR $DIR/$tdir > /dev/null
13010         log "ls done"
13011         lctl set_param fail_loc=0x0
13012         lctl get_param -n llite.*.statahead_stats
13013         rm -r $DIR/$tdir
13014         sync
13015
13016 }
13017 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13018
13019 test_123c() {
13020         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13021
13022         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13023         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13024         touch $DIR/$tdir.1/{1..3}
13025         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13026
13027         remount_client $MOUNT
13028
13029         $MULTIOP $DIR/$tdir.0 Q
13030
13031         # let statahead to complete
13032         ls -l $DIR/$tdir.0 > /dev/null
13033
13034         testid=$(echo $TESTNAME | tr '_' ' ')
13035         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13036                 error "statahead warning" || true
13037 }
13038 run_test 123c "Can not initialize inode warning on DNE statahead"
13039
13040 test_124a() {
13041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13042         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13043                 skip_env "no lru resize on server"
13044
13045         local NR=2000
13046
13047         test_mkdir $DIR/$tdir
13048
13049         log "create $NR files at $DIR/$tdir"
13050         createmany -o $DIR/$tdir/f $NR ||
13051                 error "failed to create $NR files in $DIR/$tdir"
13052
13053         cancel_lru_locks mdc
13054         ls -l $DIR/$tdir > /dev/null
13055
13056         local NSDIR=""
13057         local LRU_SIZE=0
13058         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13059                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13060                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13061                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13062                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13063                         log "NSDIR=$NSDIR"
13064                         log "NS=$(basename $NSDIR)"
13065                         break
13066                 fi
13067         done
13068
13069         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13070                 skip "Not enough cached locks created!"
13071         fi
13072         log "LRU=$LRU_SIZE"
13073
13074         local SLEEP=30
13075
13076         # We know that lru resize allows one client to hold $LIMIT locks
13077         # for 10h. After that locks begin to be killed by client.
13078         local MAX_HRS=10
13079         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13080         log "LIMIT=$LIMIT"
13081         if [ $LIMIT -lt $LRU_SIZE ]; then
13082                 skip "Limit is too small $LIMIT"
13083         fi
13084
13085         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13086         # killing locks. Some time was spent for creating locks. This means
13087         # that up to the moment of sleep finish we must have killed some of
13088         # them (10-100 locks). This depends on how fast ther were created.
13089         # Many of them were touched in almost the same moment and thus will
13090         # be killed in groups.
13091         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13092
13093         # Use $LRU_SIZE_B here to take into account real number of locks
13094         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13095         local LRU_SIZE_B=$LRU_SIZE
13096         log "LVF=$LVF"
13097         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13098         log "OLD_LVF=$OLD_LVF"
13099         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13100
13101         # Let's make sure that we really have some margin. Client checks
13102         # cached locks every 10 sec.
13103         SLEEP=$((SLEEP+20))
13104         log "Sleep ${SLEEP} sec"
13105         local SEC=0
13106         while ((SEC<$SLEEP)); do
13107                 echo -n "..."
13108                 sleep 5
13109                 SEC=$((SEC+5))
13110                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13111                 echo -n "$LRU_SIZE"
13112         done
13113         echo ""
13114         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13115         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13116
13117         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13118                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13119                 unlinkmany $DIR/$tdir/f $NR
13120                 return
13121         }
13122
13123         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13124         log "unlink $NR files at $DIR/$tdir"
13125         unlinkmany $DIR/$tdir/f $NR
13126 }
13127 run_test 124a "lru resize ======================================="
13128
13129 get_max_pool_limit()
13130 {
13131         local limit=$($LCTL get_param \
13132                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13133         local max=0
13134         for l in $limit; do
13135                 if [[ $l -gt $max ]]; then
13136                         max=$l
13137                 fi
13138         done
13139         echo $max
13140 }
13141
13142 test_124b() {
13143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13144         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13145                 skip_env "no lru resize on server"
13146
13147         LIMIT=$(get_max_pool_limit)
13148
13149         NR=$(($(default_lru_size)*20))
13150         if [[ $NR -gt $LIMIT ]]; then
13151                 log "Limit lock number by $LIMIT locks"
13152                 NR=$LIMIT
13153         fi
13154
13155         IFree=$(mdsrate_inodes_available)
13156         if [ $IFree -lt $NR ]; then
13157                 log "Limit lock number by $IFree inodes"
13158                 NR=$IFree
13159         fi
13160
13161         lru_resize_disable mdc
13162         test_mkdir -p $DIR/$tdir/disable_lru_resize
13163
13164         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13165         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13166         cancel_lru_locks mdc
13167         stime=`date +%s`
13168         PID=""
13169         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13170         PID="$PID $!"
13171         sleep 2
13172         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13173         PID="$PID $!"
13174         sleep 2
13175         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13176         PID="$PID $!"
13177         wait $PID
13178         etime=`date +%s`
13179         nolruresize_delta=$((etime-stime))
13180         log "ls -la time: $nolruresize_delta seconds"
13181         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13182         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13183
13184         lru_resize_enable mdc
13185         test_mkdir -p $DIR/$tdir/enable_lru_resize
13186
13187         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13188         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13189         cancel_lru_locks mdc
13190         stime=`date +%s`
13191         PID=""
13192         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13193         PID="$PID $!"
13194         sleep 2
13195         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13196         PID="$PID $!"
13197         sleep 2
13198         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13199         PID="$PID $!"
13200         wait $PID
13201         etime=`date +%s`
13202         lruresize_delta=$((etime-stime))
13203         log "ls -la time: $lruresize_delta seconds"
13204         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13205
13206         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13207                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13208         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13209                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13210         else
13211                 log "lru resize performs the same with no lru resize"
13212         fi
13213         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13214 }
13215 run_test 124b "lru resize (performance test) ======================="
13216
13217 test_124c() {
13218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13219         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13220                 skip_env "no lru resize on server"
13221
13222         # cache ununsed locks on client
13223         local nr=100
13224         cancel_lru_locks mdc
13225         test_mkdir $DIR/$tdir
13226         createmany -o $DIR/$tdir/f $nr ||
13227                 error "failed to create $nr files in $DIR/$tdir"
13228         ls -l $DIR/$tdir > /dev/null
13229
13230         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13231         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13232         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13233         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13234         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13235
13236         # set lru_max_age to 1 sec
13237         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13238         echo "sleep $((recalc_p * 2)) seconds..."
13239         sleep $((recalc_p * 2))
13240
13241         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13242         # restore lru_max_age
13243         $LCTL set_param -n $nsdir.lru_max_age $max_age
13244         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13245         unlinkmany $DIR/$tdir/f $nr
13246 }
13247 run_test 124c "LRUR cancel very aged locks"
13248
13249 test_124d() {
13250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13251         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13252                 skip_env "no lru resize on server"
13253
13254         # cache ununsed locks on client
13255         local nr=100
13256
13257         lru_resize_disable mdc
13258         stack_trap "lru_resize_enable mdc" EXIT
13259
13260         cancel_lru_locks mdc
13261
13262         # asynchronous object destroy at MDT could cause bl ast to client
13263         test_mkdir $DIR/$tdir
13264         createmany -o $DIR/$tdir/f $nr ||
13265                 error "failed to create $nr files in $DIR/$tdir"
13266         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13267
13268         ls -l $DIR/$tdir > /dev/null
13269
13270         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13271         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13272         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13273         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13274
13275         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13276
13277         # set lru_max_age to 1 sec
13278         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13279         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13280
13281         echo "sleep $((recalc_p * 2)) seconds..."
13282         sleep $((recalc_p * 2))
13283
13284         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13285
13286         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13287 }
13288 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13289
13290 test_125() { # 13358
13291         $LCTL get_param -n llite.*.client_type | grep -q local ||
13292                 skip "must run as local client"
13293         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13294                 skip_env "must have acl enabled"
13295         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13296
13297         test_mkdir $DIR/$tdir
13298         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13299         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13300         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13301 }
13302 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13303
13304 test_126() { # bug 12829/13455
13305         $GSS && skip_env "must run as gss disabled"
13306         $LCTL get_param -n llite.*.client_type | grep -q local ||
13307                 skip "must run as local client"
13308         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13309
13310         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13311         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13312         rm -f $DIR/$tfile
13313         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13314 }
13315 run_test 126 "check that the fsgid provided by the client is taken into account"
13316
13317 test_127a() { # bug 15521
13318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13319         local name count samp unit min max sum sumsq
13320
13321         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13322         echo "stats before reset"
13323         $LCTL get_param osc.*.stats
13324         $LCTL set_param osc.*.stats=0
13325         local fsize=$((2048 * 1024))
13326
13327         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13328         cancel_lru_locks osc
13329         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13330
13331         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13332         stack_trap "rm -f $TMP/$tfile.tmp"
13333         while read name count samp unit min max sum sumsq; do
13334                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13335                 [ ! $min ] && error "Missing min value for $name proc entry"
13336                 eval $name=$count || error "Wrong proc format"
13337
13338                 case $name in
13339                 read_bytes|write_bytes)
13340                         [[ "$unit" =~ "bytes" ]] ||
13341                                 error "unit is not 'bytes': $unit"
13342                         (( $min >= 4096 )) || error "min is too small: $min"
13343                         (( $min <= $fsize )) || error "min is too big: $min"
13344                         (( $max >= 4096 )) || error "max is too small: $max"
13345                         (( $max <= $fsize )) || error "max is too big: $max"
13346                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13347                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13348                                 error "sumsquare is too small: $sumsq"
13349                         (( $sumsq <= $fsize * $fsize )) ||
13350                                 error "sumsquare is too big: $sumsq"
13351                         ;;
13352                 ost_read|ost_write)
13353                         [[ "$unit" =~ "usec" ]] ||
13354                                 error "unit is not 'usec': $unit"
13355                         ;;
13356                 *)      ;;
13357                 esac
13358         done < $DIR/$tfile.tmp
13359
13360         #check that we actually got some stats
13361         [ "$read_bytes" ] || error "Missing read_bytes stats"
13362         [ "$write_bytes" ] || error "Missing write_bytes stats"
13363         [ "$read_bytes" != 0 ] || error "no read done"
13364         [ "$write_bytes" != 0 ] || error "no write done"
13365 }
13366 run_test 127a "verify the client stats are sane"
13367
13368 test_127b() { # bug LU-333
13369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13370         local name count samp unit min max sum sumsq
13371
13372         echo "stats before reset"
13373         $LCTL get_param llite.*.stats
13374         $LCTL set_param llite.*.stats=0
13375
13376         # perform 2 reads and writes so MAX is different from SUM.
13377         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13378         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13379         cancel_lru_locks osc
13380         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13381         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13382
13383         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13384         stack_trap "rm -f $TMP/$tfile.tmp"
13385         while read name count samp unit min max sum sumsq; do
13386                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13387                 eval $name=$count || error "Wrong proc format"
13388
13389                 case $name in
13390                 read_bytes|write_bytes)
13391                         [[ "$unit" =~ "bytes" ]] ||
13392                                 error "unit is not 'bytes': $unit"
13393                         (( $count == 2 )) || error "count is not 2: $count"
13394                         (( $min == $PAGE_SIZE )) ||
13395                                 error "min is not $PAGE_SIZE: $min"
13396                         (( $max == $PAGE_SIZE )) ||
13397                                 error "max is not $PAGE_SIZE: $max"
13398                         (( $sum == $PAGE_SIZE * 2 )) ||
13399                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13400                         ;;
13401                 read|write)
13402                         [[ "$unit" =~ "usec" ]] ||
13403                                 error "unit is not 'usec': $unit"
13404                         ;;
13405                 *)      ;;
13406                 esac
13407         done < $TMP/$tfile.tmp
13408
13409         #check that we actually got some stats
13410         [ "$read_bytes" ] || error "Missing read_bytes stats"
13411         [ "$write_bytes" ] || error "Missing write_bytes stats"
13412         [ "$read_bytes" != 0 ] || error "no read done"
13413         [ "$write_bytes" != 0 ] || error "no write done"
13414 }
13415 run_test 127b "verify the llite client stats are sane"
13416
13417 test_127c() { # LU-12394
13418         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13419         local size
13420         local bsize
13421         local reads
13422         local writes
13423         local count
13424
13425         $LCTL set_param llite.*.extents_stats=1
13426         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13427
13428         # Use two stripes so there is enough space in default config
13429         $LFS setstripe -c 2 $DIR/$tfile
13430
13431         # Extent stats start at 0-4K and go in power of two buckets
13432         # LL_HIST_START = 12 --> 2^12 = 4K
13433         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13434         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13435         # small configs
13436         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13437                 do
13438                 # Write and read, 2x each, second time at a non-zero offset
13439                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13440                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13441                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13442                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13443                 rm -f $DIR/$tfile
13444         done
13445
13446         $LCTL get_param llite.*.extents_stats
13447
13448         count=2
13449         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13450                 do
13451                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13452                                 grep -m 1 $bsize)
13453                 reads=$(echo $bucket | awk '{print $5}')
13454                 writes=$(echo $bucket | awk '{print $9}')
13455                 [ "$reads" -eq $count ] ||
13456                         error "$reads reads in < $bsize bucket, expect $count"
13457                 [ "$writes" -eq $count ] ||
13458                         error "$writes writes in < $bsize bucket, expect $count"
13459         done
13460
13461         # Test mmap write and read
13462         $LCTL set_param llite.*.extents_stats=c
13463         size=512
13464         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13465         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13466         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13467
13468         $LCTL get_param llite.*.extents_stats
13469
13470         count=$(((size*1024) / PAGE_SIZE))
13471
13472         bsize=$((2 * PAGE_SIZE / 1024))K
13473
13474         bucket=$($LCTL get_param -n llite.*.extents_stats |
13475                         grep -m 1 $bsize)
13476         reads=$(echo $bucket | awk '{print $5}')
13477         writes=$(echo $bucket | awk '{print $9}')
13478         # mmap writes fault in the page first, creating an additonal read
13479         [ "$reads" -eq $((2 * count)) ] ||
13480                 error "$reads reads in < $bsize bucket, expect $count"
13481         [ "$writes" -eq $count ] ||
13482                 error "$writes writes in < $bsize bucket, expect $count"
13483 }
13484 run_test 127c "test llite extent stats with regular & mmap i/o"
13485
13486 test_128() { # bug 15212
13487         touch $DIR/$tfile
13488         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13489                 find $DIR/$tfile
13490                 find $DIR/$tfile
13491         EOF
13492
13493         result=$(grep error $TMP/$tfile.log)
13494         rm -f $DIR/$tfile $TMP/$tfile.log
13495         [ -z "$result" ] ||
13496                 error "consecutive find's under interactive lfs failed"
13497 }
13498 run_test 128 "interactive lfs for 2 consecutive find's"
13499
13500 set_dir_limits () {
13501         local mntdev
13502         local canondev
13503         local node
13504
13505         local ldproc=/proc/fs/ldiskfs
13506         local facets=$(get_facets MDS)
13507
13508         for facet in ${facets//,/ }; do
13509                 canondev=$(ldiskfs_canon \
13510                            *.$(convert_facet2label $facet).mntdev $facet)
13511                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13512                         ldproc=/sys/fs/ldiskfs
13513                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13514                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13515         done
13516 }
13517
13518 check_mds_dmesg() {
13519         local facets=$(get_facets MDS)
13520         for facet in ${facets//,/ }; do
13521                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13522         done
13523         return 1
13524 }
13525
13526 test_129() {
13527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13528         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13529                 skip "Need MDS version with at least 2.5.56"
13530         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13531                 skip_env "ldiskfs only test"
13532         fi
13533         remote_mds_nodsh && skip "remote MDS with nodsh"
13534
13535         local ENOSPC=28
13536         local has_warning=false
13537
13538         rm -rf $DIR/$tdir
13539         mkdir -p $DIR/$tdir
13540
13541         # block size of mds1
13542         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13543         set_dir_limits $maxsize $((maxsize * 6 / 8))
13544         stack_trap "set_dir_limits 0 0"
13545         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13546         local dirsize=$(stat -c%s "$DIR/$tdir")
13547         local nfiles=0
13548         while (( $dirsize <= $maxsize )); do
13549                 $MCREATE $DIR/$tdir/file_base_$nfiles
13550                 rc=$?
13551                 # check two errors:
13552                 # ENOSPC for ext4 max_dir_size, which has been used since
13553                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13554                 if (( rc == ENOSPC )); then
13555                         set_dir_limits 0 0
13556                         echo "rc=$rc returned as expected after $nfiles files"
13557
13558                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13559                                 error "create failed w/o dir size limit"
13560
13561                         # messages may be rate limited if test is run repeatedly
13562                         check_mds_dmesg '"is approaching max"' ||
13563                                 echo "warning message should be output"
13564                         check_mds_dmesg '"has reached max"' ||
13565                                 echo "reached message should be output"
13566
13567                         dirsize=$(stat -c%s "$DIR/$tdir")
13568
13569                         [[ $dirsize -ge $maxsize ]] && return 0
13570                         error "dirsize $dirsize < $maxsize after $nfiles files"
13571                 elif (( rc != 0 )); then
13572                         break
13573                 fi
13574                 nfiles=$((nfiles + 1))
13575                 dirsize=$(stat -c%s "$DIR/$tdir")
13576         done
13577
13578         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13579 }
13580 run_test 129 "test directory size limit ========================"
13581
13582 OLDIFS="$IFS"
13583 cleanup_130() {
13584         trap 0
13585         IFS="$OLDIFS"
13586 }
13587
13588 test_130a() {
13589         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13590         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13591
13592         trap cleanup_130 EXIT RETURN
13593
13594         local fm_file=$DIR/$tfile
13595         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13596         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13597                 error "dd failed for $fm_file"
13598
13599         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13600         filefrag -ves $fm_file
13601         RC=$?
13602         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13603                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13604         [ $RC != 0 ] && error "filefrag $fm_file failed"
13605
13606         filefrag_op=$(filefrag -ve -k $fm_file |
13607                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13608         lun=$($LFS getstripe -i $fm_file)
13609
13610         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13611         IFS=$'\n'
13612         tot_len=0
13613         for line in $filefrag_op
13614         do
13615                 frag_lun=`echo $line | cut -d: -f5`
13616                 ext_len=`echo $line | cut -d: -f4`
13617                 if (( $frag_lun != $lun )); then
13618                         cleanup_130
13619                         error "FIEMAP on 1-stripe file($fm_file) failed"
13620                         return
13621                 fi
13622                 (( tot_len += ext_len ))
13623         done
13624
13625         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13626                 cleanup_130
13627                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13628                 return
13629         fi
13630
13631         cleanup_130
13632
13633         echo "FIEMAP on single striped file succeeded"
13634 }
13635 run_test 130a "FIEMAP (1-stripe file)"
13636
13637 test_130b() {
13638         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13639
13640         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13641         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13642
13643         trap cleanup_130 EXIT RETURN
13644
13645         local fm_file=$DIR/$tfile
13646         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13647                         error "setstripe on $fm_file"
13648         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13649                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13650
13651         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13652                 error "dd failed on $fm_file"
13653
13654         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13655         filefrag_op=$(filefrag -ve -k $fm_file |
13656                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13657
13658         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13659                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13660
13661         IFS=$'\n'
13662         tot_len=0
13663         num_luns=1
13664         for line in $filefrag_op
13665         do
13666                 frag_lun=$(echo $line | cut -d: -f5 |
13667                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13668                 ext_len=$(echo $line | cut -d: -f4)
13669                 if (( $frag_lun != $last_lun )); then
13670                         if (( tot_len != 1024 )); then
13671                                 cleanup_130
13672                                 error "FIEMAP on $fm_file failed; returned " \
13673                                 "len $tot_len for OST $last_lun instead of 1024"
13674                                 return
13675                         else
13676                                 (( num_luns += 1 ))
13677                                 tot_len=0
13678                         fi
13679                 fi
13680                 (( tot_len += ext_len ))
13681                 last_lun=$frag_lun
13682         done
13683         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13684                 cleanup_130
13685                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13686                         "luns or wrong len for OST $last_lun"
13687                 return
13688         fi
13689
13690         cleanup_130
13691
13692         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13693 }
13694 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13695
13696 test_130c() {
13697         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13698
13699         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13700         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13701
13702         trap cleanup_130 EXIT RETURN
13703
13704         local fm_file=$DIR/$tfile
13705         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13706         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13707                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13708
13709         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13710                         error "dd failed on $fm_file"
13711
13712         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13713         filefrag_op=$(filefrag -ve -k $fm_file |
13714                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13715
13716         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13717                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13718
13719         IFS=$'\n'
13720         tot_len=0
13721         num_luns=1
13722         for line in $filefrag_op
13723         do
13724                 frag_lun=$(echo $line | cut -d: -f5 |
13725                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13726                 ext_len=$(echo $line | cut -d: -f4)
13727                 if (( $frag_lun != $last_lun )); then
13728                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13729                         if (( logical != 512 )); then
13730                                 cleanup_130
13731                                 error "FIEMAP on $fm_file failed; returned " \
13732                                 "logical start for lun $logical instead of 512"
13733                                 return
13734                         fi
13735                         if (( tot_len != 512 )); then
13736                                 cleanup_130
13737                                 error "FIEMAP on $fm_file failed; returned " \
13738                                 "len $tot_len for OST $last_lun instead of 1024"
13739                                 return
13740                         else
13741                                 (( num_luns += 1 ))
13742                                 tot_len=0
13743                         fi
13744                 fi
13745                 (( tot_len += ext_len ))
13746                 last_lun=$frag_lun
13747         done
13748         if (( num_luns != 2 || tot_len != 512 )); then
13749                 cleanup_130
13750                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13751                         "luns or wrong len for OST $last_lun"
13752                 return
13753         fi
13754
13755         cleanup_130
13756
13757         echo "FIEMAP on 2-stripe file with hole succeeded"
13758 }
13759 run_test 130c "FIEMAP (2-stripe file with hole)"
13760
13761 test_130d() {
13762         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13763
13764         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13765         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13766
13767         trap cleanup_130 EXIT RETURN
13768
13769         local fm_file=$DIR/$tfile
13770         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13771                         error "setstripe on $fm_file"
13772         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13773                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13774
13775         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13776         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13777                 error "dd failed on $fm_file"
13778
13779         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13780         filefrag_op=$(filefrag -ve -k $fm_file |
13781                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13782
13783         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13784                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13785
13786         IFS=$'\n'
13787         tot_len=0
13788         num_luns=1
13789         for line in $filefrag_op
13790         do
13791                 frag_lun=$(echo $line | cut -d: -f5 |
13792                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13793                 ext_len=$(echo $line | cut -d: -f4)
13794                 if (( $frag_lun != $last_lun )); then
13795                         if (( tot_len != 1024 )); then
13796                                 cleanup_130
13797                                 error "FIEMAP on $fm_file failed; returned " \
13798                                 "len $tot_len for OST $last_lun instead of 1024"
13799                                 return
13800                         else
13801                                 (( num_luns += 1 ))
13802                                 tot_len=0
13803                         fi
13804                 fi
13805                 (( tot_len += ext_len ))
13806                 last_lun=$frag_lun
13807         done
13808         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13809                 cleanup_130
13810                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13811                         "luns or wrong len for OST $last_lun"
13812                 return
13813         fi
13814
13815         cleanup_130
13816
13817         echo "FIEMAP on N-stripe file succeeded"
13818 }
13819 run_test 130d "FIEMAP (N-stripe file)"
13820
13821 test_130e() {
13822         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13823
13824         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13825         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13826
13827         trap cleanup_130 EXIT RETURN
13828
13829         local fm_file=$DIR/$tfile
13830         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13831
13832         NUM_BLKS=512
13833         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13834         for ((i = 0; i < $NUM_BLKS; i++)); do
13835                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13836                         conv=notrunc > /dev/null 2>&1
13837         done
13838
13839         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13840         filefrag_op=$(filefrag -ve -k $fm_file |
13841                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13842
13843         last_lun=$(echo $filefrag_op | cut -d: -f5)
13844
13845         IFS=$'\n'
13846         tot_len=0
13847         num_luns=1
13848         for line in $filefrag_op; do
13849                 frag_lun=$(echo $line | cut -d: -f5)
13850                 ext_len=$(echo $line | cut -d: -f4)
13851                 if [[ "$frag_lun" != "$last_lun" ]]; then
13852                         if (( tot_len != $EXPECTED_LEN )); then
13853                                 cleanup_130
13854                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13855                         else
13856                                 (( num_luns += 1 ))
13857                                 tot_len=0
13858                         fi
13859                 fi
13860                 (( tot_len += ext_len ))
13861                 last_lun=$frag_lun
13862         done
13863         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13864                 cleanup_130
13865                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13866         fi
13867
13868         echo "FIEMAP with continuation calls succeeded"
13869 }
13870 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13871
13872 test_130f() {
13873         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13874         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13875
13876         local fm_file=$DIR/$tfile
13877         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13878                 error "multiop create with lov_delay_create on $fm_file"
13879
13880         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13881         filefrag_extents=$(filefrag -vek $fm_file |
13882                            awk '/extents? found/ { print $2 }')
13883         if [[ "$filefrag_extents" != "0" ]]; then
13884                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13885         fi
13886
13887         rm -f $fm_file
13888 }
13889 run_test 130f "FIEMAP (unstriped file)"
13890
13891 test_130g() {
13892         local file=$DIR/$tfile
13893         local nr=$((OSTCOUNT * 100))
13894
13895         $LFS setstripe -C $nr $file ||
13896                 error "failed to setstripe -C $nr $file"
13897
13898         dd if=/dev/zero of=$file count=$nr bs=1M
13899         sync
13900         nr=$($LFS getstripe -c $file)
13901
13902         local extents=$(filefrag -v $file |
13903                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13904
13905         echo "filefrag list $extents extents in file with stripecount $nr"
13906         if (( extents < nr )); then
13907                 $LFS getstripe $file
13908                 filefrag -v $file
13909                 error "filefrag printed $extents < $nr extents"
13910         fi
13911
13912         rm -f $file
13913 }
13914 run_test 130g "FIEMAP (overstripe file)"
13915
13916 # Test for writev/readv
13917 test_131a() {
13918         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13919                 error "writev test failed"
13920         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13921                 error "readv failed"
13922         rm -f $DIR/$tfile
13923 }
13924 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13925
13926 test_131b() {
13927         local fsize=$((524288 + 1048576 + 1572864))
13928         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13929                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13930                         error "append writev test failed"
13931
13932         ((fsize += 1572864 + 1048576))
13933         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13934                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13935                         error "append writev test failed"
13936         rm -f $DIR/$tfile
13937 }
13938 run_test 131b "test append writev"
13939
13940 test_131c() {
13941         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13942         error "NOT PASS"
13943 }
13944 run_test 131c "test read/write on file w/o objects"
13945
13946 test_131d() {
13947         rwv -f $DIR/$tfile -w -n 1 1572864
13948         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13949         if [ "$NOB" != 1572864 ]; then
13950                 error "Short read filed: read $NOB bytes instead of 1572864"
13951         fi
13952         rm -f $DIR/$tfile
13953 }
13954 run_test 131d "test short read"
13955
13956 test_131e() {
13957         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13958         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13959         error "read hitting hole failed"
13960         rm -f $DIR/$tfile
13961 }
13962 run_test 131e "test read hitting hole"
13963
13964 check_stats() {
13965         local facet=$1
13966         local op=$2
13967         local want=${3:-0}
13968         local res
13969
13970         case $facet in
13971         mds*) res=$(do_facet $facet \
13972                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13973                  ;;
13974         ost*) res=$(do_facet $facet \
13975                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13976                  ;;
13977         *) error "Wrong facet '$facet'" ;;
13978         esac
13979         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13980         # if the argument $3 is zero, it means any stat increment is ok.
13981         if [[ $want -gt 0 ]]; then
13982                 local count=$(echo $res | awk '{ print $2 }')
13983                 [[ $count -ne $want ]] &&
13984                         error "The $op counter on $facet is $count, not $want"
13985         fi
13986 }
13987
13988 test_133a() {
13989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13990         remote_ost_nodsh && skip "remote OST with nodsh"
13991         remote_mds_nodsh && skip "remote MDS with nodsh"
13992         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13993                 skip_env "MDS doesn't support rename stats"
13994
13995         local testdir=$DIR/${tdir}/stats_testdir
13996
13997         mkdir -p $DIR/${tdir}
13998
13999         # clear stats.
14000         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14001         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14002
14003         # verify mdt stats first.
14004         mkdir ${testdir} || error "mkdir failed"
14005         check_stats $SINGLEMDS "mkdir" 1
14006         touch ${testdir}/${tfile} || error "touch failed"
14007         check_stats $SINGLEMDS "open" 1
14008         check_stats $SINGLEMDS "close" 1
14009         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14010                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14011                 check_stats $SINGLEMDS "mknod" 2
14012         }
14013         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14014         check_stats $SINGLEMDS "unlink" 1
14015         rm -f ${testdir}/${tfile} || error "file remove failed"
14016         check_stats $SINGLEMDS "unlink" 2
14017
14018         # remove working dir and check mdt stats again.
14019         rmdir ${testdir} || error "rmdir failed"
14020         check_stats $SINGLEMDS "rmdir" 1
14021
14022         local testdir1=$DIR/${tdir}/stats_testdir1
14023         mkdir -p ${testdir}
14024         mkdir -p ${testdir1}
14025         touch ${testdir1}/test1
14026         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14027         check_stats $SINGLEMDS "crossdir_rename" 1
14028
14029         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14030         check_stats $SINGLEMDS "samedir_rename" 1
14031
14032         rm -rf $DIR/${tdir}
14033 }
14034 run_test 133a "Verifying MDT stats ========================================"
14035
14036 test_133b() {
14037         local res
14038
14039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14040         remote_ost_nodsh && skip "remote OST with nodsh"
14041         remote_mds_nodsh && skip "remote MDS with nodsh"
14042
14043         local testdir=$DIR/${tdir}/stats_testdir
14044
14045         mkdir -p ${testdir} || error "mkdir failed"
14046         touch ${testdir}/${tfile} || error "touch failed"
14047         cancel_lru_locks mdc
14048
14049         # clear stats.
14050         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14051         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14052
14053         # extra mdt stats verification.
14054         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14055         check_stats $SINGLEMDS "setattr" 1
14056         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14057         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14058         then            # LU-1740
14059                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14060                 check_stats $SINGLEMDS "getattr" 1
14061         fi
14062         rm -rf $DIR/${tdir}
14063
14064         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14065         # so the check below is not reliable
14066         [ $MDSCOUNT -eq 1 ] || return 0
14067
14068         # Sleep to avoid a cached response.
14069         #define OBD_STATFS_CACHE_SECONDS 1
14070         sleep 2
14071         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14072         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14073         $LFS df || error "lfs failed"
14074         check_stats $SINGLEMDS "statfs" 1
14075
14076         # check aggregated statfs (LU-10018)
14077         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14078                 return 0
14079         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14080                 return 0
14081         sleep 2
14082         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14083         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14084         df $DIR
14085         check_stats $SINGLEMDS "statfs" 1
14086
14087         # We want to check that the client didn't send OST_STATFS to
14088         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14089         # extra care is needed here.
14090         if remote_mds; then
14091                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14092                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14093
14094                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14095                 [ "$res" ] && error "OST got STATFS"
14096         fi
14097
14098         return 0
14099 }
14100 run_test 133b "Verifying extra MDT stats =================================="
14101
14102 test_133c() {
14103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14104         remote_ost_nodsh && skip "remote OST with nodsh"
14105         remote_mds_nodsh && skip "remote MDS with nodsh"
14106
14107         local testdir=$DIR/$tdir/stats_testdir
14108
14109         test_mkdir -p $testdir
14110
14111         # verify obdfilter stats.
14112         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14113         sync
14114         cancel_lru_locks osc
14115         wait_delete_completed
14116
14117         # clear stats.
14118         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14119         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14120
14121         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14122                 error "dd failed"
14123         sync
14124         cancel_lru_locks osc
14125         check_stats ost1 "write" 1
14126
14127         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14128         check_stats ost1 "read" 1
14129
14130         > $testdir/$tfile || error "truncate failed"
14131         check_stats ost1 "punch" 1
14132
14133         rm -f $testdir/$tfile || error "file remove failed"
14134         wait_delete_completed
14135         check_stats ost1 "destroy" 1
14136
14137         rm -rf $DIR/$tdir
14138 }
14139 run_test 133c "Verifying OST stats ========================================"
14140
14141 order_2() {
14142         local value=$1
14143         local orig=$value
14144         local order=1
14145
14146         while [ $value -ge 2 ]; do
14147                 order=$((order*2))
14148                 value=$((value/2))
14149         done
14150
14151         if [ $orig -gt $order ]; then
14152                 order=$((order*2))
14153         fi
14154         echo $order
14155 }
14156
14157 size_in_KMGT() {
14158     local value=$1
14159     local size=('K' 'M' 'G' 'T');
14160     local i=0
14161     local size_string=$value
14162
14163     while [ $value -ge 1024 ]; do
14164         if [ $i -gt 3 ]; then
14165             #T is the biggest unit we get here, if that is bigger,
14166             #just return XXXT
14167             size_string=${value}T
14168             break
14169         fi
14170         value=$((value >> 10))
14171         if [ $value -lt 1024 ]; then
14172             size_string=${value}${size[$i]}
14173             break
14174         fi
14175         i=$((i + 1))
14176     done
14177
14178     echo $size_string
14179 }
14180
14181 get_rename_size() {
14182         local size=$1
14183         local context=${2:-.}
14184         local sample=$(do_facet $SINGLEMDS $LCTL \
14185                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14186                 grep -A1 $context |
14187                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14188         echo $sample
14189 }
14190
14191 test_133d() {
14192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14193         remote_ost_nodsh && skip "remote OST with nodsh"
14194         remote_mds_nodsh && skip "remote MDS with nodsh"
14195         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14196                 skip_env "MDS doesn't support rename stats"
14197
14198         local testdir1=$DIR/${tdir}/stats_testdir1
14199         local testdir2=$DIR/${tdir}/stats_testdir2
14200         mkdir -p $DIR/${tdir}
14201
14202         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14203
14204         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14205         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14206
14207         createmany -o $testdir1/test 512 || error "createmany failed"
14208
14209         # check samedir rename size
14210         mv ${testdir1}/test0 ${testdir1}/test_0
14211
14212         local testdir1_size=$(ls -l $DIR/${tdir} |
14213                 awk '/stats_testdir1/ {print $5}')
14214         local testdir2_size=$(ls -l $DIR/${tdir} |
14215                 awk '/stats_testdir2/ {print $5}')
14216
14217         testdir1_size=$(order_2 $testdir1_size)
14218         testdir2_size=$(order_2 $testdir2_size)
14219
14220         testdir1_size=$(size_in_KMGT $testdir1_size)
14221         testdir2_size=$(size_in_KMGT $testdir2_size)
14222
14223         echo "source rename dir size: ${testdir1_size}"
14224         echo "target rename dir size: ${testdir2_size}"
14225
14226         local cmd="do_facet $SINGLEMDS $LCTL "
14227         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14228
14229         eval $cmd || error "$cmd failed"
14230         local samedir=$($cmd | grep 'same_dir')
14231         local same_sample=$(get_rename_size $testdir1_size)
14232         [ -z "$samedir" ] && error "samedir_rename_size count error"
14233         [[ $same_sample -eq 1 ]] ||
14234                 error "samedir_rename_size error $same_sample"
14235         echo "Check same dir rename stats success"
14236
14237         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14238
14239         # check crossdir rename size
14240         mv ${testdir1}/test_0 ${testdir2}/test_0
14241
14242         testdir1_size=$(ls -l $DIR/${tdir} |
14243                 awk '/stats_testdir1/ {print $5}')
14244         testdir2_size=$(ls -l $DIR/${tdir} |
14245                 awk '/stats_testdir2/ {print $5}')
14246
14247         testdir1_size=$(order_2 $testdir1_size)
14248         testdir2_size=$(order_2 $testdir2_size)
14249
14250         testdir1_size=$(size_in_KMGT $testdir1_size)
14251         testdir2_size=$(size_in_KMGT $testdir2_size)
14252
14253         echo "source rename dir size: ${testdir1_size}"
14254         echo "target rename dir size: ${testdir2_size}"
14255
14256         eval $cmd || error "$cmd failed"
14257         local crossdir=$($cmd | grep 'crossdir')
14258         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14259         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14260         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14261         [[ $src_sample -eq 1 ]] ||
14262                 error "crossdir_rename_size error $src_sample"
14263         [[ $tgt_sample -eq 1 ]] ||
14264                 error "crossdir_rename_size error $tgt_sample"
14265         echo "Check cross dir rename stats success"
14266         rm -rf $DIR/${tdir}
14267 }
14268 run_test 133d "Verifying rename_stats ========================================"
14269
14270 test_133e() {
14271         remote_mds_nodsh && skip "remote MDS with nodsh"
14272         remote_ost_nodsh && skip "remote OST with nodsh"
14273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14274
14275         local testdir=$DIR/${tdir}/stats_testdir
14276         local ctr f0 f1 bs=32768 count=42 sum
14277
14278         mkdir -p ${testdir} || error "mkdir failed"
14279
14280         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14281
14282         for ctr in {write,read}_bytes; do
14283                 sync
14284                 cancel_lru_locks osc
14285
14286                 do_facet ost1 $LCTL set_param -n \
14287                         "obdfilter.*.exports.clear=clear"
14288
14289                 if [ $ctr = write_bytes ]; then
14290                         f0=/dev/zero
14291                         f1=${testdir}/${tfile}
14292                 else
14293                         f0=${testdir}/${tfile}
14294                         f1=/dev/null
14295                 fi
14296
14297                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14298                         error "dd failed"
14299                 sync
14300                 cancel_lru_locks osc
14301
14302                 sum=$(do_facet ost1 $LCTL get_param \
14303                         "obdfilter.*.exports.*.stats" |
14304                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14305                                 $1 == ctr { sum += $7 }
14306                                 END { printf("%0.0f", sum) }')
14307
14308                 if ((sum != bs * count)); then
14309                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14310                 fi
14311         done
14312
14313         rm -rf $DIR/${tdir}
14314 }
14315 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14316
14317 test_133f() {
14318         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14319                 skip "too old lustre for get_param -R ($facet_ver)"
14320
14321         # verifying readability.
14322         $LCTL get_param -R '*' &> /dev/null
14323
14324         # Verifing writability with badarea_io.
14325         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14326         local skipped_params='force_lbug|changelog_mask|daemon_file'
14327         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14328                 egrep -v "$skipped_params" |
14329                 xargs -n 1 find $proc_dirs -name |
14330                 xargs -n 1 badarea_io ||
14331                 error "client badarea_io failed"
14332
14333         # remount the FS in case writes/reads /proc break the FS
14334         cleanup || error "failed to unmount"
14335         setup || error "failed to setup"
14336 }
14337 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14338
14339 test_133g() {
14340         remote_mds_nodsh && skip "remote MDS with nodsh"
14341         remote_ost_nodsh && skip "remote OST with nodsh"
14342
14343         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14344         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14345         local facet
14346         for facet in mds1 ost1; do
14347                 local facet_ver=$(lustre_version_code $facet)
14348                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14349                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14350                 else
14351                         log "$facet: too old lustre for get_param -R"
14352                 fi
14353                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14354                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14355                                 tr -d = | egrep -v $skipped_params |
14356                                 xargs -n 1 find $proc_dirs -name |
14357                                 xargs -n 1 badarea_io" ||
14358                                         error "$facet badarea_io failed"
14359                 else
14360                         skip_noexit "$facet: too old lustre for get_param -R"
14361                 fi
14362         done
14363
14364         # remount the FS in case writes/reads /proc break the FS
14365         cleanup || error "failed to unmount"
14366         setup || error "failed to setup"
14367 }
14368 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14369
14370 test_133h() {
14371         remote_mds_nodsh && skip "remote MDS with nodsh"
14372         remote_ost_nodsh && skip "remote OST with nodsh"
14373         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14374                 skip "Need MDS version at least 2.9.54"
14375
14376         local facet
14377         for facet in client mds1 ost1; do
14378                 # Get the list of files that are missing the terminating newline
14379                 local plist=$(do_facet $facet
14380                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14381                 local ent
14382                 for ent in $plist; do
14383                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14384                                 awk -v FS='\v' -v RS='\v\v' \
14385                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14386                                         print FILENAME}'" 2>/dev/null)
14387                         [ -z $missing ] || {
14388                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14389                                 error "file does not end with newline: $facet-$ent"
14390                         }
14391                 done
14392         done
14393 }
14394 run_test 133h "Proc files should end with newlines"
14395
14396 test_134a() {
14397         remote_mds_nodsh && skip "remote MDS with nodsh"
14398         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14399                 skip "Need MDS version at least 2.7.54"
14400
14401         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14402         cancel_lru_locks mdc
14403
14404         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14405         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14406         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14407
14408         local nr=1000
14409         createmany -o $DIR/$tdir/f $nr ||
14410                 error "failed to create $nr files in $DIR/$tdir"
14411         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14412
14413         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14414         do_facet mds1 $LCTL set_param fail_loc=0x327
14415         do_facet mds1 $LCTL set_param fail_val=500
14416         touch $DIR/$tdir/m
14417
14418         echo "sleep 10 seconds ..."
14419         sleep 10
14420         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14421
14422         do_facet mds1 $LCTL set_param fail_loc=0
14423         do_facet mds1 $LCTL set_param fail_val=0
14424         [ $lck_cnt -lt $unused ] ||
14425                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14426
14427         rm $DIR/$tdir/m
14428         unlinkmany $DIR/$tdir/f $nr
14429 }
14430 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14431
14432 test_134b() {
14433         remote_mds_nodsh && skip "remote MDS with nodsh"
14434         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14435                 skip "Need MDS version at least 2.7.54"
14436
14437         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14438         cancel_lru_locks mdc
14439
14440         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14441                         ldlm.lock_reclaim_threshold_mb)
14442         # disable reclaim temporarily
14443         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14444
14445         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14446         do_facet mds1 $LCTL set_param fail_loc=0x328
14447         do_facet mds1 $LCTL set_param fail_val=500
14448
14449         $LCTL set_param debug=+trace
14450
14451         local nr=600
14452         createmany -o $DIR/$tdir/f $nr &
14453         local create_pid=$!
14454
14455         echo "Sleep $TIMEOUT seconds ..."
14456         sleep $TIMEOUT
14457         if ! ps -p $create_pid  > /dev/null 2>&1; then
14458                 do_facet mds1 $LCTL set_param fail_loc=0
14459                 do_facet mds1 $LCTL set_param fail_val=0
14460                 do_facet mds1 $LCTL set_param \
14461                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14462                 error "createmany finished incorrectly!"
14463         fi
14464         do_facet mds1 $LCTL set_param fail_loc=0
14465         do_facet mds1 $LCTL set_param fail_val=0
14466         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14467         wait $create_pid || return 1
14468
14469         unlinkmany $DIR/$tdir/f $nr
14470 }
14471 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14472
14473 test_135() {
14474         remote_mds_nodsh && skip "remote MDS with nodsh"
14475         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14476                 skip "Need MDS version at least 2.13.50"
14477         local fname
14478
14479         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14480
14481 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14482         #set only one record at plain llog
14483         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14484
14485         #fill already existed plain llog each 64767
14486         #wrapping whole catalog
14487         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14488
14489         createmany -o $DIR/$tdir/$tfile_ 64700
14490         for (( i = 0; i < 64700; i = i + 2 ))
14491         do
14492                 rm $DIR/$tdir/$tfile_$i &
14493                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14494                 local pid=$!
14495                 wait $pid
14496         done
14497
14498         #waiting osp synchronization
14499         wait_delete_completed
14500 }
14501 run_test 135 "Race catalog processing"
14502
14503 test_136() {
14504         remote_mds_nodsh && skip "remote MDS with nodsh"
14505         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14506                 skip "Need MDS version at least 2.13.50"
14507         local fname
14508
14509         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14510         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14511         #set only one record at plain llog
14512 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14513         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14514
14515         #fill already existed 2 plain llogs each 64767
14516         #wrapping whole catalog
14517         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14518         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14519         wait_delete_completed
14520
14521         createmany -o $DIR/$tdir/$tfile_ 10
14522         sleep 25
14523
14524         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14525         for (( i = 0; i < 10; i = i + 3 ))
14526         do
14527                 rm $DIR/$tdir/$tfile_$i &
14528                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14529                 local pid=$!
14530                 wait $pid
14531                 sleep 7
14532                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14533         done
14534
14535         #waiting osp synchronization
14536         wait_delete_completed
14537 }
14538 run_test 136 "Race catalog processing 2"
14539
14540 test_140() { #bug-17379
14541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14542
14543         test_mkdir $DIR/$tdir
14544         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14545         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14546
14547         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14548         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14549         local i=0
14550         while i=$((i + 1)); do
14551                 test_mkdir $i
14552                 cd $i || error "Changing to $i"
14553                 ln -s ../stat stat || error "Creating stat symlink"
14554                 # Read the symlink until ELOOP present,
14555                 # not LBUGing the system is considered success,
14556                 # we didn't overrun the stack.
14557                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14558                 if [ $ret -ne 0 ]; then
14559                         if [ $ret -eq 40 ]; then
14560                                 break  # -ELOOP
14561                         else
14562                                 error "Open stat symlink"
14563                                         return
14564                         fi
14565                 fi
14566         done
14567         i=$((i - 1))
14568         echo "The symlink depth = $i"
14569         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14570                 error "Invalid symlink depth"
14571
14572         # Test recursive symlink
14573         ln -s symlink_self symlink_self
14574         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14575         echo "open symlink_self returns $ret"
14576         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14577 }
14578 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14579
14580 test_150a() {
14581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14582
14583         local TF="$TMP/$tfile"
14584
14585         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14586         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14587         cp $TF $DIR/$tfile
14588         cancel_lru_locks $OSC
14589         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14590         remount_client $MOUNT
14591         df -P $MOUNT
14592         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14593
14594         $TRUNCATE $TF 6000
14595         $TRUNCATE $DIR/$tfile 6000
14596         cancel_lru_locks $OSC
14597         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14598
14599         echo "12345" >>$TF
14600         echo "12345" >>$DIR/$tfile
14601         cancel_lru_locks $OSC
14602         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14603
14604         echo "12345" >>$TF
14605         echo "12345" >>$DIR/$tfile
14606         cancel_lru_locks $OSC
14607         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14608 }
14609 run_test 150a "truncate/append tests"
14610
14611 test_150b() {
14612         check_set_fallocate_or_skip
14613
14614         touch $DIR/$tfile
14615         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14616         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14617 }
14618 run_test 150b "Verify fallocate (prealloc) functionality"
14619
14620 test_150bb() {
14621         check_set_fallocate_or_skip
14622
14623         touch $DIR/$tfile
14624         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14625         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14626         > $DIR/$tfile
14627         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14628         # precomputed md5sum for 20MB of zeroes
14629         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14630         local sum=($(md5sum $DIR/$tfile))
14631
14632         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14633
14634         check_set_fallocate 1
14635
14636         > $DIR/$tfile
14637         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14638         sum=($(md5sum $DIR/$tfile))
14639
14640         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14641 }
14642 run_test 150bb "Verify fallocate modes both zero space"
14643
14644 test_150c() {
14645         check_set_fallocate_or_skip
14646         local striping="-c2"
14647
14648         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14649         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14650         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14651         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14652         local want=$((OSTCOUNT * 1048576))
14653
14654         # Must allocate all requested space, not more than 5% extra
14655         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14656                 error "bytes $bytes is not $want"
14657
14658         rm -f $DIR/$tfile
14659
14660         echo "verify fallocate on PFL file"
14661
14662         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14663
14664         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14665                 error "Create $DIR/$tfile failed"
14666         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14667         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14668         want=$((512 * 1048576))
14669
14670         # Must allocate all requested space, not more than 5% extra
14671         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14672                 error "bytes $bytes is not $want"
14673 }
14674 run_test 150c "Verify fallocate Size and Blocks"
14675
14676 test_150d() {
14677         check_set_fallocate_or_skip
14678         local striping="-c2"
14679
14680         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14681
14682         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14683         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14684                 error "setstripe failed"
14685         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14686         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14687         local want=$((OSTCOUNT * 1048576))
14688
14689         # Must allocate all requested space, not more than 5% extra
14690         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14691                 error "bytes $bytes is not $want"
14692 }
14693 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14694
14695 test_150e() {
14696         check_set_fallocate_or_skip
14697
14698         echo "df before:"
14699         $LFS df
14700         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14701         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14702                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14703
14704         # Find OST with Minimum Size
14705         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14706                        sort -un | head -1)
14707
14708         # Get 100MB per OST of the available space to reduce run time
14709         # else 60% of the available space if we are running SLOW tests
14710         if [ $SLOW == "no" ]; then
14711                 local space=$((1024 * 100 * OSTCOUNT))
14712         else
14713                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14714         fi
14715
14716         fallocate -l${space}k $DIR/$tfile ||
14717                 error "fallocate ${space}k $DIR/$tfile failed"
14718         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14719
14720         # get size immediately after fallocate. This should be correctly
14721         # updated
14722         local size=$(stat -c '%s' $DIR/$tfile)
14723         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14724
14725         # Sleep for a while for statfs to get updated. And not pull from cache.
14726         sleep 2
14727
14728         echo "df after fallocate:"
14729         $LFS df
14730
14731         (( size / 1024 == space )) || error "size $size != requested $space"
14732         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14733                 error "used $used < space $space"
14734
14735         rm $DIR/$tfile || error "rm failed"
14736         sync
14737         wait_delete_completed
14738
14739         echo "df after unlink:"
14740         $LFS df
14741 }
14742 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14743
14744 test_150f() {
14745         local size
14746         local blocks
14747         local want_size_before=20480 # in bytes
14748         local want_blocks_before=40 # 512 sized blocks
14749         local want_blocks_after=24  # 512 sized blocks
14750         local length=$(((want_blocks_before - want_blocks_after) * 512))
14751
14752         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14753                 skip "need at least 2.14.0 for fallocate punch"
14754
14755         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14756                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14757         fi
14758
14759         check_set_fallocate_or_skip
14760         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14761
14762         [[ "x$DOM" == "xyes" ]] &&
14763                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14764
14765         echo "Verify fallocate punch: Range within the file range"
14766         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14767                 error "dd failed for bs 4096 and count 5"
14768
14769         # Call fallocate with punch range which is within the file range
14770         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14771                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14772         # client must see changes immediately after fallocate
14773         size=$(stat -c '%s' $DIR/$tfile)
14774         blocks=$(stat -c '%b' $DIR/$tfile)
14775
14776         # Verify punch worked.
14777         (( blocks == want_blocks_after )) ||
14778                 error "punch failed: blocks $blocks != $want_blocks_after"
14779
14780         (( size == want_size_before )) ||
14781                 error "punch failed: size $size != $want_size_before"
14782
14783         # Verify there is hole in file
14784         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14785         # precomputed md5sum
14786         local expect="4a9a834a2db02452929c0a348273b4aa"
14787
14788         cksum=($(md5sum $DIR/$tfile))
14789         [[ "${cksum[0]}" == "$expect" ]] ||
14790                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14791
14792         # Start second sub-case for fallocate punch.
14793         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14794         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14795                 error "dd failed for bs 4096 and count 5"
14796
14797         # Punch range less than block size will have no change in block count
14798         want_blocks_after=40  # 512 sized blocks
14799
14800         # Punch overlaps two blocks and less than blocksize
14801         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14802                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14803         size=$(stat -c '%s' $DIR/$tfile)
14804         blocks=$(stat -c '%b' $DIR/$tfile)
14805
14806         # Verify punch worked.
14807         (( blocks == want_blocks_after )) ||
14808                 error "punch failed: blocks $blocks != $want_blocks_after"
14809
14810         (( size == want_size_before )) ||
14811                 error "punch failed: size $size != $want_size_before"
14812
14813         # Verify if range is really zero'ed out. We expect Zeros.
14814         # precomputed md5sum
14815         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14816         cksum=($(md5sum $DIR/$tfile))
14817         [[ "${cksum[0]}" == "$expect" ]] ||
14818                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14819 }
14820 run_test 150f "Verify fallocate punch functionality"
14821
14822 test_150g() {
14823         local space
14824         local size
14825         local blocks
14826         local blocks_after
14827         local size_after
14828         local BS=4096 # Block size in bytes
14829
14830         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14831                 skip "need at least 2.14.0 for fallocate punch"
14832
14833         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14834                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14835         fi
14836
14837         check_set_fallocate_or_skip
14838         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14839
14840         if [[ "x$DOM" == "xyes" ]]; then
14841                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14842                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14843         else
14844                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14845                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14846         fi
14847
14848         # Get 100MB per OST of the available space to reduce run time
14849         # else 60% of the available space if we are running SLOW tests
14850         if [ $SLOW == "no" ]; then
14851                 space=$((1024 * 100 * OSTCOUNT))
14852         else
14853                 # Find OST with Minimum Size
14854                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14855                         sort -un | head -1)
14856                 echo "min size OST: $space"
14857                 space=$(((space * 60)/100 * OSTCOUNT))
14858         fi
14859         # space in 1k units, round to 4k blocks
14860         local blkcount=$((space * 1024 / $BS))
14861
14862         echo "Verify fallocate punch: Very large Range"
14863         fallocate -l${space}k $DIR/$tfile ||
14864                 error "fallocate ${space}k $DIR/$tfile failed"
14865         # write 1M at the end, start and in the middle
14866         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14867                 error "dd failed: bs $BS count 256"
14868         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14869                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14870         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14871                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14872
14873         # Gather stats.
14874         size=$(stat -c '%s' $DIR/$tfile)
14875
14876         # gather punch length.
14877         local punch_size=$((size - (BS * 2)))
14878
14879         echo "punch_size = $punch_size"
14880         echo "size - punch_size: $((size - punch_size))"
14881         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14882
14883         # Call fallocate to punch all except 2 blocks. We leave the
14884         # first and the last block
14885         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14886         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
14887                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
14888
14889         size_after=$(stat -c '%s' $DIR/$tfile)
14890         blocks_after=$(stat -c '%b' $DIR/$tfile)
14891
14892         # Verify punch worked.
14893         # Size should be kept
14894         (( size == size_after )) ||
14895                 error "punch failed: size $size != $size_after"
14896
14897         # two 4k data blocks to remain plus possible 1 extra extent block
14898         (( blocks_after <= ((BS / 512) * 3) )) ||
14899                 error "too many blocks remains: $blocks_after"
14900
14901         # Verify that file has hole between the first and the last blocks
14902         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14903         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14904
14905         echo "Hole at [$hole_start, $hole_end)"
14906         (( hole_start == BS )) ||
14907                 error "no hole at offset $BS after punch"
14908
14909         (( hole_end == BS + punch_size )) ||
14910                 error "data at offset $hole_end < $((BS + punch_size))"
14911 }
14912 run_test 150g "Verify fallocate punch on large range"
14913
14914 #LU-2902 roc_hit was not able to read all values from lproc
14915 function roc_hit_init() {
14916         local list=$(comma_list $(osts_nodes))
14917         local dir=$DIR/$tdir-check
14918         local file=$dir/$tfile
14919         local BEFORE
14920         local AFTER
14921         local idx
14922
14923         test_mkdir $dir
14924         #use setstripe to do a write to every ost
14925         for i in $(seq 0 $((OSTCOUNT-1))); do
14926                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14927                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14928                 idx=$(printf %04x $i)
14929                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14930                         awk '$1 == "cache_access" {sum += $7}
14931                                 END { printf("%0.0f", sum) }')
14932
14933                 cancel_lru_locks osc
14934                 cat $file >/dev/null
14935
14936                 AFTER=$(get_osd_param $list *OST*$idx stats |
14937                         awk '$1 == "cache_access" {sum += $7}
14938                                 END { printf("%0.0f", sum) }')
14939
14940                 echo BEFORE:$BEFORE AFTER:$AFTER
14941                 if ! let "AFTER - BEFORE == 4"; then
14942                         rm -rf $dir
14943                         error "roc_hit is not safe to use"
14944                 fi
14945                 rm $file
14946         done
14947
14948         rm -rf $dir
14949 }
14950
14951 function roc_hit() {
14952         local list=$(comma_list $(osts_nodes))
14953         echo $(get_osd_param $list '' stats |
14954                 awk '$1 == "cache_hit" {sum += $7}
14955                         END { printf("%0.0f", sum) }')
14956 }
14957
14958 function set_cache() {
14959         local on=1
14960
14961         if [ "$2" == "off" ]; then
14962                 on=0;
14963         fi
14964         local list=$(comma_list $(osts_nodes))
14965         set_osd_param $list '' $1_cache_enable $on
14966
14967         cancel_lru_locks osc
14968 }
14969
14970 test_151() {
14971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14972         remote_ost_nodsh && skip "remote OST with nodsh"
14973
14974         local CPAGES=3
14975         local list=$(comma_list $(osts_nodes))
14976
14977         # check whether obdfilter is cache capable at all
14978         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14979                 skip "not cache-capable obdfilter"
14980         fi
14981
14982         # check cache is enabled on all obdfilters
14983         if get_osd_param $list '' read_cache_enable | grep 0; then
14984                 skip "oss cache is disabled"
14985         fi
14986
14987         set_osd_param $list '' writethrough_cache_enable 1
14988
14989         # check write cache is enabled on all obdfilters
14990         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14991                 skip "oss write cache is NOT enabled"
14992         fi
14993
14994         roc_hit_init
14995
14996         #define OBD_FAIL_OBD_NO_LRU  0x609
14997         do_nodes $list $LCTL set_param fail_loc=0x609
14998
14999         # pages should be in the case right after write
15000         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15001                 error "dd failed"
15002
15003         local BEFORE=$(roc_hit)
15004         cancel_lru_locks osc
15005         cat $DIR/$tfile >/dev/null
15006         local AFTER=$(roc_hit)
15007
15008         do_nodes $list $LCTL set_param fail_loc=0
15009
15010         if ! let "AFTER - BEFORE == CPAGES"; then
15011                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15012         fi
15013
15014         cancel_lru_locks osc
15015         # invalidates OST cache
15016         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15017         set_osd_param $list '' read_cache_enable 0
15018         cat $DIR/$tfile >/dev/null
15019
15020         # now data shouldn't be found in the cache
15021         BEFORE=$(roc_hit)
15022         cancel_lru_locks osc
15023         cat $DIR/$tfile >/dev/null
15024         AFTER=$(roc_hit)
15025         if let "AFTER - BEFORE != 0"; then
15026                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15027         fi
15028
15029         set_osd_param $list '' read_cache_enable 1
15030         rm -f $DIR/$tfile
15031 }
15032 run_test 151 "test cache on oss and controls ==============================="
15033
15034 test_152() {
15035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15036
15037         local TF="$TMP/$tfile"
15038
15039         # simulate ENOMEM during write
15040 #define OBD_FAIL_OST_NOMEM      0x226
15041         lctl set_param fail_loc=0x80000226
15042         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15043         cp $TF $DIR/$tfile
15044         sync || error "sync failed"
15045         lctl set_param fail_loc=0
15046
15047         # discard client's cache
15048         cancel_lru_locks osc
15049
15050         # simulate ENOMEM during read
15051         lctl set_param fail_loc=0x80000226
15052         cmp $TF $DIR/$tfile || error "cmp failed"
15053         lctl set_param fail_loc=0
15054
15055         rm -f $TF
15056 }
15057 run_test 152 "test read/write with enomem ============================"
15058
15059 test_153() {
15060         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15061 }
15062 run_test 153 "test if fdatasync does not crash ======================="
15063
15064 dot_lustre_fid_permission_check() {
15065         local fid=$1
15066         local ffid=$MOUNT/.lustre/fid/$fid
15067         local test_dir=$2
15068
15069         echo "stat fid $fid"
15070         stat $ffid > /dev/null || error "stat $ffid failed."
15071         echo "touch fid $fid"
15072         touch $ffid || error "touch $ffid failed."
15073         echo "write to fid $fid"
15074         cat /etc/hosts > $ffid || error "write $ffid failed."
15075         echo "read fid $fid"
15076         diff /etc/hosts $ffid || error "read $ffid failed."
15077         echo "append write to fid $fid"
15078         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15079         echo "rename fid $fid"
15080         mv $ffid $test_dir/$tfile.1 &&
15081                 error "rename $ffid to $tfile.1 should fail."
15082         touch $test_dir/$tfile.1
15083         mv $test_dir/$tfile.1 $ffid &&
15084                 error "rename $tfile.1 to $ffid should fail."
15085         rm -f $test_dir/$tfile.1
15086         echo "truncate fid $fid"
15087         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15088         echo "link fid $fid"
15089         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15090         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15091                 echo "setfacl fid $fid"
15092                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15093                 echo "getfacl fid $fid"
15094                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15095         fi
15096         echo "unlink fid $fid"
15097         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15098         echo "mknod fid $fid"
15099         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15100
15101         fid=[0xf00000400:0x1:0x0]
15102         ffid=$MOUNT/.lustre/fid/$fid
15103
15104         echo "stat non-exist fid $fid"
15105         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15106         echo "write to non-exist fid $fid"
15107         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15108         echo "link new fid $fid"
15109         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15110
15111         mkdir -p $test_dir/$tdir
15112         touch $test_dir/$tdir/$tfile
15113         fid=$($LFS path2fid $test_dir/$tdir)
15114         rc=$?
15115         [ $rc -ne 0 ] &&
15116                 error "error: could not get fid for $test_dir/$dir/$tfile."
15117
15118         ffid=$MOUNT/.lustre/fid/$fid
15119
15120         echo "ls $fid"
15121         ls $ffid > /dev/null || error "ls $ffid failed."
15122         echo "touch $fid/$tfile.1"
15123         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15124
15125         echo "touch $MOUNT/.lustre/fid/$tfile"
15126         touch $MOUNT/.lustre/fid/$tfile && \
15127                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15128
15129         echo "setxattr to $MOUNT/.lustre/fid"
15130         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15131
15132         echo "listxattr for $MOUNT/.lustre/fid"
15133         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15134
15135         echo "delxattr from $MOUNT/.lustre/fid"
15136         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15137
15138         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15139         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15140                 error "touch invalid fid should fail."
15141
15142         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15143         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15144                 error "touch non-normal fid should fail."
15145
15146         echo "rename $tdir to $MOUNT/.lustre/fid"
15147         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15148                 error "rename to $MOUNT/.lustre/fid should fail."
15149
15150         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15151         then            # LU-3547
15152                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15153                 local new_obf_mode=777
15154
15155                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15156                 chmod $new_obf_mode $DIR/.lustre/fid ||
15157                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15158
15159                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15160                 [ $obf_mode -eq $new_obf_mode ] ||
15161                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15162
15163                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15164                 chmod $old_obf_mode $DIR/.lustre/fid ||
15165                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15166         fi
15167
15168         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15169         fid=$($LFS path2fid $test_dir/$tfile-2)
15170
15171         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15172         then # LU-5424
15173                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15174                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15175                         error "create lov data thru .lustre failed"
15176         fi
15177         echo "cp /etc/passwd $test_dir/$tfile-2"
15178         cp /etc/passwd $test_dir/$tfile-2 ||
15179                 error "copy to $test_dir/$tfile-2 failed."
15180         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15181         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15182                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15183
15184         rm -rf $test_dir/tfile.lnk
15185         rm -rf $test_dir/$tfile-2
15186 }
15187
15188 test_154A() {
15189         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15190                 skip "Need MDS version at least 2.4.1"
15191
15192         local tf=$DIR/$tfile
15193         touch $tf
15194
15195         local fid=$($LFS path2fid $tf)
15196         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15197
15198         # check that we get the same pathname back
15199         local rootpath
15200         local found
15201         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15202                 echo "$rootpath $fid"
15203                 found=$($LFS fid2path $rootpath "$fid")
15204                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15205                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15206         done
15207
15208         # check wrong root path format
15209         rootpath=$MOUNT"_wrong"
15210         found=$($LFS fid2path $rootpath "$fid")
15211         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15212 }
15213 run_test 154A "lfs path2fid and fid2path basic checks"
15214
15215 test_154B() {
15216         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15217                 skip "Need MDS version at least 2.4.1"
15218
15219         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15220         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15221         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15222         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15223
15224         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15225         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15226
15227         # check that we get the same pathname
15228         echo "PFID: $PFID, name: $name"
15229         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15230         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15231         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15232                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15233
15234         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15235 }
15236 run_test 154B "verify the ll_decode_linkea tool"
15237
15238 test_154a() {
15239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15240         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15241         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15242                 skip "Need MDS version at least 2.2.51"
15243         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15244
15245         cp /etc/hosts $DIR/$tfile
15246
15247         fid=$($LFS path2fid $DIR/$tfile)
15248         rc=$?
15249         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15250
15251         dot_lustre_fid_permission_check "$fid" $DIR ||
15252                 error "dot lustre permission check $fid failed"
15253
15254         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15255
15256         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15257
15258         touch $MOUNT/.lustre/file &&
15259                 error "creation is not allowed under .lustre"
15260
15261         mkdir $MOUNT/.lustre/dir &&
15262                 error "mkdir is not allowed under .lustre"
15263
15264         rm -rf $DIR/$tfile
15265 }
15266 run_test 154a "Open-by-FID"
15267
15268 test_154b() {
15269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15270         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15271         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15272         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15273                 skip "Need MDS version at least 2.2.51"
15274
15275         local remote_dir=$DIR/$tdir/remote_dir
15276         local MDTIDX=1
15277         local rc=0
15278
15279         mkdir -p $DIR/$tdir
15280         $LFS mkdir -i $MDTIDX $remote_dir ||
15281                 error "create remote directory failed"
15282
15283         cp /etc/hosts $remote_dir/$tfile
15284
15285         fid=$($LFS path2fid $remote_dir/$tfile)
15286         rc=$?
15287         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15288
15289         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15290                 error "dot lustre permission check $fid failed"
15291         rm -rf $DIR/$tdir
15292 }
15293 run_test 154b "Open-by-FID for remote directory"
15294
15295 test_154c() {
15296         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15297                 skip "Need MDS version at least 2.4.1"
15298
15299         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15300         local FID1=$($LFS path2fid $DIR/$tfile.1)
15301         local FID2=$($LFS path2fid $DIR/$tfile.2)
15302         local FID3=$($LFS path2fid $DIR/$tfile.3)
15303
15304         local N=1
15305         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15306                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15307                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15308                 local want=FID$N
15309                 [ "$FID" = "${!want}" ] ||
15310                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15311                 N=$((N + 1))
15312         done
15313
15314         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15315         do
15316                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15317                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15318                 N=$((N + 1))
15319         done
15320 }
15321 run_test 154c "lfs path2fid and fid2path multiple arguments"
15322
15323 test_154d() {
15324         remote_mds_nodsh && skip "remote MDS with nodsh"
15325         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15326                 skip "Need MDS version at least 2.5.53"
15327
15328         if remote_mds; then
15329                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15330         else
15331                 nid="0@lo"
15332         fi
15333         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15334         local fd
15335         local cmd
15336
15337         rm -f $DIR/$tfile
15338         touch $DIR/$tfile
15339
15340         local fid=$($LFS path2fid $DIR/$tfile)
15341         # Open the file
15342         fd=$(free_fd)
15343         cmd="exec $fd<$DIR/$tfile"
15344         eval $cmd
15345         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15346         echo "$fid_list" | grep "$fid"
15347         rc=$?
15348
15349         cmd="exec $fd>/dev/null"
15350         eval $cmd
15351         if [ $rc -ne 0 ]; then
15352                 error "FID $fid not found in open files list $fid_list"
15353         fi
15354 }
15355 run_test 154d "Verify open file fid"
15356
15357 test_154e()
15358 {
15359         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15360                 skip "Need MDS version at least 2.6.50"
15361
15362         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15363                 error ".lustre returned by readdir"
15364         fi
15365 }
15366 run_test 154e ".lustre is not returned by readdir"
15367
15368 test_154f() {
15369         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15370
15371         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15372         mkdir_on_mdt0 $DIR/$tdir
15373         # test dirs inherit from its stripe
15374         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15375         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15376         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15377         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15378         touch $DIR/f
15379
15380         # get fid of parents
15381         local FID0=$($LFS path2fid $DIR/$tdir)
15382         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15383         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15384         local FID3=$($LFS path2fid $DIR)
15385
15386         # check that path2fid --parents returns expected <parent_fid>/name
15387         # 1) test for a directory (single parent)
15388         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15389         [ "$parent" == "$FID0/foo1" ] ||
15390                 error "expected parent: $FID0/foo1, got: $parent"
15391
15392         # 2) test for a file with nlink > 1 (multiple parents)
15393         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15394         echo "$parent" | grep -F "$FID1/$tfile" ||
15395                 error "$FID1/$tfile not returned in parent list"
15396         echo "$parent" | grep -F "$FID2/link" ||
15397                 error "$FID2/link not returned in parent list"
15398
15399         # 3) get parent by fid
15400         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15401         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15402         echo "$parent" | grep -F "$FID1/$tfile" ||
15403                 error "$FID1/$tfile not returned in parent list (by fid)"
15404         echo "$parent" | grep -F "$FID2/link" ||
15405                 error "$FID2/link not returned in parent list (by fid)"
15406
15407         # 4) test for entry in root directory
15408         parent=$($LFS path2fid --parents $DIR/f)
15409         echo "$parent" | grep -F "$FID3/f" ||
15410                 error "$FID3/f not returned in parent list"
15411
15412         # 5) test it on root directory
15413         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15414                 error "$MOUNT should not have parents"
15415
15416         # enable xattr caching and check that linkea is correctly updated
15417         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15418         save_lustre_params client "llite.*.xattr_cache" > $save
15419         lctl set_param llite.*.xattr_cache 1
15420
15421         # 6.1) linkea update on rename
15422         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15423
15424         # get parents by fid
15425         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15426         # foo1 should no longer be returned in parent list
15427         echo "$parent" | grep -F "$FID1" &&
15428                 error "$FID1 should no longer be in parent list"
15429         # the new path should appear
15430         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15431                 error "$FID2/$tfile.moved is not in parent list"
15432
15433         # 6.2) linkea update on unlink
15434         rm -f $DIR/$tdir/foo2/link
15435         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15436         # foo2/link should no longer be returned in parent list
15437         echo "$parent" | grep -F "$FID2/link" &&
15438                 error "$FID2/link should no longer be in parent list"
15439         true
15440
15441         rm -f $DIR/f
15442         restore_lustre_params < $save
15443         rm -f $save
15444 }
15445 run_test 154f "get parent fids by reading link ea"
15446
15447 test_154g()
15448 {
15449         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15450         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15451            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15452                 skip "Need MDS version at least 2.6.92"
15453
15454         mkdir_on_mdt0 $DIR/$tdir
15455         llapi_fid_test -d $DIR/$tdir
15456 }
15457 run_test 154g "various llapi FID tests"
15458
15459 test_155_small_load() {
15460     local temp=$TMP/$tfile
15461     local file=$DIR/$tfile
15462
15463     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15464         error "dd of=$temp bs=6096 count=1 failed"
15465     cp $temp $file
15466     cancel_lru_locks $OSC
15467     cmp $temp $file || error "$temp $file differ"
15468
15469     $TRUNCATE $temp 6000
15470     $TRUNCATE $file 6000
15471     cmp $temp $file || error "$temp $file differ (truncate1)"
15472
15473     echo "12345" >>$temp
15474     echo "12345" >>$file
15475     cmp $temp $file || error "$temp $file differ (append1)"
15476
15477     echo "12345" >>$temp
15478     echo "12345" >>$file
15479     cmp $temp $file || error "$temp $file differ (append2)"
15480
15481     rm -f $temp $file
15482     true
15483 }
15484
15485 test_155_big_load() {
15486         remote_ost_nodsh && skip "remote OST with nodsh"
15487
15488         local temp=$TMP/$tfile
15489         local file=$DIR/$tfile
15490
15491         free_min_max
15492         local cache_size=$(do_facet ost$((MAXI+1)) \
15493                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15494         local large_file_size=$((cache_size * 2))
15495
15496         echo "OSS cache size: $cache_size KB"
15497         echo "Large file size: $large_file_size KB"
15498
15499         [ $MAXV -le $large_file_size ] &&
15500                 skip_env "max available OST size needs > $large_file_size KB"
15501
15502         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15503
15504         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15505                 error "dd of=$temp bs=$large_file_size count=1k failed"
15506         cp $temp $file
15507         ls -lh $temp $file
15508         cancel_lru_locks osc
15509         cmp $temp $file || error "$temp $file differ"
15510
15511         rm -f $temp $file
15512         true
15513 }
15514
15515 save_writethrough() {
15516         local facets=$(get_facets OST)
15517
15518         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15519 }
15520
15521 test_155a() {
15522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15523
15524         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15525
15526         save_writethrough $p
15527
15528         set_cache read on
15529         set_cache writethrough on
15530         test_155_small_load
15531         restore_lustre_params < $p
15532         rm -f $p
15533 }
15534 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15535
15536 test_155b() {
15537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15538
15539         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15540
15541         save_writethrough $p
15542
15543         set_cache read on
15544         set_cache writethrough off
15545         test_155_small_load
15546         restore_lustre_params < $p
15547         rm -f $p
15548 }
15549 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15550
15551 test_155c() {
15552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15553
15554         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15555
15556         save_writethrough $p
15557
15558         set_cache read off
15559         set_cache writethrough on
15560         test_155_small_load
15561         restore_lustre_params < $p
15562         rm -f $p
15563 }
15564 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15565
15566 test_155d() {
15567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15568
15569         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15570
15571         save_writethrough $p
15572
15573         set_cache read off
15574         set_cache writethrough off
15575         test_155_small_load
15576         restore_lustre_params < $p
15577         rm -f $p
15578 }
15579 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15580
15581 test_155e() {
15582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15583
15584         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15585
15586         save_writethrough $p
15587
15588         set_cache read on
15589         set_cache writethrough on
15590         test_155_big_load
15591         restore_lustre_params < $p
15592         rm -f $p
15593 }
15594 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15595
15596 test_155f() {
15597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15598
15599         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15600
15601         save_writethrough $p
15602
15603         set_cache read on
15604         set_cache writethrough off
15605         test_155_big_load
15606         restore_lustre_params < $p
15607         rm -f $p
15608 }
15609 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15610
15611 test_155g() {
15612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15613
15614         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15615
15616         save_writethrough $p
15617
15618         set_cache read off
15619         set_cache writethrough on
15620         test_155_big_load
15621         restore_lustre_params < $p
15622         rm -f $p
15623 }
15624 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15625
15626 test_155h() {
15627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15628
15629         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15630
15631         save_writethrough $p
15632
15633         set_cache read off
15634         set_cache writethrough off
15635         test_155_big_load
15636         restore_lustre_params < $p
15637         rm -f $p
15638 }
15639 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15640
15641 test_156() {
15642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15643         remote_ost_nodsh && skip "remote OST with nodsh"
15644         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15645                 skip "stats not implemented on old servers"
15646         [ "$ost1_FSTYPE" = "zfs" ] &&
15647                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15648
15649         local CPAGES=3
15650         local BEFORE
15651         local AFTER
15652         local file="$DIR/$tfile"
15653         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15654
15655         save_writethrough $p
15656         roc_hit_init
15657
15658         log "Turn on read and write cache"
15659         set_cache read on
15660         set_cache writethrough on
15661
15662         log "Write data and read it back."
15663         log "Read should be satisfied from the cache."
15664         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15665         BEFORE=$(roc_hit)
15666         cancel_lru_locks osc
15667         cat $file >/dev/null
15668         AFTER=$(roc_hit)
15669         if ! let "AFTER - BEFORE == CPAGES"; then
15670                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15671         else
15672                 log "cache hits: before: $BEFORE, after: $AFTER"
15673         fi
15674
15675         log "Read again; it should be satisfied from the cache."
15676         BEFORE=$AFTER
15677         cancel_lru_locks osc
15678         cat $file >/dev/null
15679         AFTER=$(roc_hit)
15680         if ! let "AFTER - BEFORE == CPAGES"; then
15681                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15682         else
15683                 log "cache hits:: before: $BEFORE, after: $AFTER"
15684         fi
15685
15686         log "Turn off the read cache and turn on the write cache"
15687         set_cache read off
15688         set_cache writethrough on
15689
15690         log "Read again; it should be satisfied from the cache."
15691         BEFORE=$(roc_hit)
15692         cancel_lru_locks osc
15693         cat $file >/dev/null
15694         AFTER=$(roc_hit)
15695         if ! let "AFTER - BEFORE == CPAGES"; then
15696                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15697         else
15698                 log "cache hits:: before: $BEFORE, after: $AFTER"
15699         fi
15700
15701         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15702                 # > 2.12.56 uses pagecache if cached
15703                 log "Read again; it should not be satisfied from the cache."
15704                 BEFORE=$AFTER
15705                 cancel_lru_locks osc
15706                 cat $file >/dev/null
15707                 AFTER=$(roc_hit)
15708                 if ! let "AFTER - BEFORE == 0"; then
15709                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15710                 else
15711                         log "cache hits:: before: $BEFORE, after: $AFTER"
15712                 fi
15713         fi
15714
15715         log "Write data and read it back."
15716         log "Read should be satisfied from the cache."
15717         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15718         BEFORE=$(roc_hit)
15719         cancel_lru_locks osc
15720         cat $file >/dev/null
15721         AFTER=$(roc_hit)
15722         if ! let "AFTER - BEFORE == CPAGES"; then
15723                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15724         else
15725                 log "cache hits:: before: $BEFORE, after: $AFTER"
15726         fi
15727
15728         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15729                 # > 2.12.56 uses pagecache if cached
15730                 log "Read again; it should not be satisfied from the cache."
15731                 BEFORE=$AFTER
15732                 cancel_lru_locks osc
15733                 cat $file >/dev/null
15734                 AFTER=$(roc_hit)
15735                 if ! let "AFTER - BEFORE == 0"; then
15736                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15737                 else
15738                         log "cache hits:: before: $BEFORE, after: $AFTER"
15739                 fi
15740         fi
15741
15742         log "Turn off read and write cache"
15743         set_cache read off
15744         set_cache writethrough off
15745
15746         log "Write data and read it back"
15747         log "It should not be satisfied from the cache."
15748         rm -f $file
15749         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15750         cancel_lru_locks osc
15751         BEFORE=$(roc_hit)
15752         cat $file >/dev/null
15753         AFTER=$(roc_hit)
15754         if ! let "AFTER - BEFORE == 0"; then
15755                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15756         else
15757                 log "cache hits:: before: $BEFORE, after: $AFTER"
15758         fi
15759
15760         log "Turn on the read cache and turn off the write cache"
15761         set_cache read on
15762         set_cache writethrough off
15763
15764         log "Write data and read it back"
15765         log "It should not be satisfied from the cache."
15766         rm -f $file
15767         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15768         BEFORE=$(roc_hit)
15769         cancel_lru_locks osc
15770         cat $file >/dev/null
15771         AFTER=$(roc_hit)
15772         if ! let "AFTER - BEFORE == 0"; then
15773                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15774         else
15775                 log "cache hits:: before: $BEFORE, after: $AFTER"
15776         fi
15777
15778         log "Read again; it should be satisfied from the cache."
15779         BEFORE=$(roc_hit)
15780         cancel_lru_locks osc
15781         cat $file >/dev/null
15782         AFTER=$(roc_hit)
15783         if ! let "AFTER - BEFORE == CPAGES"; then
15784                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15785         else
15786                 log "cache hits:: before: $BEFORE, after: $AFTER"
15787         fi
15788
15789         restore_lustre_params < $p
15790         rm -f $p $file
15791 }
15792 run_test 156 "Verification of tunables"
15793
15794 test_160a() {
15795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15796         remote_mds_nodsh && skip "remote MDS with nodsh"
15797         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15798                 skip "Need MDS version at least 2.2.0"
15799
15800         changelog_register || error "changelog_register failed"
15801         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15802         changelog_users $SINGLEMDS | grep -q $cl_user ||
15803                 error "User $cl_user not found in changelog_users"
15804
15805         mkdir_on_mdt0 $DIR/$tdir
15806
15807         # change something
15808         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15809         changelog_clear 0 || error "changelog_clear failed"
15810         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15811         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15812         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15813         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15814         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15815         rm $DIR/$tdir/pics/desktop.jpg
15816
15817         echo "verifying changelog mask"
15818         changelog_chmask "-MKDIR"
15819         changelog_chmask "-CLOSE"
15820
15821         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15822         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15823
15824         changelog_chmask "+MKDIR"
15825         changelog_chmask "+CLOSE"
15826
15827         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15828         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15829
15830         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15831         CLOSES=$(changelog_dump | grep -c "CLOSE")
15832         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15833         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15834
15835         # verify contents
15836         echo "verifying target fid"
15837         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15838         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15839         [ "$fidc" == "$fidf" ] ||
15840                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15841         echo "verifying parent fid"
15842         # The FID returned from the Changelog may be the directory shard on
15843         # a different MDT, and not the FID returned by path2fid on the parent.
15844         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15845         # since this is what will matter when recreating this file in the tree.
15846         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15847         local pathp=$($LFS fid2path $MOUNT "$fidp")
15848         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15849                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15850
15851         echo "getting records for $cl_user"
15852         changelog_users $SINGLEMDS
15853         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15854         local nclr=3
15855         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15856                 error "changelog_clear failed"
15857         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15858         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15859         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15860                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15861
15862         local min0_rec=$(changelog_users $SINGLEMDS |
15863                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15864         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15865                           awk '{ print $1; exit; }')
15866
15867         changelog_dump | tail -n 5
15868         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15869         [ $first_rec == $((min0_rec + 1)) ] ||
15870                 error "first index should be $min0_rec + 1 not $first_rec"
15871
15872         # LU-3446 changelog index reset on MDT restart
15873         local cur_rec1=$(changelog_users $SINGLEMDS |
15874                          awk '/^current.index:/ { print $NF }')
15875         changelog_clear 0 ||
15876                 error "clear all changelog records for $cl_user failed"
15877         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15878         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15879                 error "Fail to start $SINGLEMDS"
15880         local cur_rec2=$(changelog_users $SINGLEMDS |
15881                          awk '/^current.index:/ { print $NF }')
15882         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15883         [ $cur_rec1 == $cur_rec2 ] ||
15884                 error "current index should be $cur_rec1 not $cur_rec2"
15885
15886         echo "verifying users from this test are deregistered"
15887         changelog_deregister || error "changelog_deregister failed"
15888         changelog_users $SINGLEMDS | grep -q $cl_user &&
15889                 error "User '$cl_user' still in changelog_users"
15890
15891         # lctl get_param -n mdd.*.changelog_users
15892         # current_index: 144
15893         # ID    index (idle seconds)
15894         # cl3   144   (2) mask=<list>
15895         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15896                 # this is the normal case where all users were deregistered
15897                 # make sure no new records are added when no users are present
15898                 local last_rec1=$(changelog_users $SINGLEMDS |
15899                                   awk '/^current.index:/ { print $NF }')
15900                 touch $DIR/$tdir/chloe
15901                 local last_rec2=$(changelog_users $SINGLEMDS |
15902                                   awk '/^current.index:/ { print $NF }')
15903                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15904                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15905         else
15906                 # any changelog users must be leftovers from a previous test
15907                 changelog_users $SINGLEMDS
15908                 echo "other changelog users; can't verify off"
15909         fi
15910 }
15911 run_test 160a "changelog sanity"
15912
15913 test_160b() { # LU-3587
15914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15915         remote_mds_nodsh && skip "remote MDS with nodsh"
15916         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15917                 skip "Need MDS version at least 2.2.0"
15918
15919         changelog_register || error "changelog_register failed"
15920         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15921         changelog_users $SINGLEMDS | grep -q $cl_user ||
15922                 error "User '$cl_user' not found in changelog_users"
15923
15924         local longname1=$(str_repeat a 255)
15925         local longname2=$(str_repeat b 255)
15926
15927         cd $DIR
15928         echo "creating very long named file"
15929         touch $longname1 || error "create of '$longname1' failed"
15930         echo "renaming very long named file"
15931         mv $longname1 $longname2
15932
15933         changelog_dump | grep RENME | tail -n 5
15934         rm -f $longname2
15935 }
15936 run_test 160b "Verify that very long rename doesn't crash in changelog"
15937
15938 test_160c() {
15939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15940         remote_mds_nodsh && skip "remote MDS with nodsh"
15941
15942         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15943                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15944                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15945                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15946
15947         local rc=0
15948
15949         # Registration step
15950         changelog_register || error "changelog_register failed"
15951
15952         rm -rf $DIR/$tdir
15953         mkdir -p $DIR/$tdir
15954         $MCREATE $DIR/$tdir/foo_160c
15955         changelog_chmask "-TRUNC"
15956         $TRUNCATE $DIR/$tdir/foo_160c 200
15957         changelog_chmask "+TRUNC"
15958         $TRUNCATE $DIR/$tdir/foo_160c 199
15959         changelog_dump | tail -n 5
15960         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15961         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15962 }
15963 run_test 160c "verify that changelog log catch the truncate event"
15964
15965 test_160d() {
15966         remote_mds_nodsh && skip "remote MDS with nodsh"
15967         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15969         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15970                 skip "Need MDS version at least 2.7.60"
15971
15972         # Registration step
15973         changelog_register || error "changelog_register failed"
15974
15975         mkdir -p $DIR/$tdir/migrate_dir
15976         changelog_clear 0 || error "changelog_clear failed"
15977
15978         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15979         changelog_dump | tail -n 5
15980         local migrates=$(changelog_dump | grep -c "MIGRT")
15981         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15982 }
15983 run_test 160d "verify that changelog log catch the migrate event"
15984
15985 test_160e() {
15986         remote_mds_nodsh && skip "remote MDS with nodsh"
15987
15988         # Create a user
15989         changelog_register || error "changelog_register failed"
15990
15991         local MDT0=$(facet_svc $SINGLEMDS)
15992         local rc
15993
15994         # No user (expect fail)
15995         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15996         rc=$?
15997         if [ $rc -eq 0 ]; then
15998                 error "Should fail without user"
15999         elif [ $rc -ne 4 ]; then
16000                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16001         fi
16002
16003         # Delete a future user (expect fail)
16004         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16005         rc=$?
16006         if [ $rc -eq 0 ]; then
16007                 error "Deleted non-existant user cl77"
16008         elif [ $rc -ne 2 ]; then
16009                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16010         fi
16011
16012         # Clear to a bad index (1 billion should be safe)
16013         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16014         rc=$?
16015
16016         if [ $rc -eq 0 ]; then
16017                 error "Successfully cleared to invalid CL index"
16018         elif [ $rc -ne 22 ]; then
16019                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16020         fi
16021 }
16022 run_test 160e "changelog negative testing (should return errors)"
16023
16024 test_160f() {
16025         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16026         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16027                 skip "Need MDS version at least 2.10.56"
16028
16029         local mdts=$(comma_list $(mdts_nodes))
16030
16031         # Create a user
16032         changelog_register || error "first changelog_register failed"
16033         changelog_register || error "second changelog_register failed"
16034         local cl_users
16035         declare -A cl_user1
16036         declare -A cl_user2
16037         local user_rec1
16038         local user_rec2
16039         local i
16040
16041         # generate some changelog records to accumulate on each MDT
16042         # use all_char because created files should be evenly distributed
16043         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16044                 error "test_mkdir $tdir failed"
16045         log "$(date +%s): creating first files"
16046         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16047                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16048                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16049         done
16050
16051         # check changelogs have been generated
16052         local start=$SECONDS
16053         local idle_time=$((MDSCOUNT * 5 + 5))
16054         local nbcl=$(changelog_dump | wc -l)
16055         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16056
16057         for param in "changelog_max_idle_time=$idle_time" \
16058                      "changelog_gc=1" \
16059                      "changelog_min_gc_interval=2" \
16060                      "changelog_min_free_cat_entries=3"; do
16061                 local MDT0=$(facet_svc $SINGLEMDS)
16062                 local var="${param%=*}"
16063                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16064
16065                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16066                 do_nodes $mdts $LCTL set_param mdd.*.$param
16067         done
16068
16069         # force cl_user2 to be idle (1st part), but also cancel the
16070         # cl_user1 records so that it is not evicted later in the test.
16071         local sleep1=$((idle_time / 2))
16072         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16073         sleep $sleep1
16074
16075         # simulate changelog catalog almost full
16076         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16077         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16078
16079         for i in $(seq $MDSCOUNT); do
16080                 cl_users=(${CL_USERS[mds$i]})
16081                 cl_user1[mds$i]="${cl_users[0]}"
16082                 cl_user2[mds$i]="${cl_users[1]}"
16083
16084                 [ -n "${cl_user1[mds$i]}" ] ||
16085                         error "mds$i: no user registered"
16086                 [ -n "${cl_user2[mds$i]}" ] ||
16087                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16088
16089                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16090                 [ -n "$user_rec1" ] ||
16091                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16092                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16093                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16094                 [ -n "$user_rec2" ] ||
16095                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16096                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16097                      "$user_rec1 + 2 == $user_rec2"
16098                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16099                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16100                               "$user_rec1 + 2, but is $user_rec2"
16101                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16102                 [ -n "$user_rec2" ] ||
16103                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16104                 [ $user_rec1 == $user_rec2 ] ||
16105                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16106                               "$user_rec1, but is $user_rec2"
16107         done
16108
16109         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16110         local sleep2=$((idle_time - (SECONDS - start) + 1))
16111         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16112         sleep $sleep2
16113
16114         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16115         # cl_user1 should be OK because it recently processed records.
16116         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16117         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16118                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16119                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16120         done
16121
16122         # ensure gc thread is done
16123         for i in $(mdts_nodes); do
16124                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16125                         error "$i: GC-thread not done"
16126         done
16127
16128         local first_rec
16129         for (( i = 1; i <= MDSCOUNT; i++ )); do
16130                 # check cl_user1 still registered
16131                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16132                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16133                 # check cl_user2 unregistered
16134                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16135                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16136
16137                 # check changelogs are present and starting at $user_rec1 + 1
16138                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16139                 [ -n "$user_rec1" ] ||
16140                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16141                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16142                             awk '{ print $1; exit; }')
16143
16144                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16145                 [ $((user_rec1 + 1)) == $first_rec ] ||
16146                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16147         done
16148 }
16149 run_test 160f "changelog garbage collect (timestamped users)"
16150
16151 test_160g() {
16152         remote_mds_nodsh && skip "remote MDS with nodsh"
16153         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16154                 skip "Need MDS version at least 2.14.55"
16155
16156         local mdts=$(comma_list $(mdts_nodes))
16157
16158         # Create a user
16159         changelog_register || error "first changelog_register failed"
16160         changelog_register || error "second changelog_register failed"
16161         local cl_users
16162         declare -A cl_user1
16163         declare -A cl_user2
16164         local user_rec1
16165         local user_rec2
16166         local i
16167
16168         # generate some changelog records to accumulate on each MDT
16169         # use all_char because created files should be evenly distributed
16170         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16171                 error "test_mkdir $tdir failed"
16172         for ((i = 0; i < MDSCOUNT; i++)); do
16173                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16174                         error "create $DIR/$tdir/d$i.1 failed"
16175         done
16176
16177         # check changelogs have been generated
16178         local nbcl=$(changelog_dump | wc -l)
16179         (( $nbcl > 0 )) || error "no changelogs found"
16180
16181         # reduce the max_idle_indexes value to make sure we exceed it
16182         for param in "changelog_max_idle_indexes=2" \
16183                      "changelog_gc=1" \
16184                      "changelog_min_gc_interval=2"; do
16185                 local MDT0=$(facet_svc $SINGLEMDS)
16186                 local var="${param%=*}"
16187                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16188
16189                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16190                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16191                         error "unable to set mdd.*.$param"
16192         done
16193
16194         local start=$SECONDS
16195         for i in $(seq $MDSCOUNT); do
16196                 cl_users=(${CL_USERS[mds$i]})
16197                 cl_user1[mds$i]="${cl_users[0]}"
16198                 cl_user2[mds$i]="${cl_users[1]}"
16199
16200                 [ -n "${cl_user1[mds$i]}" ] ||
16201                         error "mds$i: user1 is not registered"
16202                 [ -n "${cl_user2[mds$i]}" ] ||
16203                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16204
16205                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16206                 [ -n "$user_rec1" ] ||
16207                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16208                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16209                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16210                 [ -n "$user_rec2" ] ||
16211                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16212                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16213                      "$user_rec1 + 2 == $user_rec2"
16214                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16215                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16216                               "expected $user_rec1 + 2, but is $user_rec2"
16217                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16218                 [ -n "$user_rec2" ] ||
16219                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16220                 [ $user_rec1 == $user_rec2 ] ||
16221                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16222                               "expected $user_rec1, but is $user_rec2"
16223         done
16224
16225         # ensure we are past the previous changelog_min_gc_interval set above
16226         local sleep2=$((start + 2 - SECONDS))
16227         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16228         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16229         # cl_user1 should be OK because it recently processed records.
16230         for ((i = 0; i < MDSCOUNT; i++)); do
16231                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16232                         error "create $DIR/$tdir/d$i.3 failed"
16233         done
16234
16235         # ensure gc thread is done
16236         for i in $(mdts_nodes); do
16237                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16238                         error "$i: GC-thread not done"
16239         done
16240
16241         local first_rec
16242         for (( i = 1; i <= MDSCOUNT; i++ )); do
16243                 # check cl_user1 still registered
16244                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16245                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16246                 # check cl_user2 unregistered
16247                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16248                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16249
16250                 # check changelogs are present and starting at $user_rec1 + 1
16251                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16252                 [ -n "$user_rec1" ] ||
16253                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16254                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16255                             awk '{ print $1; exit; }')
16256
16257                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16258                 [ $((user_rec1 + 1)) == $first_rec ] ||
16259                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16260         done
16261 }
16262 run_test 160g "changelog garbage collect on idle records"
16263
16264 test_160h() {
16265         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16266         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16267                 skip "Need MDS version at least 2.10.56"
16268
16269         local mdts=$(comma_list $(mdts_nodes))
16270
16271         # Create a user
16272         changelog_register || error "first changelog_register failed"
16273         changelog_register || error "second changelog_register failed"
16274         local cl_users
16275         declare -A cl_user1
16276         declare -A cl_user2
16277         local user_rec1
16278         local user_rec2
16279         local i
16280
16281         # generate some changelog records to accumulate on each MDT
16282         # use all_char because created files should be evenly distributed
16283         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16284                 error "test_mkdir $tdir failed"
16285         for ((i = 0; i < MDSCOUNT; i++)); do
16286                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16287                         error "create $DIR/$tdir/d$i.1 failed"
16288         done
16289
16290         # check changelogs have been generated
16291         local nbcl=$(changelog_dump | wc -l)
16292         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16293
16294         for param in "changelog_max_idle_time=10" \
16295                      "changelog_gc=1" \
16296                      "changelog_min_gc_interval=2"; do
16297                 local MDT0=$(facet_svc $SINGLEMDS)
16298                 local var="${param%=*}"
16299                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16300
16301                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16302                 do_nodes $mdts $LCTL set_param mdd.*.$param
16303         done
16304
16305         # force cl_user2 to be idle (1st part)
16306         sleep 9
16307
16308         for i in $(seq $MDSCOUNT); do
16309                 cl_users=(${CL_USERS[mds$i]})
16310                 cl_user1[mds$i]="${cl_users[0]}"
16311                 cl_user2[mds$i]="${cl_users[1]}"
16312
16313                 [ -n "${cl_user1[mds$i]}" ] ||
16314                         error "mds$i: no user registered"
16315                 [ -n "${cl_user2[mds$i]}" ] ||
16316                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16317
16318                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16319                 [ -n "$user_rec1" ] ||
16320                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16321                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16322                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16323                 [ -n "$user_rec2" ] ||
16324                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16325                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16326                      "$user_rec1 + 2 == $user_rec2"
16327                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16328                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16329                               "$user_rec1 + 2, but is $user_rec2"
16330                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16331                 [ -n "$user_rec2" ] ||
16332                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16333                 [ $user_rec1 == $user_rec2 ] ||
16334                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16335                               "$user_rec1, but is $user_rec2"
16336         done
16337
16338         # force cl_user2 to be idle (2nd part) and to reach
16339         # changelog_max_idle_time
16340         sleep 2
16341
16342         # force each GC-thread start and block then
16343         # one per MDT/MDD, set fail_val accordingly
16344         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16345         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16346
16347         # generate more changelogs to trigger fail_loc
16348         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16349                 error "create $DIR/$tdir/${tfile}bis failed"
16350
16351         # stop MDT to stop GC-thread, should be done in back-ground as it will
16352         # block waiting for the thread to be released and exit
16353         declare -A stop_pids
16354         for i in $(seq $MDSCOUNT); do
16355                 stop mds$i &
16356                 stop_pids[mds$i]=$!
16357         done
16358
16359         for i in $(mdts_nodes); do
16360                 local facet
16361                 local nb=0
16362                 local facets=$(facets_up_on_host $i)
16363
16364                 for facet in ${facets//,/ }; do
16365                         if [[ $facet == mds* ]]; then
16366                                 nb=$((nb + 1))
16367                         fi
16368                 done
16369                 # ensure each MDS's gc threads are still present and all in "R"
16370                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16371                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16372                         error "$i: expected $nb GC-thread"
16373                 wait_update $i \
16374                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16375                         "R" 20 ||
16376                         error "$i: GC-thread not found in R-state"
16377                 # check umounts of each MDT on MDS have reached kthread_stop()
16378                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16379                         error "$i: expected $nb umount"
16380                 wait_update $i \
16381                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16382                         error "$i: umount not found in D-state"
16383         done
16384
16385         # release all GC-threads
16386         do_nodes $mdts $LCTL set_param fail_loc=0
16387
16388         # wait for MDT stop to complete
16389         for i in $(seq $MDSCOUNT); do
16390                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16391         done
16392
16393         # XXX
16394         # may try to check if any orphan changelog records are present
16395         # via ldiskfs/zfs and llog_reader...
16396
16397         # re-start/mount MDTs
16398         for i in $(seq $MDSCOUNT); do
16399                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16400                         error "Fail to start mds$i"
16401         done
16402
16403         local first_rec
16404         for i in $(seq $MDSCOUNT); do
16405                 # check cl_user1 still registered
16406                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16407                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16408                 # check cl_user2 unregistered
16409                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16410                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16411
16412                 # check changelogs are present and starting at $user_rec1 + 1
16413                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16414                 [ -n "$user_rec1" ] ||
16415                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16416                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16417                             awk '{ print $1; exit; }')
16418
16419                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16420                 [ $((user_rec1 + 1)) == $first_rec ] ||
16421                         error "mds$i: first index should be $user_rec1 + 1, " \
16422                               "but is $first_rec"
16423         done
16424 }
16425 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16426               "during mount"
16427
16428 test_160i() {
16429
16430         local mdts=$(comma_list $(mdts_nodes))
16431
16432         changelog_register || error "first changelog_register failed"
16433
16434         # generate some changelog records to accumulate on each MDT
16435         # use all_char because created files should be evenly distributed
16436         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16437                 error "test_mkdir $tdir failed"
16438         for ((i = 0; i < MDSCOUNT; i++)); do
16439                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16440                         error "create $DIR/$tdir/d$i.1 failed"
16441         done
16442
16443         # check changelogs have been generated
16444         local nbcl=$(changelog_dump | wc -l)
16445         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16446
16447         # simulate race between register and unregister
16448         # XXX as fail_loc is set per-MDS, with DNE configs the race
16449         # simulation will only occur for one MDT per MDS and for the
16450         # others the normal race scenario will take place
16451         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16452         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16453         do_nodes $mdts $LCTL set_param fail_val=1
16454
16455         # unregister 1st user
16456         changelog_deregister &
16457         local pid1=$!
16458         # wait some time for deregister work to reach race rdv
16459         sleep 2
16460         # register 2nd user
16461         changelog_register || error "2nd user register failed"
16462
16463         wait $pid1 || error "1st user deregister failed"
16464
16465         local i
16466         local last_rec
16467         declare -A LAST_REC
16468         for i in $(seq $MDSCOUNT); do
16469                 if changelog_users mds$i | grep "^cl"; then
16470                         # make sure new records are added with one user present
16471                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16472                                           awk '/^current.index:/ { print $NF }')
16473                 else
16474                         error "mds$i has no user registered"
16475                 fi
16476         done
16477
16478         # generate more changelog records to accumulate on each MDT
16479         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16480                 error "create $DIR/$tdir/${tfile}bis failed"
16481
16482         for i in $(seq $MDSCOUNT); do
16483                 last_rec=$(changelog_users $SINGLEMDS |
16484                            awk '/^current.index:/ { print $NF }')
16485                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16486                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16487                         error "changelogs are off on mds$i"
16488         done
16489 }
16490 run_test 160i "changelog user register/unregister race"
16491
16492 test_160j() {
16493         remote_mds_nodsh && skip "remote MDS with nodsh"
16494         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16495                 skip "Need MDS version at least 2.12.56"
16496
16497         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16498         stack_trap "umount $MOUNT2" EXIT
16499
16500         changelog_register || error "first changelog_register failed"
16501         stack_trap "changelog_deregister" EXIT
16502
16503         # generate some changelog
16504         # use all_char because created files should be evenly distributed
16505         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16506                 error "mkdir $tdir failed"
16507         for ((i = 0; i < MDSCOUNT; i++)); do
16508                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16509                         error "create $DIR/$tdir/d$i.1 failed"
16510         done
16511
16512         # open the changelog device
16513         exec 3>/dev/changelog-$FSNAME-MDT0000
16514         stack_trap "exec 3>&-" EXIT
16515         exec 4</dev/changelog-$FSNAME-MDT0000
16516         stack_trap "exec 4<&-" EXIT
16517
16518         # umount the first lustre mount
16519         umount $MOUNT
16520         stack_trap "mount_client $MOUNT" EXIT
16521
16522         # read changelog, which may or may not fail, but should not crash
16523         cat <&4 >/dev/null
16524
16525         # clear changelog
16526         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16527         changelog_users $SINGLEMDS | grep -q $cl_user ||
16528                 error "User $cl_user not found in changelog_users"
16529
16530         printf 'clear:'$cl_user':0' >&3
16531 }
16532 run_test 160j "client can be umounted while its chanangelog is being used"
16533
16534 test_160k() {
16535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16536         remote_mds_nodsh && skip "remote MDS with nodsh"
16537
16538         mkdir -p $DIR/$tdir/1/1
16539
16540         changelog_register || error "changelog_register failed"
16541         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16542
16543         changelog_users $SINGLEMDS | grep -q $cl_user ||
16544                 error "User '$cl_user' not found in changelog_users"
16545 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16546         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16547         rmdir $DIR/$tdir/1/1 & sleep 1
16548         mkdir $DIR/$tdir/2
16549         touch $DIR/$tdir/2/2
16550         rm -rf $DIR/$tdir/2
16551
16552         wait
16553         sleep 4
16554
16555         changelog_dump | grep rmdir || error "rmdir not recorded"
16556 }
16557 run_test 160k "Verify that changelog records are not lost"
16558
16559 # Verifies that a file passed as a parameter has recently had an operation
16560 # performed on it that has generated an MTIME changelog which contains the
16561 # correct parent FID. As files might reside on a different MDT from the
16562 # parent directory in DNE configurations, the FIDs are translated to paths
16563 # before being compared, which should be identical
16564 compare_mtime_changelog() {
16565         local file="${1}"
16566         local mdtidx
16567         local mtime
16568         local cl_fid
16569         local pdir
16570         local dir
16571
16572         mdtidx=$($LFS getstripe --mdt-index $file)
16573         mdtidx=$(printf "%04x" $mdtidx)
16574
16575         # Obtain the parent FID from the MTIME changelog
16576         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16577         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16578
16579         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16580         [ -z "$cl_fid" ] && error "parent FID not present"
16581
16582         # Verify that the path for the parent FID is the same as the path for
16583         # the test directory
16584         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16585
16586         dir=$(dirname $1)
16587
16588         [[ "${pdir%/}" == "$dir" ]] ||
16589                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16590 }
16591
16592 test_160l() {
16593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16594
16595         remote_mds_nodsh && skip "remote MDS with nodsh"
16596         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16597                 skip "Need MDS version at least 2.13.55"
16598
16599         local cl_user
16600
16601         changelog_register || error "changelog_register failed"
16602         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16603
16604         changelog_users $SINGLEMDS | grep -q $cl_user ||
16605                 error "User '$cl_user' not found in changelog_users"
16606
16607         # Clear some types so that MTIME changelogs are generated
16608         changelog_chmask "-CREAT"
16609         changelog_chmask "-CLOSE"
16610
16611         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16612
16613         # Test CL_MTIME during setattr
16614         touch $DIR/$tdir/$tfile
16615         compare_mtime_changelog $DIR/$tdir/$tfile
16616
16617         # Test CL_MTIME during close
16618         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16619         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16620 }
16621 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16622
16623 test_160m() {
16624         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16625         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16626                 skip "Need MDS version at least 2.14.51"
16627         local cl_users
16628         local cl_user1
16629         local cl_user2
16630         local pid1
16631
16632         # Create a user
16633         changelog_register || error "first changelog_register failed"
16634         changelog_register || error "second changelog_register failed"
16635
16636         cl_users=(${CL_USERS[mds1]})
16637         cl_user1="${cl_users[0]}"
16638         cl_user2="${cl_users[1]}"
16639         # generate some changelog records to accumulate on MDT0
16640         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16641         createmany -m $DIR/$tdir/$tfile 50 ||
16642                 error "create $DIR/$tdir/$tfile failed"
16643         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16644         rm -f $DIR/$tdir
16645
16646         # check changelogs have been generated
16647         local nbcl=$(changelog_dump | wc -l)
16648         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16649
16650 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16651         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16652
16653         __changelog_clear mds1 $cl_user1 +10
16654         __changelog_clear mds1 $cl_user2 0 &
16655         pid1=$!
16656         sleep 2
16657         __changelog_clear mds1 $cl_user1 0 ||
16658                 error "fail to cancel record for $cl_user1"
16659         wait $pid1
16660         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16661 }
16662 run_test 160m "Changelog clear race"
16663
16664 test_160n() {
16665         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16666         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16667                 skip "Need MDS version at least 2.14.51"
16668         local cl_users
16669         local cl_user1
16670         local cl_user2
16671         local pid1
16672         local first_rec
16673         local last_rec=0
16674
16675         # Create a user
16676         changelog_register || error "first changelog_register failed"
16677
16678         cl_users=(${CL_USERS[mds1]})
16679         cl_user1="${cl_users[0]}"
16680
16681         # generate some changelog records to accumulate on MDT0
16682         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16683         first_rec=$(changelog_users $SINGLEMDS |
16684                         awk '/^current.index:/ { print $NF }')
16685         while (( last_rec < (( first_rec + 65000)) )); do
16686                 createmany -m $DIR/$tdir/$tfile 10000 ||
16687                         error "create $DIR/$tdir/$tfile failed"
16688
16689                 for i in $(seq 0 10000); do
16690                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16691                                 > /dev/null
16692                 done
16693
16694                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16695                         error "unlinkmany failed unlink"
16696                 last_rec=$(changelog_users $SINGLEMDS |
16697                         awk '/^current.index:/ { print $NF }')
16698                 echo last record $last_rec
16699                 (( last_rec == 0 )) && error "no changelog found"
16700         done
16701
16702 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16703         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16704
16705         __changelog_clear mds1 $cl_user1 0 &
16706         pid1=$!
16707         sleep 2
16708         __changelog_clear mds1 $cl_user1 0 ||
16709                 error "fail to cancel record for $cl_user1"
16710         wait $pid1
16711         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16712 }
16713 run_test 160n "Changelog destroy race"
16714
16715 test_160o() {
16716         local mdt="$(facet_svc $SINGLEMDS)"
16717
16718         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16719         remote_mds_nodsh && skip "remote MDS with nodsh"
16720         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16721                 skip "Need MDS version at least 2.14.52"
16722
16723         changelog_register --user test_160o -m unlnk+close+open ||
16724                 error "changelog_register failed"
16725
16726         do_facet $SINGLEMDS $LCTL --device $mdt \
16727                                 changelog_register -u "Tt3_-#" &&
16728                 error "bad symbols in name should fail"
16729
16730         do_facet $SINGLEMDS $LCTL --device $mdt \
16731                                 changelog_register -u test_160o &&
16732                 error "the same name registration should fail"
16733
16734         do_facet $SINGLEMDS $LCTL --device $mdt \
16735                         changelog_register -u test_160toolongname &&
16736                 error "too long name registration should fail"
16737
16738         changelog_chmask "MARK+HSM"
16739         lctl get_param mdd.*.changelog*mask
16740         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16741         changelog_users $SINGLEMDS | grep -q $cl_user ||
16742                 error "User $cl_user not found in changelog_users"
16743         #verify username
16744         echo $cl_user | grep -q test_160o ||
16745                 error "User $cl_user has no specific name 'test160o'"
16746
16747         # change something
16748         changelog_clear 0 || error "changelog_clear failed"
16749         # generate some changelog records to accumulate on MDT0
16750         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16751         touch $DIR/$tdir/$tfile                 # open 1
16752
16753         OPENS=$(changelog_dump | grep -c "OPEN")
16754         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16755
16756         # must be no MKDIR it wasn't set as user mask
16757         MKDIR=$(changelog_dump | grep -c "MKDIR")
16758         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16759
16760         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16761                                 mdd.$mdt.changelog_current_mask -n)
16762         # register maskless user
16763         changelog_register || error "changelog_register failed"
16764         # effective mask should be not changed because it is not minimal
16765         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16766                                 mdd.$mdt.changelog_current_mask -n)
16767         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16768         # set server mask to minimal value
16769         changelog_chmask "MARK"
16770         # check effective mask again, should be treated as DEFMASK now
16771         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16772                                 mdd.$mdt.changelog_current_mask -n)
16773         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16774
16775         do_facet $SINGLEMDS $LCTL --device $mdt \
16776                                 changelog_deregister -u test_160o ||
16777                 error "cannot deregister by name"
16778 }
16779 run_test 160o "changelog user name and mask"
16780
16781 test_160p() {
16782         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16783         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16784                 skip "Need MDS version at least 2.14.51"
16785         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16786         local cl_users
16787         local cl_user1
16788         local entry_count
16789
16790         # Create a user
16791         changelog_register || error "first changelog_register failed"
16792
16793         cl_users=(${CL_USERS[mds1]})
16794         cl_user1="${cl_users[0]}"
16795
16796         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16797         createmany -m $DIR/$tdir/$tfile 50 ||
16798                 error "create $DIR/$tdir/$tfile failed"
16799         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16800         rm -rf $DIR/$tdir
16801
16802         # check changelogs have been generated
16803         entry_count=$(changelog_dump | wc -l)
16804         ((entry_count != 0)) || error "no changelog entries found"
16805
16806         # remove changelog_users and check that orphan entries are removed
16807         stop mds1
16808         local dev=$(mdsdevname 1)
16809         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16810         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16811         entry_count=$(changelog_dump | wc -l)
16812         ((entry_count == 0)) ||
16813                 error "found $entry_count changelog entries, expected none"
16814 }
16815 run_test 160p "Changelog orphan cleanup with no users"
16816
16817 test_160q() {
16818         local mdt="$(facet_svc $SINGLEMDS)"
16819         local clu
16820
16821         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16822         remote_mds_nodsh && skip "remote MDS with nodsh"
16823         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16824                 skip "Need MDS version at least 2.14.54"
16825
16826         # set server mask to minimal value like server init does
16827         changelog_chmask "MARK"
16828         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16829                 error "changelog_register failed"
16830         # check effective mask again, should be treated as DEFMASK now
16831         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16832                                 mdd.$mdt.changelog_current_mask -n)
16833         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16834                 error "changelog_deregister failed"
16835         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16836 }
16837 run_test 160q "changelog effective mask is DEFMASK if not set"
16838
16839 test_160s() {
16840         remote_mds_nodsh && skip "remote MDS with nodsh"
16841         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16842                 skip "Need MDS version at least 2.14.55"
16843
16844         local mdts=$(comma_list $(mdts_nodes))
16845
16846         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16847         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16848                                        fail_val=$((24 * 3600 * 10))
16849
16850         # Create a user which is 10 days old
16851         changelog_register || error "first changelog_register failed"
16852         local cl_users
16853         declare -A cl_user1
16854         local i
16855
16856         # generate some changelog records to accumulate on each MDT
16857         # use all_char because created files should be evenly distributed
16858         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16859                 error "test_mkdir $tdir failed"
16860         for ((i = 0; i < MDSCOUNT; i++)); do
16861                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16862                         error "create $DIR/$tdir/d$i.1 failed"
16863         done
16864
16865         # check changelogs have been generated
16866         local nbcl=$(changelog_dump | wc -l)
16867         (( nbcl > 0 )) || error "no changelogs found"
16868
16869         # reduce the max_idle_indexes value to make sure we exceed it
16870         for param in "changelog_max_idle_indexes=2097446912" \
16871                      "changelog_max_idle_time=2592000" \
16872                      "changelog_gc=1" \
16873                      "changelog_min_gc_interval=2"; do
16874                 local MDT0=$(facet_svc $SINGLEMDS)
16875                 local var="${param%=*}"
16876                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16877
16878                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16879                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16880                         error "unable to set mdd.*.$param"
16881         done
16882
16883         local start=$SECONDS
16884         for i in $(seq $MDSCOUNT); do
16885                 cl_users=(${CL_USERS[mds$i]})
16886                 cl_user1[mds$i]="${cl_users[0]}"
16887
16888                 [[ -n "${cl_user1[mds$i]}" ]] ||
16889                         error "mds$i: no user registered"
16890         done
16891
16892         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16893         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16894
16895         # ensure we are past the previous changelog_min_gc_interval set above
16896         local sleep2=$((start + 2 - SECONDS))
16897         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16898
16899         # Generate one more changelog to trigger GC
16900         for ((i = 0; i < MDSCOUNT; i++)); do
16901                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16902                         error "create $DIR/$tdir/d$i.3 failed"
16903         done
16904
16905         # ensure gc thread is done
16906         for node in $(mdts_nodes); do
16907                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16908                         error "$node: GC-thread not done"
16909         done
16910
16911         do_nodes $mdts $LCTL set_param fail_loc=0
16912
16913         for (( i = 1; i <= MDSCOUNT; i++ )); do
16914                 # check cl_user1 is purged
16915                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16916                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16917         done
16918         return 0
16919 }
16920 run_test 160s "changelog garbage collect on idle records * time"
16921
16922 test_161a() {
16923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16924
16925         test_mkdir -c1 $DIR/$tdir
16926         cp /etc/hosts $DIR/$tdir/$tfile
16927         test_mkdir -c1 $DIR/$tdir/foo1
16928         test_mkdir -c1 $DIR/$tdir/foo2
16929         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16930         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16931         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16932         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16933         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16934         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16935                 $LFS fid2path $DIR $FID
16936                 error "bad link ea"
16937         fi
16938         # middle
16939         rm $DIR/$tdir/foo2/zachary
16940         # last
16941         rm $DIR/$tdir/foo2/thor
16942         # first
16943         rm $DIR/$tdir/$tfile
16944         # rename
16945         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16946         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16947                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16948         rm $DIR/$tdir/foo2/maggie
16949
16950         # overflow the EA
16951         local longname=$tfile.avg_len_is_thirty_two_
16952         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16953                 error_noexit 'failed to unlink many hardlinks'" EXIT
16954         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16955                 error "failed to hardlink many files"
16956         links=$($LFS fid2path $DIR $FID | wc -l)
16957         echo -n "${links}/1000 links in link EA"
16958         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16959 }
16960 run_test 161a "link ea sanity"
16961
16962 test_161b() {
16963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16964         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16965
16966         local MDTIDX=1
16967         local remote_dir=$DIR/$tdir/remote_dir
16968
16969         mkdir -p $DIR/$tdir
16970         $LFS mkdir -i $MDTIDX $remote_dir ||
16971                 error "create remote directory failed"
16972
16973         cp /etc/hosts $remote_dir/$tfile
16974         mkdir -p $remote_dir/foo1
16975         mkdir -p $remote_dir/foo2
16976         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16977         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16978         ln $remote_dir/$tfile $remote_dir/foo1/luna
16979         ln $remote_dir/$tfile $remote_dir/foo2/thor
16980
16981         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16982                      tr -d ']')
16983         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16984                 $LFS fid2path $DIR $FID
16985                 error "bad link ea"
16986         fi
16987         # middle
16988         rm $remote_dir/foo2/zachary
16989         # last
16990         rm $remote_dir/foo2/thor
16991         # first
16992         rm $remote_dir/$tfile
16993         # rename
16994         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16995         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16996         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16997                 $LFS fid2path $DIR $FID
16998                 error "bad link rename"
16999         fi
17000         rm $remote_dir/foo2/maggie
17001
17002         # overflow the EA
17003         local longname=filename_avg_len_is_thirty_two_
17004         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17005                 error "failed to hardlink many files"
17006         links=$($LFS fid2path $DIR $FID | wc -l)
17007         echo -n "${links}/1000 links in link EA"
17008         [[ ${links} -gt 60 ]] ||
17009                 error "expected at least 60 links in link EA"
17010         unlinkmany $remote_dir/foo2/$longname 1000 ||
17011         error "failed to unlink many hardlinks"
17012 }
17013 run_test 161b "link ea sanity under remote directory"
17014
17015 test_161c() {
17016         remote_mds_nodsh && skip "remote MDS with nodsh"
17017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17018         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17019                 skip "Need MDS version at least 2.1.5"
17020
17021         # define CLF_RENAME_LAST 0x0001
17022         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17023         changelog_register || error "changelog_register failed"
17024
17025         rm -rf $DIR/$tdir
17026         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17027         touch $DIR/$tdir/foo_161c
17028         touch $DIR/$tdir/bar_161c
17029         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17030         changelog_dump | grep RENME | tail -n 5
17031         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17032         changelog_clear 0 || error "changelog_clear failed"
17033         if [ x$flags != "x0x1" ]; then
17034                 error "flag $flags is not 0x1"
17035         fi
17036
17037         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17038         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17039         touch $DIR/$tdir/foo_161c
17040         touch $DIR/$tdir/bar_161c
17041         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17042         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17043         changelog_dump | grep RENME | tail -n 5
17044         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17045         changelog_clear 0 || error "changelog_clear failed"
17046         if [ x$flags != "x0x0" ]; then
17047                 error "flag $flags is not 0x0"
17048         fi
17049         echo "rename overwrite a target having nlink > 1," \
17050                 "changelog record has flags of $flags"
17051
17052         # rename doesn't overwrite a target (changelog flag 0x0)
17053         touch $DIR/$tdir/foo_161c
17054         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17055         changelog_dump | grep RENME | tail -n 5
17056         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17057         changelog_clear 0 || error "changelog_clear failed"
17058         if [ x$flags != "x0x0" ]; then
17059                 error "flag $flags is not 0x0"
17060         fi
17061         echo "rename doesn't overwrite a target," \
17062                 "changelog record has flags of $flags"
17063
17064         # define CLF_UNLINK_LAST 0x0001
17065         # unlink a file having nlink = 1 (changelog flag 0x1)
17066         rm -f $DIR/$tdir/foo2_161c
17067         changelog_dump | grep UNLNK | tail -n 5
17068         flags=$(changelog_dump | grep UNLNK | tail -1 | 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         echo "unlink a file having nlink = 1," \
17074                 "changelog record has flags of $flags"
17075
17076         # unlink a file having nlink > 1 (changelog flag 0x0)
17077         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17078         rm -f $DIR/$tdir/foobar_161c
17079         changelog_dump | grep UNLNK | tail -n 5
17080         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17081         changelog_clear 0 || error "changelog_clear failed"
17082         if [ x$flags != "x0x0" ]; then
17083                 error "flag $flags is not 0x0"
17084         fi
17085         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17086 }
17087 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17088
17089 test_161d() {
17090         remote_mds_nodsh && skip "remote MDS with nodsh"
17091         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17092
17093         local pid
17094         local fid
17095
17096         changelog_register || error "changelog_register failed"
17097
17098         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17099         # interfer with $MOUNT/.lustre/fid/ access
17100         mkdir $DIR/$tdir
17101         [[ $? -eq 0 ]] || error "mkdir failed"
17102
17103         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17104         $LCTL set_param fail_loc=0x8000140c
17105         # 5s pause
17106         $LCTL set_param fail_val=5
17107
17108         # create file
17109         echo foofoo > $DIR/$tdir/$tfile &
17110         pid=$!
17111
17112         # wait for create to be delayed
17113         sleep 2
17114
17115         ps -p $pid
17116         [[ $? -eq 0 ]] || error "create should be blocked"
17117
17118         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17119         stack_trap "rm -f $tempfile"
17120         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17121         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17122         # some delay may occur during ChangeLog publishing and file read just
17123         # above, that could allow file write to happen finally
17124         [[ -s $tempfile ]] && echo "file should be empty"
17125
17126         $LCTL set_param fail_loc=0
17127
17128         wait $pid
17129         [[ $? -eq 0 ]] || error "create failed"
17130 }
17131 run_test 161d "create with concurrent .lustre/fid access"
17132
17133 check_path() {
17134         local expected="$1"
17135         shift
17136         local fid="$2"
17137
17138         local path
17139         path=$($LFS fid2path "$@")
17140         local rc=$?
17141
17142         if [ $rc -ne 0 ]; then
17143                 error "path looked up of '$expected' failed: rc=$rc"
17144         elif [ "$path" != "$expected" ]; then
17145                 error "path looked up '$path' instead of '$expected'"
17146         else
17147                 echo "FID '$fid' resolves to path '$path' as expected"
17148         fi
17149 }
17150
17151 test_162a() { # was test_162
17152         test_mkdir -p -c1 $DIR/$tdir/d2
17153         touch $DIR/$tdir/d2/$tfile
17154         touch $DIR/$tdir/d2/x1
17155         touch $DIR/$tdir/d2/x2
17156         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17157         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17158         # regular file
17159         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17160         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17161
17162         # softlink
17163         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17164         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17165         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17166
17167         # softlink to wrong file
17168         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17169         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17170         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17171
17172         # hardlink
17173         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17174         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17175         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17176         # fid2path dir/fsname should both work
17177         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17178         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17179
17180         # hardlink count: check that there are 2 links
17181         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17182         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17183
17184         # hardlink indexing: remove the first link
17185         rm $DIR/$tdir/d2/p/q/r/hlink
17186         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17187 }
17188 run_test 162a "path lookup sanity"
17189
17190 test_162b() {
17191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17192         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17193
17194         mkdir $DIR/$tdir
17195         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17196                                 error "create striped dir failed"
17197
17198         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17199                                         tail -n 1 | awk '{print $2}')
17200         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17201
17202         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17203         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17204
17205         # regular file
17206         for ((i=0;i<5;i++)); do
17207                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17208                         error "get fid for f$i failed"
17209                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17210
17211                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17212                         error "get fid for d$i failed"
17213                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17214         done
17215
17216         return 0
17217 }
17218 run_test 162b "striped directory path lookup sanity"
17219
17220 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17221 test_162c() {
17222         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17223                 skip "Need MDS version at least 2.7.51"
17224
17225         local lpath=$tdir.local
17226         local rpath=$tdir.remote
17227
17228         test_mkdir $DIR/$lpath
17229         test_mkdir $DIR/$rpath
17230
17231         for ((i = 0; i <= 101; i++)); do
17232                 lpath="$lpath/$i"
17233                 mkdir $DIR/$lpath
17234                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17235                         error "get fid for local directory $DIR/$lpath failed"
17236                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17237
17238                 rpath="$rpath/$i"
17239                 test_mkdir $DIR/$rpath
17240                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17241                         error "get fid for remote directory $DIR/$rpath failed"
17242                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17243         done
17244
17245         return 0
17246 }
17247 run_test 162c "fid2path works with paths 100 or more directories deep"
17248
17249 oalr_event_count() {
17250         local event="${1}"
17251         local trace="${2}"
17252
17253         awk -v name="${FSNAME}-OST0000" \
17254             -v event="${event}" \
17255             '$1 == "TRACE" && $2 == event && $3 == name' \
17256             "${trace}" |
17257         wc -l
17258 }
17259
17260 oalr_expect_event_count() {
17261         local event="${1}"
17262         local trace="${2}"
17263         local expect="${3}"
17264         local count
17265
17266         count=$(oalr_event_count "${event}" "${trace}")
17267         if ((count == expect)); then
17268                 return 0
17269         fi
17270
17271         error_noexit "${event} event count was '${count}', expected ${expect}"
17272         cat "${trace}" >&2
17273         exit 1
17274 }
17275
17276 cleanup_165() {
17277         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17278         stop ost1
17279         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17280 }
17281
17282 setup_165() {
17283         sync # Flush previous IOs so we can count log entries.
17284         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17285         stack_trap cleanup_165 EXIT
17286 }
17287
17288 test_165a() {
17289         local trace="/tmp/${tfile}.trace"
17290         local rc
17291         local count
17292
17293         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17294                 skip "OFD access log unsupported"
17295
17296         setup_165
17297         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17298         sleep 5
17299
17300         do_facet ost1 ofd_access_log_reader --list
17301         stop ost1
17302
17303         do_facet ost1 killall -TERM ofd_access_log_reader
17304         wait
17305         rc=$?
17306
17307         if ((rc != 0)); then
17308                 error "ofd_access_log_reader exited with rc = '${rc}'"
17309         fi
17310
17311         # Parse trace file for discovery events:
17312         oalr_expect_event_count alr_log_add "${trace}" 1
17313         oalr_expect_event_count alr_log_eof "${trace}" 1
17314         oalr_expect_event_count alr_log_free "${trace}" 1
17315 }
17316 run_test 165a "ofd access log discovery"
17317
17318 test_165b() {
17319         local trace="/tmp/${tfile}.trace"
17320         local file="${DIR}/${tfile}"
17321         local pfid1
17322         local pfid2
17323         local -a entry
17324         local rc
17325         local count
17326         local size
17327         local flags
17328
17329         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17330                 skip "OFD access log unsupported"
17331
17332         setup_165
17333         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17334         sleep 5
17335
17336         do_facet ost1 ofd_access_log_reader --list
17337
17338         lfs setstripe -c 1 -i 0 "${file}"
17339         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17340                 error "cannot create '${file}'"
17341
17342         sleep 5
17343         do_facet ost1 killall -TERM ofd_access_log_reader
17344         wait
17345         rc=$?
17346
17347         if ((rc != 0)); then
17348                 error "ofd_access_log_reader exited with rc = '${rc}'"
17349         fi
17350
17351         oalr_expect_event_count alr_log_entry "${trace}" 1
17352
17353         pfid1=$($LFS path2fid "${file}")
17354
17355         # 1     2             3   4    5     6   7    8    9     10
17356         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17357         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17358
17359         echo "entry = '${entry[*]}'" >&2
17360
17361         pfid2=${entry[4]}
17362         if [[ "${pfid1}" != "${pfid2}" ]]; then
17363                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17364         fi
17365
17366         size=${entry[8]}
17367         if ((size != 1048576)); then
17368                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17369         fi
17370
17371         flags=${entry[10]}
17372         if [[ "${flags}" != "w" ]]; then
17373                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17374         fi
17375
17376         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17377         sleep 5
17378
17379         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17380                 error "cannot read '${file}'"
17381         sleep 5
17382
17383         do_facet ost1 killall -TERM ofd_access_log_reader
17384         wait
17385         rc=$?
17386
17387         if ((rc != 0)); then
17388                 error "ofd_access_log_reader exited with rc = '${rc}'"
17389         fi
17390
17391         oalr_expect_event_count alr_log_entry "${trace}" 1
17392
17393         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17394         echo "entry = '${entry[*]}'" >&2
17395
17396         pfid2=${entry[4]}
17397         if [[ "${pfid1}" != "${pfid2}" ]]; then
17398                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17399         fi
17400
17401         size=${entry[8]}
17402         if ((size != 524288)); then
17403                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17404         fi
17405
17406         flags=${entry[10]}
17407         if [[ "${flags}" != "r" ]]; then
17408                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17409         fi
17410 }
17411 run_test 165b "ofd access log entries are produced and consumed"
17412
17413 test_165c() {
17414         local trace="/tmp/${tfile}.trace"
17415         local file="${DIR}/${tdir}/${tfile}"
17416
17417         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17418                 skip "OFD access log unsupported"
17419
17420         test_mkdir "${DIR}/${tdir}"
17421
17422         setup_165
17423         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17424         sleep 5
17425
17426         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17427
17428         # 4096 / 64 = 64. Create twice as many entries.
17429         for ((i = 0; i < 128; i++)); do
17430                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17431                         error "cannot create file"
17432         done
17433
17434         sync
17435
17436         do_facet ost1 killall -TERM ofd_access_log_reader
17437         wait
17438         rc=$?
17439         if ((rc != 0)); then
17440                 error "ofd_access_log_reader exited with rc = '${rc}'"
17441         fi
17442
17443         unlinkmany  "${file}-%d" 128
17444 }
17445 run_test 165c "full ofd access logs do not block IOs"
17446
17447 oal_get_read_count() {
17448         local stats="$1"
17449
17450         # STATS lustre-OST0001 alr_read_count 1
17451
17452         do_facet ost1 cat "${stats}" |
17453         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17454              END { print count; }'
17455 }
17456
17457 oal_expect_read_count() {
17458         local stats="$1"
17459         local count
17460         local expect="$2"
17461
17462         # Ask ofd_access_log_reader to write stats.
17463         do_facet ost1 killall -USR1 ofd_access_log_reader
17464
17465         # Allow some time for things to happen.
17466         sleep 1
17467
17468         count=$(oal_get_read_count "${stats}")
17469         if ((count == expect)); then
17470                 return 0
17471         fi
17472
17473         error_noexit "bad read count, got ${count}, expected ${expect}"
17474         do_facet ost1 cat "${stats}" >&2
17475         exit 1
17476 }
17477
17478 test_165d() {
17479         local stats="/tmp/${tfile}.stats"
17480         local file="${DIR}/${tdir}/${tfile}"
17481         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17482
17483         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17484                 skip "OFD access log unsupported"
17485
17486         test_mkdir "${DIR}/${tdir}"
17487
17488         setup_165
17489         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17490         sleep 5
17491
17492         lfs setstripe -c 1 -i 0 "${file}"
17493
17494         do_facet ost1 lctl set_param "${param}=rw"
17495         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17496                 error "cannot create '${file}'"
17497         oal_expect_read_count "${stats}" 1
17498
17499         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17500                 error "cannot read '${file}'"
17501         oal_expect_read_count "${stats}" 2
17502
17503         do_facet ost1 lctl set_param "${param}=r"
17504         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17505                 error "cannot create '${file}'"
17506         oal_expect_read_count "${stats}" 2
17507
17508         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17509                 error "cannot read '${file}'"
17510         oal_expect_read_count "${stats}" 3
17511
17512         do_facet ost1 lctl set_param "${param}=w"
17513         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17514                 error "cannot create '${file}'"
17515         oal_expect_read_count "${stats}" 4
17516
17517         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17518                 error "cannot read '${file}'"
17519         oal_expect_read_count "${stats}" 4
17520
17521         do_facet ost1 lctl set_param "${param}=0"
17522         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17523                 error "cannot create '${file}'"
17524         oal_expect_read_count "${stats}" 4
17525
17526         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17527                 error "cannot read '${file}'"
17528         oal_expect_read_count "${stats}" 4
17529
17530         do_facet ost1 killall -TERM ofd_access_log_reader
17531         wait
17532         rc=$?
17533         if ((rc != 0)); then
17534                 error "ofd_access_log_reader exited with rc = '${rc}'"
17535         fi
17536 }
17537 run_test 165d "ofd_access_log mask works"
17538
17539 test_165e() {
17540         local stats="/tmp/${tfile}.stats"
17541         local file0="${DIR}/${tdir}-0/${tfile}"
17542         local file1="${DIR}/${tdir}-1/${tfile}"
17543
17544         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17545                 skip "OFD access log unsupported"
17546
17547         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17548
17549         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17550         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17551
17552         lfs setstripe -c 1 -i 0 "${file0}"
17553         lfs setstripe -c 1 -i 0 "${file1}"
17554
17555         setup_165
17556         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17557         sleep 5
17558
17559         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17560                 error "cannot create '${file0}'"
17561         sync
17562         oal_expect_read_count "${stats}" 0
17563
17564         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17565                 error "cannot create '${file1}'"
17566         sync
17567         oal_expect_read_count "${stats}" 1
17568
17569         do_facet ost1 killall -TERM ofd_access_log_reader
17570         wait
17571         rc=$?
17572         if ((rc != 0)); then
17573                 error "ofd_access_log_reader exited with rc = '${rc}'"
17574         fi
17575 }
17576 run_test 165e "ofd_access_log MDT index filter works"
17577
17578 test_165f() {
17579         local trace="/tmp/${tfile}.trace"
17580         local rc
17581         local count
17582
17583         setup_165
17584         do_facet ost1 timeout 60 ofd_access_log_reader \
17585                 --exit-on-close --debug=- --trace=- > "${trace}" &
17586         sleep 5
17587         stop ost1
17588
17589         wait
17590         rc=$?
17591
17592         if ((rc != 0)); then
17593                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17594                 cat "${trace}"
17595                 exit 1
17596         fi
17597 }
17598 run_test 165f "ofd_access_log_reader --exit-on-close works"
17599
17600 test_169() {
17601         # do directio so as not to populate the page cache
17602         log "creating a 10 Mb file"
17603         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17604                 error "multiop failed while creating a file"
17605         log "starting reads"
17606         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17607         log "truncating the file"
17608         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17609                 error "multiop failed while truncating the file"
17610         log "killing dd"
17611         kill %+ || true # reads might have finished
17612         echo "wait until dd is finished"
17613         wait
17614         log "removing the temporary file"
17615         rm -rf $DIR/$tfile || error "tmp file removal failed"
17616 }
17617 run_test 169 "parallel read and truncate should not deadlock"
17618
17619 test_170() {
17620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17621
17622         $LCTL clear     # bug 18514
17623         $LCTL debug_daemon start $TMP/${tfile}_log_good
17624         touch $DIR/$tfile
17625         $LCTL debug_daemon stop
17626         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17627                 error "sed failed to read log_good"
17628
17629         $LCTL debug_daemon start $TMP/${tfile}_log_good
17630         rm -rf $DIR/$tfile
17631         $LCTL debug_daemon stop
17632
17633         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17634                error "lctl df log_bad failed"
17635
17636         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17637         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17638
17639         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17640         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17641
17642         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17643                 error "bad_line good_line1 good_line2 are empty"
17644
17645         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17646         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17647         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17648
17649         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17650         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17651         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17652
17653         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17654                 error "bad_line_new good_line_new are empty"
17655
17656         local expected_good=$((good_line1 + good_line2*2))
17657
17658         rm -f $TMP/${tfile}*
17659         # LU-231, short malformed line may not be counted into bad lines
17660         if [ $bad_line -ne $bad_line_new ] &&
17661                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17662                 error "expected $bad_line bad lines, but got $bad_line_new"
17663                 return 1
17664         fi
17665
17666         if [ $expected_good -ne $good_line_new ]; then
17667                 error "expected $expected_good good lines, but got $good_line_new"
17668                 return 2
17669         fi
17670         true
17671 }
17672 run_test 170 "test lctl df to handle corrupted log ====================="
17673
17674 test_171() { # bug20592
17675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17676
17677         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17678         $LCTL set_param fail_loc=0x50e
17679         $LCTL set_param fail_val=3000
17680         multiop_bg_pause $DIR/$tfile O_s || true
17681         local MULTIPID=$!
17682         kill -USR1 $MULTIPID
17683         # cause log dump
17684         sleep 3
17685         wait $MULTIPID
17686         if dmesg | grep "recursive fault"; then
17687                 error "caught a recursive fault"
17688         fi
17689         $LCTL set_param fail_loc=0
17690         true
17691 }
17692 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17693
17694 # it would be good to share it with obdfilter-survey/iokit-libecho code
17695 setup_obdecho_osc () {
17696         local rc=0
17697         local ost_nid=$1
17698         local obdfilter_name=$2
17699         echo "Creating new osc for $obdfilter_name on $ost_nid"
17700         # make sure we can find loopback nid
17701         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17702
17703         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17704                            ${obdfilter_name}_osc_UUID || rc=2; }
17705         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17706                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17707         return $rc
17708 }
17709
17710 cleanup_obdecho_osc () {
17711         local obdfilter_name=$1
17712         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17713         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17714         return 0
17715 }
17716
17717 obdecho_test() {
17718         local OBD=$1
17719         local node=$2
17720         local pages=${3:-64}
17721         local rc=0
17722         local id
17723
17724         local count=10
17725         local obd_size=$(get_obd_size $node $OBD)
17726         local page_size=$(get_page_size $node)
17727         if [[ -n "$obd_size" ]]; then
17728                 local new_count=$((obd_size / (pages * page_size / 1024)))
17729                 [[ $new_count -ge $count ]] || count=$new_count
17730         fi
17731
17732         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17733         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17734                            rc=2; }
17735         if [ $rc -eq 0 ]; then
17736             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17737             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17738         fi
17739         echo "New object id is $id"
17740         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17741                            rc=4; }
17742         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17743                            "test_brw $count w v $pages $id" || rc=4; }
17744         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17745                            rc=4; }
17746         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17747                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17748         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17749                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17750         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17751         return $rc
17752 }
17753
17754 test_180a() {
17755         skip "obdecho on osc is no longer supported"
17756 }
17757 run_test 180a "test obdecho on osc"
17758
17759 test_180b() {
17760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17761         remote_ost_nodsh && skip "remote OST with nodsh"
17762
17763         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17764                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17765                 error "failed to load module obdecho"
17766
17767         local target=$(do_facet ost1 $LCTL dl |
17768                        awk '/obdfilter/ { print $4; exit; }')
17769
17770         if [ -n "$target" ]; then
17771                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17772         else
17773                 do_facet ost1 $LCTL dl
17774                 error "there is no obdfilter target on ost1"
17775         fi
17776 }
17777 run_test 180b "test obdecho directly on obdfilter"
17778
17779 test_180c() { # LU-2598
17780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17781         remote_ost_nodsh && skip "remote OST with nodsh"
17782         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17783                 skip "Need MDS version at least 2.4.0"
17784
17785         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17786                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17787                 error "failed to load module obdecho"
17788
17789         local target=$(do_facet ost1 $LCTL dl |
17790                        awk '/obdfilter/ { print $4; exit; }')
17791
17792         if [ -n "$target" ]; then
17793                 local pages=16384 # 64MB bulk I/O RPC size
17794
17795                 obdecho_test "$target" ost1 "$pages" ||
17796                         error "obdecho_test with pages=$pages failed with $?"
17797         else
17798                 do_facet ost1 $LCTL dl
17799                 error "there is no obdfilter target on ost1"
17800         fi
17801 }
17802 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17803
17804 test_181() { # bug 22177
17805         test_mkdir $DIR/$tdir
17806         # create enough files to index the directory
17807         createmany -o $DIR/$tdir/foobar 4000
17808         # print attributes for debug purpose
17809         lsattr -d .
17810         # open dir
17811         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17812         MULTIPID=$!
17813         # remove the files & current working dir
17814         unlinkmany $DIR/$tdir/foobar 4000
17815         rmdir $DIR/$tdir
17816         kill -USR1 $MULTIPID
17817         wait $MULTIPID
17818         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17819         return 0
17820 }
17821 run_test 181 "Test open-unlinked dir ========================"
17822
17823 test_182a() {
17824         local fcount=1000
17825         local tcount=10
17826
17827         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17828
17829         $LCTL set_param mdc.*.rpc_stats=clear
17830
17831         for (( i = 0; i < $tcount; i++ )) ; do
17832                 mkdir $DIR/$tdir/$i
17833         done
17834
17835         for (( i = 0; i < $tcount; i++ )) ; do
17836                 createmany -o $DIR/$tdir/$i/f- $fcount &
17837         done
17838         wait
17839
17840         for (( i = 0; i < $tcount; i++ )) ; do
17841                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17842         done
17843         wait
17844
17845         $LCTL get_param mdc.*.rpc_stats
17846
17847         rm -rf $DIR/$tdir
17848 }
17849 run_test 182a "Test parallel modify metadata operations from mdc"
17850
17851 test_182b() {
17852         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17853         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
17854         local dcount=1000
17855         local tcount=10
17856         local stime
17857         local etime
17858         local delta
17859
17860         do_facet mds1 $LCTL list_param \
17861                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
17862                 skip "MDS lacks parallel RPC handling"
17863
17864         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17865
17866         rpc_count=$(do_facet mds1 $LCTL get_param -n \
17867                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
17868
17869         stime=$(date +%s)
17870         createmany -i 0 -d $DIR/$tdir/t- $tcount
17871
17872         for (( i = 0; i < $tcount; i++ )) ; do
17873                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
17874         done
17875         wait
17876         etime=$(date +%s)
17877         delta=$((etime - stime))
17878         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
17879
17880         stime=$(date +%s)
17881         for (( i = 0; i < $tcount; i++ )) ; do
17882                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
17883         done
17884         wait
17885         etime=$(date +%s)
17886         delta=$((etime - stime))
17887         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
17888
17889         rm -rf $DIR/$tdir
17890
17891         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17892
17893         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
17894
17895         stime=$(date +%s)
17896         createmany -i 0 -d $DIR/$tdir/t- $tcount
17897
17898         for (( i = 0; i < $tcount; i++ )) ; do
17899                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
17900         done
17901         wait
17902         etime=$(date +%s)
17903         delta=$((etime - stime))
17904         echo "Time for file creation $delta sec for 1 RPC sent at a time"
17905
17906         stime=$(date +%s)
17907         for (( i = 0; i < $tcount; i++ )) ; do
17908                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
17909         done
17910         wait
17911         etime=$(date +%s)
17912         delta=$((etime - stime))
17913         echo "Time for file removal $delta sec for 1 RPC sent at a time"
17914
17915         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
17916 }
17917 run_test 182b "Test parallel modify metadata operations from osp"
17918
17919 test_183() { # LU-2275
17920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17921         remote_mds_nodsh && skip "remote MDS with nodsh"
17922         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17923                 skip "Need MDS version at least 2.3.56"
17924
17925         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17926         echo aaa > $DIR/$tdir/$tfile
17927
17928 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17929         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17930
17931         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17932         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17933
17934         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17935
17936         # Flush negative dentry cache
17937         touch $DIR/$tdir/$tfile
17938
17939         # We are not checking for any leaked references here, they'll
17940         # become evident next time we do cleanup with module unload.
17941         rm -rf $DIR/$tdir
17942 }
17943 run_test 183 "No crash or request leak in case of strange dispositions ========"
17944
17945 # test suite 184 is for LU-2016, LU-2017
17946 test_184a() {
17947         check_swap_layouts_support
17948
17949         dir0=$DIR/$tdir/$testnum
17950         test_mkdir -p -c1 $dir0
17951         ref1=/etc/passwd
17952         ref2=/etc/group
17953         file1=$dir0/f1
17954         file2=$dir0/f2
17955         $LFS setstripe -c1 $file1
17956         cp $ref1 $file1
17957         $LFS setstripe -c2 $file2
17958         cp $ref2 $file2
17959         gen1=$($LFS getstripe -g $file1)
17960         gen2=$($LFS getstripe -g $file2)
17961
17962         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17963         gen=$($LFS getstripe -g $file1)
17964         [[ $gen1 != $gen ]] ||
17965                 error "Layout generation on $file1 does not change"
17966         gen=$($LFS getstripe -g $file2)
17967         [[ $gen2 != $gen ]] ||
17968                 error "Layout generation on $file2 does not change"
17969
17970         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17971         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17972
17973         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17974 }
17975 run_test 184a "Basic layout swap"
17976
17977 test_184b() {
17978         check_swap_layouts_support
17979
17980         dir0=$DIR/$tdir/$testnum
17981         mkdir -p $dir0 || error "creating dir $dir0"
17982         file1=$dir0/f1
17983         file2=$dir0/f2
17984         file3=$dir0/f3
17985         dir1=$dir0/d1
17986         dir2=$dir0/d2
17987         mkdir $dir1 $dir2
17988         $LFS setstripe -c1 $file1
17989         $LFS setstripe -c2 $file2
17990         $LFS setstripe -c1 $file3
17991         chown $RUNAS_ID $file3
17992         gen1=$($LFS getstripe -g $file1)
17993         gen2=$($LFS getstripe -g $file2)
17994
17995         $LFS swap_layouts $dir1 $dir2 &&
17996                 error "swap of directories layouts should fail"
17997         $LFS swap_layouts $dir1 $file1 &&
17998                 error "swap of directory and file layouts should fail"
17999         $RUNAS $LFS swap_layouts $file1 $file2 &&
18000                 error "swap of file we cannot write should fail"
18001         $LFS swap_layouts $file1 $file3 &&
18002                 error "swap of file with different owner should fail"
18003         /bin/true # to clear error code
18004 }
18005 run_test 184b "Forbidden layout swap (will generate errors)"
18006
18007 test_184c() {
18008         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18009         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18010         check_swap_layouts_support
18011         check_swap_layout_no_dom $DIR
18012
18013         local dir0=$DIR/$tdir/$testnum
18014         mkdir -p $dir0 || error "creating dir $dir0"
18015
18016         local ref1=$dir0/ref1
18017         local ref2=$dir0/ref2
18018         local file1=$dir0/file1
18019         local file2=$dir0/file2
18020         # create a file large enough for the concurrent test
18021         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18022         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18023         echo "ref file size: ref1($(stat -c %s $ref1))," \
18024              "ref2($(stat -c %s $ref2))"
18025
18026         cp $ref2 $file2
18027         dd if=$ref1 of=$file1 bs=16k &
18028         local DD_PID=$!
18029
18030         # Make sure dd starts to copy file, but wait at most 5 seconds
18031         local loops=0
18032         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18033
18034         $LFS swap_layouts $file1 $file2
18035         local rc=$?
18036         wait $DD_PID
18037         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18038         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18039
18040         # how many bytes copied before swapping layout
18041         local copied=$(stat -c %s $file2)
18042         local remaining=$(stat -c %s $ref1)
18043         remaining=$((remaining - copied))
18044         echo "Copied $copied bytes before swapping layout..."
18045
18046         cmp -n $copied $file1 $ref2 | grep differ &&
18047                 error "Content mismatch [0, $copied) of ref2 and file1"
18048         cmp -n $copied $file2 $ref1 ||
18049                 error "Content mismatch [0, $copied) of ref1 and file2"
18050         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18051                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18052
18053         # clean up
18054         rm -f $ref1 $ref2 $file1 $file2
18055 }
18056 run_test 184c "Concurrent write and layout swap"
18057
18058 test_184d() {
18059         check_swap_layouts_support
18060         check_swap_layout_no_dom $DIR
18061         [ -z "$(which getfattr 2>/dev/null)" ] &&
18062                 skip_env "no getfattr command"
18063
18064         local file1=$DIR/$tdir/$tfile-1
18065         local file2=$DIR/$tdir/$tfile-2
18066         local file3=$DIR/$tdir/$tfile-3
18067         local lovea1
18068         local lovea2
18069
18070         mkdir -p $DIR/$tdir
18071         touch $file1 || error "create $file1 failed"
18072         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18073                 error "create $file2 failed"
18074         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18075                 error "create $file3 failed"
18076         lovea1=$(get_layout_param $file1)
18077
18078         $LFS swap_layouts $file2 $file3 ||
18079                 error "swap $file2 $file3 layouts failed"
18080         $LFS swap_layouts $file1 $file2 ||
18081                 error "swap $file1 $file2 layouts failed"
18082
18083         lovea2=$(get_layout_param $file2)
18084         echo "$lovea1"
18085         echo "$lovea2"
18086         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18087
18088         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18089         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18090 }
18091 run_test 184d "allow stripeless layouts swap"
18092
18093 test_184e() {
18094         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18095                 skip "Need MDS version at least 2.6.94"
18096         check_swap_layouts_support
18097         check_swap_layout_no_dom $DIR
18098         [ -z "$(which getfattr 2>/dev/null)" ] &&
18099                 skip_env "no getfattr command"
18100
18101         local file1=$DIR/$tdir/$tfile-1
18102         local file2=$DIR/$tdir/$tfile-2
18103         local file3=$DIR/$tdir/$tfile-3
18104         local lovea
18105
18106         mkdir -p $DIR/$tdir
18107         touch $file1 || error "create $file1 failed"
18108         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18109                 error "create $file2 failed"
18110         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18111                 error "create $file3 failed"
18112
18113         $LFS swap_layouts $file1 $file2 ||
18114                 error "swap $file1 $file2 layouts failed"
18115
18116         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18117         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18118
18119         echo 123 > $file1 || error "Should be able to write into $file1"
18120
18121         $LFS swap_layouts $file1 $file3 ||
18122                 error "swap $file1 $file3 layouts failed"
18123
18124         echo 123 > $file1 || error "Should be able to write into $file1"
18125
18126         rm -rf $file1 $file2 $file3
18127 }
18128 run_test 184e "Recreate layout after stripeless layout swaps"
18129
18130 test_184f() {
18131         # Create a file with name longer than sizeof(struct stat) ==
18132         # 144 to see if we can get chars from the file name to appear
18133         # in the returned striping. Note that 'f' == 0x66.
18134         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18135
18136         mkdir -p $DIR/$tdir
18137         mcreate $DIR/$tdir/$file
18138         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18139                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18140         fi
18141 }
18142 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18143
18144 test_185() { # LU-2441
18145         # LU-3553 - no volatile file support in old servers
18146         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18147                 skip "Need MDS version at least 2.3.60"
18148
18149         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18150         touch $DIR/$tdir/spoo
18151         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18152         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18153                 error "cannot create/write a volatile file"
18154         [ "$FILESET" == "" ] &&
18155         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18156                 error "FID is still valid after close"
18157
18158         multiop_bg_pause $DIR/$tdir vVw4096_c
18159         local multi_pid=$!
18160
18161         local OLD_IFS=$IFS
18162         IFS=":"
18163         local fidv=($fid)
18164         IFS=$OLD_IFS
18165         # assume that the next FID for this client is sequential, since stdout
18166         # is unfortunately eaten by multiop_bg_pause
18167         local n=$((${fidv[1]} + 1))
18168         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18169         if [ "$FILESET" == "" ]; then
18170                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18171                         error "FID is missing before close"
18172         fi
18173         kill -USR1 $multi_pid
18174         # 1 second delay, so if mtime change we will see it
18175         sleep 1
18176         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18177         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18178 }
18179 run_test 185 "Volatile file support"
18180
18181 function create_check_volatile() {
18182         local idx=$1
18183         local tgt
18184
18185         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18186         local PID=$!
18187         sleep 1
18188         local FID=$(cat /tmp/${tfile}.fid)
18189         [ "$FID" == "" ] && error "can't get FID for volatile"
18190         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18191         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18192         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18193         kill -USR1 $PID
18194         wait
18195         sleep 1
18196         cancel_lru_locks mdc # flush opencache
18197         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18198         return 0
18199 }
18200
18201 test_185a(){
18202         # LU-12516 - volatile creation via .lustre
18203         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18204                 skip "Need MDS version at least 2.3.55"
18205
18206         create_check_volatile 0
18207         [ $MDSCOUNT -lt 2 ] && return 0
18208
18209         # DNE case
18210         create_check_volatile 1
18211
18212         return 0
18213 }
18214 run_test 185a "Volatile file creation in .lustre/fid/"
18215
18216 test_187a() {
18217         remote_mds_nodsh && skip "remote MDS with nodsh"
18218         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18219                 skip "Need MDS version at least 2.3.0"
18220
18221         local dir0=$DIR/$tdir/$testnum
18222         mkdir -p $dir0 || error "creating dir $dir0"
18223
18224         local file=$dir0/file1
18225         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18226         local dv1=$($LFS data_version $file)
18227         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18228         local dv2=$($LFS data_version $file)
18229         [[ $dv1 != $dv2 ]] ||
18230                 error "data version did not change on write $dv1 == $dv2"
18231
18232         # clean up
18233         rm -f $file1
18234 }
18235 run_test 187a "Test data version change"
18236
18237 test_187b() {
18238         remote_mds_nodsh && skip "remote MDS with nodsh"
18239         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18240                 skip "Need MDS version at least 2.3.0"
18241
18242         local dir0=$DIR/$tdir/$testnum
18243         mkdir -p $dir0 || error "creating dir $dir0"
18244
18245         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18246         [[ ${DV[0]} != ${DV[1]} ]] ||
18247                 error "data version did not change on write"\
18248                       " ${DV[0]} == ${DV[1]}"
18249
18250         # clean up
18251         rm -f $file1
18252 }
18253 run_test 187b "Test data version change on volatile file"
18254
18255 test_200() {
18256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18257         remote_mgs_nodsh && skip "remote MGS with nodsh"
18258         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18259
18260         local POOL=${POOL:-cea1}
18261         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18262         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18263         # Pool OST targets
18264         local first_ost=0
18265         local last_ost=$(($OSTCOUNT - 1))
18266         local ost_step=2
18267         local ost_list=$(seq $first_ost $ost_step $last_ost)
18268         local ost_range="$first_ost $last_ost $ost_step"
18269         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18270         local file_dir=$POOL_ROOT/file_tst
18271         local subdir=$test_path/subdir
18272         local rc=0
18273
18274         while : ; do
18275                 # former test_200a test_200b
18276                 pool_add $POOL                          || { rc=$? ; break; }
18277                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18278                 # former test_200c test_200d
18279                 mkdir -p $test_path
18280                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18281                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18282                 mkdir -p $subdir
18283                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18284                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18285                                                         || { rc=$? ; break; }
18286                 # former test_200e test_200f
18287                 local files=$((OSTCOUNT*3))
18288                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18289                                                         || { rc=$? ; break; }
18290                 pool_create_files $POOL $file_dir $files "$ost_list" \
18291                                                         || { rc=$? ; break; }
18292                 # former test_200g test_200h
18293                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18294                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18295
18296                 # former test_201a test_201b test_201c
18297                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18298
18299                 local f=$test_path/$tfile
18300                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18301                 pool_remove $POOL $f                    || { rc=$? ; break; }
18302                 break
18303         done
18304
18305         destroy_test_pools
18306
18307         return $rc
18308 }
18309 run_test 200 "OST pools"
18310
18311 # usage: default_attr <count | size | offset>
18312 default_attr() {
18313         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18314 }
18315
18316 # usage: check_default_stripe_attr
18317 check_default_stripe_attr() {
18318         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18319         case $1 in
18320         --stripe-count|-c)
18321                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18322         --stripe-size|-S)
18323                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18324         --stripe-index|-i)
18325                 EXPECTED=-1;;
18326         *)
18327                 error "unknown getstripe attr '$1'"
18328         esac
18329
18330         [ $ACTUAL == $EXPECTED ] ||
18331                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18332 }
18333
18334 test_204a() {
18335         test_mkdir $DIR/$tdir
18336         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18337
18338         check_default_stripe_attr --stripe-count
18339         check_default_stripe_attr --stripe-size
18340         check_default_stripe_attr --stripe-index
18341 }
18342 run_test 204a "Print default stripe attributes"
18343
18344 test_204b() {
18345         test_mkdir $DIR/$tdir
18346         $LFS setstripe --stripe-count 1 $DIR/$tdir
18347
18348         check_default_stripe_attr --stripe-size
18349         check_default_stripe_attr --stripe-index
18350 }
18351 run_test 204b "Print default stripe size and offset"
18352
18353 test_204c() {
18354         test_mkdir $DIR/$tdir
18355         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18356
18357         check_default_stripe_attr --stripe-count
18358         check_default_stripe_attr --stripe-index
18359 }
18360 run_test 204c "Print default stripe count and offset"
18361
18362 test_204d() {
18363         test_mkdir $DIR/$tdir
18364         $LFS setstripe --stripe-index 0 $DIR/$tdir
18365
18366         check_default_stripe_attr --stripe-count
18367         check_default_stripe_attr --stripe-size
18368 }
18369 run_test 204d "Print default stripe count and size"
18370
18371 test_204e() {
18372         test_mkdir $DIR/$tdir
18373         $LFS setstripe -d $DIR/$tdir
18374
18375         check_default_stripe_attr --stripe-count --raw
18376         check_default_stripe_attr --stripe-size --raw
18377         check_default_stripe_attr --stripe-index --raw
18378 }
18379 run_test 204e "Print raw stripe attributes"
18380
18381 test_204f() {
18382         test_mkdir $DIR/$tdir
18383         $LFS setstripe --stripe-count 1 $DIR/$tdir
18384
18385         check_default_stripe_attr --stripe-size --raw
18386         check_default_stripe_attr --stripe-index --raw
18387 }
18388 run_test 204f "Print raw stripe size and offset"
18389
18390 test_204g() {
18391         test_mkdir $DIR/$tdir
18392         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18393
18394         check_default_stripe_attr --stripe-count --raw
18395         check_default_stripe_attr --stripe-index --raw
18396 }
18397 run_test 204g "Print raw stripe count and offset"
18398
18399 test_204h() {
18400         test_mkdir $DIR/$tdir
18401         $LFS setstripe --stripe-index 0 $DIR/$tdir
18402
18403         check_default_stripe_attr --stripe-count --raw
18404         check_default_stripe_attr --stripe-size --raw
18405 }
18406 run_test 204h "Print raw stripe count and size"
18407
18408 # Figure out which job scheduler is being used, if any,
18409 # or use a fake one
18410 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18411         JOBENV=SLURM_JOB_ID
18412 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18413         JOBENV=LSB_JOBID
18414 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18415         JOBENV=PBS_JOBID
18416 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18417         JOBENV=LOADL_STEP_ID
18418 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18419         JOBENV=JOB_ID
18420 else
18421         $LCTL list_param jobid_name > /dev/null 2>&1
18422         if [ $? -eq 0 ]; then
18423                 JOBENV=nodelocal
18424         else
18425                 JOBENV=FAKE_JOBID
18426         fi
18427 fi
18428 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18429
18430 verify_jobstats() {
18431         local cmd=($1)
18432         shift
18433         local facets="$@"
18434
18435 # we don't really need to clear the stats for this test to work, since each
18436 # command has a unique jobid, but it makes debugging easier if needed.
18437 #       for facet in $facets; do
18438 #               local dev=$(convert_facet2label $facet)
18439 #               # clear old jobstats
18440 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18441 #       done
18442
18443         # use a new JobID for each test, or we might see an old one
18444         [ "$JOBENV" = "FAKE_JOBID" ] &&
18445                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18446
18447         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18448
18449         [ "$JOBENV" = "nodelocal" ] && {
18450                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18451                 $LCTL set_param jobid_name=$FAKE_JOBID
18452                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18453         }
18454
18455         log "Test: ${cmd[*]}"
18456         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18457
18458         if [ $JOBENV = "FAKE_JOBID" ]; then
18459                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18460         else
18461                 ${cmd[*]}
18462         fi
18463
18464         # all files are created on OST0000
18465         for facet in $facets; do
18466                 local stats="*.$(convert_facet2label $facet).job_stats"
18467
18468                 # strip out libtool wrappers for in-tree executables
18469                 if (( $(do_facet $facet lctl get_param $stats |
18470                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18471                         do_facet $facet lctl get_param $stats
18472                         error "No jobstats for $JOBVAL found on $facet::$stats"
18473                 fi
18474         done
18475 }
18476
18477 jobstats_set() {
18478         local new_jobenv=$1
18479
18480         set_persistent_param_and_check client "jobid_var" \
18481                 "$FSNAME.sys.jobid_var" $new_jobenv
18482 }
18483
18484 test_205a() { # Job stats
18485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18486         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18487                 skip "Need MDS version with at least 2.7.1"
18488         remote_mgs_nodsh && skip "remote MGS with nodsh"
18489         remote_mds_nodsh && skip "remote MDS with nodsh"
18490         remote_ost_nodsh && skip "remote OST with nodsh"
18491         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18492                 skip "Server doesn't support jobstats"
18493         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18494
18495         local old_jobenv=$($LCTL get_param -n jobid_var)
18496         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18497
18498         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18499                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18500         else
18501                 stack_trap "do_facet mgs $PERM_CMD \
18502                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18503         fi
18504         changelog_register
18505
18506         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18507                                 mdt.*.job_cleanup_interval | head -n 1)
18508         local new_interval=5
18509         do_facet $SINGLEMDS \
18510                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18511         stack_trap "do_facet $SINGLEMDS \
18512                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18513         local start=$SECONDS
18514
18515         local cmd
18516         # mkdir
18517         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18518         verify_jobstats "$cmd" "$SINGLEMDS"
18519         # rmdir
18520         cmd="rmdir $DIR/$tdir"
18521         verify_jobstats "$cmd" "$SINGLEMDS"
18522         # mkdir on secondary MDT
18523         if [ $MDSCOUNT -gt 1 ]; then
18524                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18525                 verify_jobstats "$cmd" "mds2"
18526         fi
18527         # mknod
18528         cmd="mknod $DIR/$tfile c 1 3"
18529         verify_jobstats "$cmd" "$SINGLEMDS"
18530         # unlink
18531         cmd="rm -f $DIR/$tfile"
18532         verify_jobstats "$cmd" "$SINGLEMDS"
18533         # create all files on OST0000 so verify_jobstats can find OST stats
18534         # open & close
18535         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18536         verify_jobstats "$cmd" "$SINGLEMDS"
18537         # setattr
18538         cmd="touch $DIR/$tfile"
18539         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18540         # write
18541         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18542         verify_jobstats "$cmd" "ost1"
18543         # read
18544         cancel_lru_locks osc
18545         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18546         verify_jobstats "$cmd" "ost1"
18547         # truncate
18548         cmd="$TRUNCATE $DIR/$tfile 0"
18549         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18550         # rename
18551         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18552         verify_jobstats "$cmd" "$SINGLEMDS"
18553         # jobstats expiry - sleep until old stats should be expired
18554         local left=$((new_interval + 5 - (SECONDS - start)))
18555         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18556                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18557                         "0" $left
18558         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18559         verify_jobstats "$cmd" "$SINGLEMDS"
18560         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18561             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18562
18563         # Ensure that jobid are present in changelog (if supported by MDS)
18564         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18565                 changelog_dump | tail -10
18566                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18567                 [ $jobids -eq 9 ] ||
18568                         error "Wrong changelog jobid count $jobids != 9"
18569
18570                 # LU-5862
18571                 JOBENV="disable"
18572                 jobstats_set $JOBENV
18573                 touch $DIR/$tfile
18574                 changelog_dump | grep $tfile
18575                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18576                 [ $jobids -eq 0 ] ||
18577                         error "Unexpected jobids when jobid_var=$JOBENV"
18578         fi
18579
18580         # test '%j' access to environment variable - if supported
18581         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18582                 JOBENV="JOBCOMPLEX"
18583                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18584
18585                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18586         fi
18587
18588         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18589                 JOBENV="JOBCOMPLEX"
18590                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18591
18592                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18593         fi
18594
18595         # test '%j' access to per-session jobid - if supported
18596         if lctl list_param jobid_this_session > /dev/null 2>&1
18597         then
18598                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18599                 lctl set_param jobid_this_session=$USER
18600
18601                 JOBENV="JOBCOMPLEX"
18602                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18603
18604                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18605         fi
18606 }
18607 run_test 205a "Verify job stats"
18608
18609 # LU-13117, LU-13597
18610 test_205b() {
18611         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18612                 skip "Need MDS version at least 2.13.54.91"
18613
18614         job_stats="mdt.*.job_stats"
18615         $LCTL set_param $job_stats=clear
18616         # Setting jobid_var to USER might not be supported
18617         $LCTL set_param jobid_var=USER || true
18618         $LCTL set_param jobid_name="%e.%u"
18619         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18620         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18621                 grep "job_id:.*foolish" &&
18622                         error "Unexpected jobid found"
18623         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18624                 grep "open:.*min.*max.*sum" ||
18625                         error "wrong job_stats format found"
18626 }
18627 run_test 205b "Verify job stats jobid and output format"
18628
18629 # LU-13733
18630 test_205c() {
18631         $LCTL set_param llite.*.stats=0
18632         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18633         $LCTL get_param llite.*.stats
18634         $LCTL get_param llite.*.stats | grep \
18635                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18636                         error "wrong client stats format found"
18637 }
18638 run_test 205c "Verify client stats format"
18639
18640 # LU-1480, LU-1773 and LU-1657
18641 test_206() {
18642         mkdir -p $DIR/$tdir
18643         $LFS setstripe -c -1 $DIR/$tdir
18644 #define OBD_FAIL_LOV_INIT 0x1403
18645         $LCTL set_param fail_loc=0xa0001403
18646         $LCTL set_param fail_val=1
18647         touch $DIR/$tdir/$tfile || true
18648 }
18649 run_test 206 "fail lov_init_raid0() doesn't lbug"
18650
18651 test_207a() {
18652         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18653         local fsz=`stat -c %s $DIR/$tfile`
18654         cancel_lru_locks mdc
18655
18656         # do not return layout in getattr intent
18657 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18658         $LCTL set_param fail_loc=0x170
18659         local sz=`stat -c %s $DIR/$tfile`
18660
18661         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18662
18663         rm -rf $DIR/$tfile
18664 }
18665 run_test 207a "can refresh layout at glimpse"
18666
18667 test_207b() {
18668         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18669         local cksum=`md5sum $DIR/$tfile`
18670         local fsz=`stat -c %s $DIR/$tfile`
18671         cancel_lru_locks mdc
18672         cancel_lru_locks osc
18673
18674         # do not return layout in getattr intent
18675 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18676         $LCTL set_param fail_loc=0x171
18677
18678         # it will refresh layout after the file is opened but before read issues
18679         echo checksum is "$cksum"
18680         echo "$cksum" |md5sum -c --quiet || error "file differs"
18681
18682         rm -rf $DIR/$tfile
18683 }
18684 run_test 207b "can refresh layout at open"
18685
18686 test_208() {
18687         # FIXME: in this test suite, only RD lease is used. This is okay
18688         # for now as only exclusive open is supported. After generic lease
18689         # is done, this test suite should be revised. - Jinshan
18690
18691         remote_mds_nodsh && skip "remote MDS with nodsh"
18692         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18693                 skip "Need MDS version at least 2.4.52"
18694
18695         echo "==== test 1: verify get lease work"
18696         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18697
18698         echo "==== test 2: verify lease can be broken by upcoming open"
18699         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18700         local PID=$!
18701         sleep 2
18702
18703         $MULTIOP $DIR/$tfile oO_RDWR:c
18704         kill -USR1 $PID && wait $PID || error "break lease error"
18705
18706         echo "==== test 3: verify lease can't be granted if an open already exists"
18707         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18708         local PID=$!
18709         sleep 2
18710
18711         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18712         kill -USR1 $PID && wait $PID || error "open file error"
18713
18714         echo "==== test 4: lease can sustain over recovery"
18715         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18716         PID=$!
18717         sleep 2
18718
18719         fail mds1
18720
18721         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18722
18723         echo "==== test 5: lease broken can't be regained by replay"
18724         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18725         PID=$!
18726         sleep 2
18727
18728         # open file to break lease and then recovery
18729         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18730         fail mds1
18731
18732         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18733
18734         rm -f $DIR/$tfile
18735 }
18736 run_test 208 "Exclusive open"
18737
18738 test_209() {
18739         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18740                 skip_env "must have disp_stripe"
18741
18742         touch $DIR/$tfile
18743         sync; sleep 5; sync;
18744
18745         echo 3 > /proc/sys/vm/drop_caches
18746         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18747                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18748         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18749
18750         # open/close 500 times
18751         for i in $(seq 500); do
18752                 cat $DIR/$tfile
18753         done
18754
18755         echo 3 > /proc/sys/vm/drop_caches
18756         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18757                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18758         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18759
18760         echo "before: $req_before, after: $req_after"
18761         [ $((req_after - req_before)) -ge 300 ] &&
18762                 error "open/close requests are not freed"
18763         return 0
18764 }
18765 run_test 209 "read-only open/close requests should be freed promptly"
18766
18767 test_210() {
18768         local pid
18769
18770         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18771         pid=$!
18772         sleep 1
18773
18774         $LFS getstripe $DIR/$tfile
18775         kill -USR1 $pid
18776         wait $pid || error "multiop failed"
18777
18778         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18779         pid=$!
18780         sleep 1
18781
18782         $LFS getstripe $DIR/$tfile
18783         kill -USR1 $pid
18784         wait $pid || error "multiop failed"
18785 }
18786 run_test 210 "lfs getstripe does not break leases"
18787
18788 test_212() {
18789         size=`date +%s`
18790         size=$((size % 8192 + 1))
18791         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18792         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18793         rm -f $DIR/f212 $DIR/f212.xyz
18794 }
18795 run_test 212 "Sendfile test ============================================"
18796
18797 test_213() {
18798         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18799         cancel_lru_locks osc
18800         lctl set_param fail_loc=0x8000040f
18801         # generate a read lock
18802         cat $DIR/$tfile > /dev/null
18803         # write to the file, it will try to cancel the above read lock.
18804         cat /etc/hosts >> $DIR/$tfile
18805 }
18806 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18807
18808 test_214() { # for bug 20133
18809         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18810         for (( i=0; i < 340; i++ )) ; do
18811                 touch $DIR/$tdir/d214c/a$i
18812         done
18813
18814         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18815         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18816         ls $DIR/d214c || error "ls $DIR/d214c failed"
18817         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18818         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18819 }
18820 run_test 214 "hash-indexed directory test - bug 20133"
18821
18822 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18823 create_lnet_proc_files() {
18824         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18825 }
18826
18827 # counterpart of create_lnet_proc_files
18828 remove_lnet_proc_files() {
18829         rm -f $TMP/lnet_$1.sys
18830 }
18831
18832 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18833 # 3rd arg as regexp for body
18834 check_lnet_proc_stats() {
18835         local l=$(cat "$TMP/lnet_$1" |wc -l)
18836         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18837
18838         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18839 }
18840
18841 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18842 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18843 # optional and can be regexp for 2nd line (lnet.routes case)
18844 check_lnet_proc_entry() {
18845         local blp=2          # blp stands for 'position of 1st line of body'
18846         [ -z "$5" ] || blp=3 # lnet.routes case
18847
18848         local l=$(cat "$TMP/lnet_$1" |wc -l)
18849         # subtracting one from $blp because the body can be empty
18850         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18851
18852         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18853                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18854
18855         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18856                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18857
18858         # bail out if any unexpected line happened
18859         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18860         [ "$?" != 0 ] || error "$2 misformatted"
18861 }
18862
18863 test_215() { # for bugs 18102, 21079, 21517
18864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18865
18866         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18867         local P='[1-9][0-9]*'           # positive numeric
18868         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18869         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18870         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18871         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18872
18873         local L1 # regexp for 1st line
18874         local L2 # regexp for 2nd line (optional)
18875         local BR # regexp for the rest (body)
18876
18877         # lnet.stats should look as 11 space-separated non-negative numerics
18878         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18879         create_lnet_proc_files "stats"
18880         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18881         remove_lnet_proc_files "stats"
18882
18883         # lnet.routes should look like this:
18884         # Routing disabled/enabled
18885         # net hops priority state router
18886         # where net is a string like tcp0, hops > 0, priority >= 0,
18887         # state is up/down,
18888         # router is a string like 192.168.1.1@tcp2
18889         L1="^Routing (disabled|enabled)$"
18890         L2="^net +hops +priority +state +router$"
18891         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18892         create_lnet_proc_files "routes"
18893         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18894         remove_lnet_proc_files "routes"
18895
18896         # lnet.routers should look like this:
18897         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18898         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18899         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18900         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18901         L1="^ref +rtr_ref +alive +router$"
18902         BR="^$P +$P +(up|down) +$NID$"
18903         create_lnet_proc_files "routers"
18904         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18905         remove_lnet_proc_files "routers"
18906
18907         # lnet.peers should look like this:
18908         # nid refs state last max rtr min tx min queue
18909         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18910         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18911         # numeric (0 or >0 or <0), queue >= 0.
18912         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18913         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18914         create_lnet_proc_files "peers"
18915         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18916         remove_lnet_proc_files "peers"
18917
18918         # lnet.buffers  should look like this:
18919         # pages count credits min
18920         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18921         L1="^pages +count +credits +min$"
18922         BR="^ +$N +$N +$I +$I$"
18923         create_lnet_proc_files "buffers"
18924         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18925         remove_lnet_proc_files "buffers"
18926
18927         # lnet.nis should look like this:
18928         # nid status alive refs peer rtr max tx min
18929         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18930         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18931         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18932         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18933         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18934         create_lnet_proc_files "nis"
18935         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18936         remove_lnet_proc_files "nis"
18937
18938         # can we successfully write to lnet.stats?
18939         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18940 }
18941 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18942
18943 test_216() { # bug 20317
18944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18945         remote_ost_nodsh && skip "remote OST with nodsh"
18946
18947         local node
18948         local facets=$(get_facets OST)
18949         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18950
18951         save_lustre_params client "osc.*.contention_seconds" > $p
18952         save_lustre_params $facets \
18953                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18954         save_lustre_params $facets \
18955                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18956         save_lustre_params $facets \
18957                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18958         clear_stats osc.*.osc_stats
18959
18960         # agressive lockless i/o settings
18961         do_nodes $(comma_list $(osts_nodes)) \
18962                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18963                         ldlm.namespaces.filter-*.contended_locks=0 \
18964                         ldlm.namespaces.filter-*.contention_seconds=60"
18965         lctl set_param -n osc.*.contention_seconds=60
18966
18967         $DIRECTIO write $DIR/$tfile 0 10 4096
18968         $CHECKSTAT -s 40960 $DIR/$tfile
18969
18970         # disable lockless i/o
18971         do_nodes $(comma_list $(osts_nodes)) \
18972                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18973                         ldlm.namespaces.filter-*.contended_locks=32 \
18974                         ldlm.namespaces.filter-*.contention_seconds=0"
18975         lctl set_param -n osc.*.contention_seconds=0
18976         clear_stats osc.*.osc_stats
18977
18978         dd if=/dev/zero of=$DIR/$tfile count=0
18979         $CHECKSTAT -s 0 $DIR/$tfile
18980
18981         restore_lustre_params <$p
18982         rm -f $p
18983         rm $DIR/$tfile
18984 }
18985 run_test 216 "check lockless direct write updates file size and kms correctly"
18986
18987 test_217() { # bug 22430
18988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18989
18990         local node
18991         local nid
18992
18993         for node in $(nodes_list); do
18994                 nid=$(host_nids_address $node $NETTYPE)
18995                 if [[ $nid = *-* ]] ; then
18996                         echo "lctl ping $(h2nettype $nid)"
18997                         lctl ping $(h2nettype $nid)
18998                 else
18999                         echo "skipping $node (no hyphen detected)"
19000                 fi
19001         done
19002 }
19003 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19004
19005 test_218() {
19006        # do directio so as not to populate the page cache
19007        log "creating a 10 Mb file"
19008        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19009        log "starting reads"
19010        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19011        log "truncating the file"
19012        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19013        log "killing dd"
19014        kill %+ || true # reads might have finished
19015        echo "wait until dd is finished"
19016        wait
19017        log "removing the temporary file"
19018        rm -rf $DIR/$tfile || error "tmp file removal failed"
19019 }
19020 run_test 218 "parallel read and truncate should not deadlock"
19021
19022 test_219() {
19023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19024
19025         # write one partial page
19026         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19027         # set no grant so vvp_io_commit_write will do sync write
19028         $LCTL set_param fail_loc=0x411
19029         # write a full page at the end of file
19030         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19031
19032         $LCTL set_param fail_loc=0
19033         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19034         $LCTL set_param fail_loc=0x411
19035         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19036
19037         # LU-4201
19038         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19039         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19040 }
19041 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19042
19043 test_220() { #LU-325
19044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19045         remote_ost_nodsh && skip "remote OST with nodsh"
19046         remote_mds_nodsh && skip "remote MDS with nodsh"
19047         remote_mgs_nodsh && skip "remote MGS with nodsh"
19048
19049         local OSTIDX=0
19050
19051         # create on MDT0000 so the last_id and next_id are correct
19052         mkdir_on_mdt0 $DIR/$tdir
19053         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19054         OST=${OST%_UUID}
19055
19056         # on the mdt's osc
19057         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19058         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19059                         osp.$mdtosc_proc1.prealloc_last_id)
19060         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19061                         osp.$mdtosc_proc1.prealloc_next_id)
19062
19063         $LFS df -i
19064
19065         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19066         #define OBD_FAIL_OST_ENOINO              0x229
19067         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19068         create_pool $FSNAME.$TESTNAME || return 1
19069         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19070
19071         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19072
19073         MDSOBJS=$((last_id - next_id))
19074         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19075
19076         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19077         echo "OST still has $count kbytes free"
19078
19079         echo "create $MDSOBJS files @next_id..."
19080         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19081
19082         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19083                         osp.$mdtosc_proc1.prealloc_last_id)
19084         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19085                         osp.$mdtosc_proc1.prealloc_next_id)
19086
19087         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19088         $LFS df -i
19089
19090         echo "cleanup..."
19091
19092         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19093         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19094
19095         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19096                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19097         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19098                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19099         echo "unlink $MDSOBJS files @$next_id..."
19100         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19101 }
19102 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19103
19104 test_221() {
19105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19106
19107         dd if=`which date` of=$MOUNT/date oflag=sync
19108         chmod +x $MOUNT/date
19109
19110         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19111         $LCTL set_param fail_loc=0x80001401
19112
19113         $MOUNT/date > /dev/null
19114         rm -f $MOUNT/date
19115 }
19116 run_test 221 "make sure fault and truncate race to not cause OOM"
19117
19118 test_222a () {
19119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19120
19121         rm -rf $DIR/$tdir
19122         test_mkdir $DIR/$tdir
19123         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19124         createmany -o $DIR/$tdir/$tfile 10
19125         cancel_lru_locks mdc
19126         cancel_lru_locks osc
19127         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19128         $LCTL set_param fail_loc=0x31a
19129         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19130         $LCTL set_param fail_loc=0
19131         rm -r $DIR/$tdir
19132 }
19133 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19134
19135 test_222b () {
19136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19137
19138         rm -rf $DIR/$tdir
19139         test_mkdir $DIR/$tdir
19140         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19141         createmany -o $DIR/$tdir/$tfile 10
19142         cancel_lru_locks mdc
19143         cancel_lru_locks osc
19144         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19145         $LCTL set_param fail_loc=0x31a
19146         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19147         $LCTL set_param fail_loc=0
19148 }
19149 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19150
19151 test_223 () {
19152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19153
19154         rm -rf $DIR/$tdir
19155         test_mkdir $DIR/$tdir
19156         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19157         createmany -o $DIR/$tdir/$tfile 10
19158         cancel_lru_locks mdc
19159         cancel_lru_locks osc
19160         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19161         $LCTL set_param fail_loc=0x31b
19162         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19163         $LCTL set_param fail_loc=0
19164         rm -r $DIR/$tdir
19165 }
19166 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19167
19168 test_224a() { # LU-1039, MRP-303
19169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19170         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19171         $LCTL set_param fail_loc=0x508
19172         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19173         $LCTL set_param fail_loc=0
19174         df $DIR
19175 }
19176 run_test 224a "Don't panic on bulk IO failure"
19177
19178 test_224bd_sub() { # LU-1039, MRP-303
19179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19180         local timeout=$1
19181
19182         shift
19183         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19184
19185         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19186
19187         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19188         cancel_lru_locks osc
19189         set_checksums 0
19190         stack_trap "set_checksums $ORIG_CSUM" EXIT
19191         local at_max_saved=0
19192
19193         # adaptive timeouts may prevent seeing the issue
19194         if at_is_enabled; then
19195                 at_max_saved=$(at_max_get mds)
19196                 at_max_set 0 mds client
19197                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19198         fi
19199
19200         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19201         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19202         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19203
19204         do_facet ost1 $LCTL set_param fail_loc=0
19205         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19206         df $DIR
19207 }
19208
19209 test_224b() {
19210         test_224bd_sub 3 error "dd failed"
19211 }
19212 run_test 224b "Don't panic on bulk IO failure"
19213
19214 test_224c() { # LU-6441
19215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19216         remote_mds_nodsh && skip "remote MDS with nodsh"
19217
19218         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19219         save_writethrough $p
19220         set_cache writethrough on
19221
19222         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19223         local at_max=$($LCTL get_param -n at_max)
19224         local timeout=$($LCTL get_param -n timeout)
19225         local test_at="at_max"
19226         local param_at="$FSNAME.sys.at_max"
19227         local test_timeout="timeout"
19228         local param_timeout="$FSNAME.sys.timeout"
19229
19230         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19231
19232         set_persistent_param_and_check client "$test_at" "$param_at" 0
19233         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19234
19235         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19236         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19237         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19238         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19239         sync
19240         do_facet ost1 "$LCTL set_param fail_loc=0"
19241
19242         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19243         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19244                 $timeout
19245
19246         $LCTL set_param -n $pages_per_rpc
19247         restore_lustre_params < $p
19248         rm -f $p
19249 }
19250 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19251
19252 test_224d() { # LU-11169
19253         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19254 }
19255 run_test 224d "Don't corrupt data on bulk IO timeout"
19256
19257 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19258 test_225a () {
19259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19260         if [ -z ${MDSSURVEY} ]; then
19261                 skip_env "mds-survey not found"
19262         fi
19263         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19264                 skip "Need MDS version at least 2.2.51"
19265
19266         local mds=$(facet_host $SINGLEMDS)
19267         local target=$(do_nodes $mds 'lctl dl' |
19268                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19269
19270         local cmd1="file_count=1000 thrhi=4"
19271         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19272         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19273         local cmd="$cmd1 $cmd2 $cmd3"
19274
19275         rm -f ${TMP}/mds_survey*
19276         echo + $cmd
19277         eval $cmd || error "mds-survey with zero-stripe failed"
19278         cat ${TMP}/mds_survey*
19279         rm -f ${TMP}/mds_survey*
19280 }
19281 run_test 225a "Metadata survey sanity with zero-stripe"
19282
19283 test_225b () {
19284         if [ -z ${MDSSURVEY} ]; then
19285                 skip_env "mds-survey not found"
19286         fi
19287         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19288                 skip "Need MDS version at least 2.2.51"
19289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19290         remote_mds_nodsh && skip "remote MDS with nodsh"
19291         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19292                 skip_env "Need to mount OST to test"
19293         fi
19294
19295         local mds=$(facet_host $SINGLEMDS)
19296         local target=$(do_nodes $mds 'lctl dl' |
19297                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19298
19299         local cmd1="file_count=1000 thrhi=4"
19300         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19301         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19302         local cmd="$cmd1 $cmd2 $cmd3"
19303
19304         rm -f ${TMP}/mds_survey*
19305         echo + $cmd
19306         eval $cmd || error "mds-survey with stripe_count failed"
19307         cat ${TMP}/mds_survey*
19308         rm -f ${TMP}/mds_survey*
19309 }
19310 run_test 225b "Metadata survey sanity with stripe_count = 1"
19311
19312 mcreate_path2fid () {
19313         local mode=$1
19314         local major=$2
19315         local minor=$3
19316         local name=$4
19317         local desc=$5
19318         local path=$DIR/$tdir/$name
19319         local fid
19320         local rc
19321         local fid_path
19322
19323         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19324                 error "cannot create $desc"
19325
19326         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19327         rc=$?
19328         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19329
19330         fid_path=$($LFS fid2path $MOUNT $fid)
19331         rc=$?
19332         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19333
19334         [ "$path" == "$fid_path" ] ||
19335                 error "fid2path returned $fid_path, expected $path"
19336
19337         echo "pass with $path and $fid"
19338 }
19339
19340 test_226a () {
19341         rm -rf $DIR/$tdir
19342         mkdir -p $DIR/$tdir
19343
19344         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19345         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19346         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19347         mcreate_path2fid 0040666 0 0 dir "directory"
19348         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19349         mcreate_path2fid 0100666 0 0 file "regular file"
19350         mcreate_path2fid 0120666 0 0 link "symbolic link"
19351         mcreate_path2fid 0140666 0 0 sock "socket"
19352 }
19353 run_test 226a "call path2fid and fid2path on files of all type"
19354
19355 test_226b () {
19356         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19357
19358         local MDTIDX=1
19359
19360         rm -rf $DIR/$tdir
19361         mkdir -p $DIR/$tdir
19362         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19363                 error "create remote directory failed"
19364         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19365         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19366                                 "character special file (null)"
19367         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19368                                 "character special file (no device)"
19369         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19370         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19371                                 "block special file (loop)"
19372         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19373         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19374         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19375 }
19376 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19377
19378 test_226c () {
19379         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19380         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19381                 skip "Need MDS version at least 2.13.55"
19382
19383         local submnt=/mnt/submnt
19384         local srcfile=/etc/passwd
19385         local dstfile=$submnt/passwd
19386         local path
19387         local fid
19388
19389         rm -rf $DIR/$tdir
19390         rm -rf $submnt
19391         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19392                 error "create remote directory failed"
19393         mkdir -p $submnt || error "create $submnt failed"
19394         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19395                 error "mount $submnt failed"
19396         stack_trap "umount $submnt" EXIT
19397
19398         cp $srcfile $dstfile
19399         fid=$($LFS path2fid $dstfile)
19400         path=$($LFS fid2path $submnt "$fid")
19401         [ "$path" = "$dstfile" ] ||
19402                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19403 }
19404 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19405
19406 # LU-1299 Executing or running ldd on a truncated executable does not
19407 # cause an out-of-memory condition.
19408 test_227() {
19409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19410         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19411
19412         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19413         chmod +x $MOUNT/date
19414
19415         $MOUNT/date > /dev/null
19416         ldd $MOUNT/date > /dev/null
19417         rm -f $MOUNT/date
19418 }
19419 run_test 227 "running truncated executable does not cause OOM"
19420
19421 # LU-1512 try to reuse idle OI blocks
19422 test_228a() {
19423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19424         remote_mds_nodsh && skip "remote MDS with nodsh"
19425         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19426
19427         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19428         local myDIR=$DIR/$tdir
19429
19430         mkdir -p $myDIR
19431         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19432         $LCTL set_param fail_loc=0x80001002
19433         createmany -o $myDIR/t- 10000
19434         $LCTL set_param fail_loc=0
19435         # The guard is current the largest FID holder
19436         touch $myDIR/guard
19437         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19438                     tr -d '[')
19439         local IDX=$(($SEQ % 64))
19440
19441         do_facet $SINGLEMDS sync
19442         # Make sure journal flushed.
19443         sleep 6
19444         local blk1=$(do_facet $SINGLEMDS \
19445                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19446                      grep Blockcount | awk '{print $4}')
19447
19448         # Remove old files, some OI blocks will become idle.
19449         unlinkmany $myDIR/t- 10000
19450         # Create new files, idle OI blocks should be reused.
19451         createmany -o $myDIR/t- 2000
19452         do_facet $SINGLEMDS sync
19453         # Make sure journal flushed.
19454         sleep 6
19455         local blk2=$(do_facet $SINGLEMDS \
19456                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19457                      grep Blockcount | awk '{print $4}')
19458
19459         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19460 }
19461 run_test 228a "try to reuse idle OI blocks"
19462
19463 test_228b() {
19464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19465         remote_mds_nodsh && skip "remote MDS with nodsh"
19466         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19467
19468         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19469         local myDIR=$DIR/$tdir
19470
19471         mkdir -p $myDIR
19472         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19473         $LCTL set_param fail_loc=0x80001002
19474         createmany -o $myDIR/t- 10000
19475         $LCTL set_param fail_loc=0
19476         # The guard is current the largest FID holder
19477         touch $myDIR/guard
19478         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19479                     tr -d '[')
19480         local IDX=$(($SEQ % 64))
19481
19482         do_facet $SINGLEMDS sync
19483         # Make sure journal flushed.
19484         sleep 6
19485         local blk1=$(do_facet $SINGLEMDS \
19486                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19487                      grep Blockcount | awk '{print $4}')
19488
19489         # Remove old files, some OI blocks will become idle.
19490         unlinkmany $myDIR/t- 10000
19491
19492         # stop the MDT
19493         stop $SINGLEMDS || error "Fail to stop MDT."
19494         # remount the MDT
19495         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19496                 error "Fail to start MDT."
19497
19498         df $MOUNT || error "Fail to df."
19499         # Create new files, idle OI blocks should be reused.
19500         createmany -o $myDIR/t- 2000
19501         do_facet $SINGLEMDS sync
19502         # Make sure journal flushed.
19503         sleep 6
19504         local blk2=$(do_facet $SINGLEMDS \
19505                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19506                      grep Blockcount | awk '{print $4}')
19507
19508         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19509 }
19510 run_test 228b "idle OI blocks can be reused after MDT restart"
19511
19512 #LU-1881
19513 test_228c() {
19514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19515         remote_mds_nodsh && skip "remote MDS with nodsh"
19516         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19517
19518         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19519         local myDIR=$DIR/$tdir
19520
19521         mkdir -p $myDIR
19522         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19523         $LCTL set_param fail_loc=0x80001002
19524         # 20000 files can guarantee there are index nodes in the OI file
19525         createmany -o $myDIR/t- 20000
19526         $LCTL set_param fail_loc=0
19527         # The guard is current the largest FID holder
19528         touch $myDIR/guard
19529         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19530                     tr -d '[')
19531         local IDX=$(($SEQ % 64))
19532
19533         do_facet $SINGLEMDS sync
19534         # Make sure journal flushed.
19535         sleep 6
19536         local blk1=$(do_facet $SINGLEMDS \
19537                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19538                      grep Blockcount | awk '{print $4}')
19539
19540         # Remove old files, some OI blocks will become idle.
19541         unlinkmany $myDIR/t- 20000
19542         rm -f $myDIR/guard
19543         # The OI file should become empty now
19544
19545         # Create new files, idle OI blocks should be reused.
19546         createmany -o $myDIR/t- 2000
19547         do_facet $SINGLEMDS sync
19548         # Make sure journal flushed.
19549         sleep 6
19550         local blk2=$(do_facet $SINGLEMDS \
19551                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19552                      grep Blockcount | awk '{print $4}')
19553
19554         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19555 }
19556 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19557
19558 test_229() { # LU-2482, LU-3448
19559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19560         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19561         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19562                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19563
19564         rm -f $DIR/$tfile
19565
19566         # Create a file with a released layout and stripe count 2.
19567         $MULTIOP $DIR/$tfile H2c ||
19568                 error "failed to create file with released layout"
19569
19570         $LFS getstripe -v $DIR/$tfile
19571
19572         local pattern=$($LFS getstripe -L $DIR/$tfile)
19573         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19574
19575         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19576                 error "getstripe"
19577         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19578         stat $DIR/$tfile || error "failed to stat released file"
19579
19580         chown $RUNAS_ID $DIR/$tfile ||
19581                 error "chown $RUNAS_ID $DIR/$tfile failed"
19582
19583         chgrp $RUNAS_ID $DIR/$tfile ||
19584                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19585
19586         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19587         rm $DIR/$tfile || error "failed to remove released file"
19588 }
19589 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19590
19591 test_230a() {
19592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19593         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19594         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19595                 skip "Need MDS version at least 2.11.52"
19596
19597         local MDTIDX=1
19598
19599         test_mkdir $DIR/$tdir
19600         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19601         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19602         [ $mdt_idx -ne 0 ] &&
19603                 error "create local directory on wrong MDT $mdt_idx"
19604
19605         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19606                         error "create remote directory failed"
19607         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19608         [ $mdt_idx -ne $MDTIDX ] &&
19609                 error "create remote directory on wrong MDT $mdt_idx"
19610
19611         createmany -o $DIR/$tdir/test_230/t- 10 ||
19612                 error "create files on remote directory failed"
19613         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19614         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19615         rm -r $DIR/$tdir || error "unlink remote directory failed"
19616 }
19617 run_test 230a "Create remote directory and files under the remote directory"
19618
19619 test_230b() {
19620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19621         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19622         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19623                 skip "Need MDS version at least 2.11.52"
19624
19625         local MDTIDX=1
19626         local mdt_index
19627         local i
19628         local file
19629         local pid
19630         local stripe_count
19631         local migrate_dir=$DIR/$tdir/migrate_dir
19632         local other_dir=$DIR/$tdir/other_dir
19633
19634         test_mkdir $DIR/$tdir
19635         test_mkdir -i0 -c1 $migrate_dir
19636         test_mkdir -i0 -c1 $other_dir
19637         for ((i=0; i<10; i++)); do
19638                 mkdir -p $migrate_dir/dir_${i}
19639                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19640                         error "create files under remote dir failed $i"
19641         done
19642
19643         cp /etc/passwd $migrate_dir/$tfile
19644         cp /etc/passwd $other_dir/$tfile
19645         chattr +SAD $migrate_dir
19646         chattr +SAD $migrate_dir/$tfile
19647
19648         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19649         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19650         local old_dir_mode=$(stat -c%f $migrate_dir)
19651         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19652
19653         mkdir -p $migrate_dir/dir_default_stripe2
19654         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19655         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19656
19657         mkdir -p $other_dir
19658         ln $migrate_dir/$tfile $other_dir/luna
19659         ln $migrate_dir/$tfile $migrate_dir/sofia
19660         ln $other_dir/$tfile $migrate_dir/david
19661         ln -s $migrate_dir/$tfile $other_dir/zachary
19662         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19663         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19664
19665         local len
19666         local lnktgt
19667
19668         # inline symlink
19669         for len in 58 59 60; do
19670                 lnktgt=$(str_repeat 'l' $len)
19671                 touch $migrate_dir/$lnktgt
19672                 ln -s $lnktgt $migrate_dir/${len}char_ln
19673         done
19674
19675         # PATH_MAX
19676         for len in 4094 4095; do
19677                 lnktgt=$(str_repeat 'l' $len)
19678                 ln -s $lnktgt $migrate_dir/${len}char_ln
19679         done
19680
19681         # NAME_MAX
19682         for len in 254 255; do
19683                 touch $migrate_dir/$(str_repeat 'l' $len)
19684         done
19685
19686         $LFS migrate -m $MDTIDX $migrate_dir ||
19687                 error "fails on migrating remote dir to MDT1"
19688
19689         echo "migratate to MDT1, then checking.."
19690         for ((i = 0; i < 10; i++)); do
19691                 for file in $(find $migrate_dir/dir_${i}); do
19692                         mdt_index=$($LFS getstripe -m $file)
19693                         # broken symlink getstripe will fail
19694                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19695                                 error "$file is not on MDT${MDTIDX}"
19696                 done
19697         done
19698
19699         # the multiple link file should still in MDT0
19700         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19701         [ $mdt_index == 0 ] ||
19702                 error "$file is not on MDT${MDTIDX}"
19703
19704         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19705         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19706                 error " expect $old_dir_flag get $new_dir_flag"
19707
19708         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19709         [ "$old_file_flag" = "$new_file_flag" ] ||
19710                 error " expect $old_file_flag get $new_file_flag"
19711
19712         local new_dir_mode=$(stat -c%f $migrate_dir)
19713         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19714                 error "expect mode $old_dir_mode get $new_dir_mode"
19715
19716         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19717         [ "$old_file_mode" = "$new_file_mode" ] ||
19718                 error "expect mode $old_file_mode get $new_file_mode"
19719
19720         diff /etc/passwd $migrate_dir/$tfile ||
19721                 error "$tfile different after migration"
19722
19723         diff /etc/passwd $other_dir/luna ||
19724                 error "luna different after migration"
19725
19726         diff /etc/passwd $migrate_dir/sofia ||
19727                 error "sofia different after migration"
19728
19729         diff /etc/passwd $migrate_dir/david ||
19730                 error "david different after migration"
19731
19732         diff /etc/passwd $other_dir/zachary ||
19733                 error "zachary different after migration"
19734
19735         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19736                 error "${tfile}_ln different after migration"
19737
19738         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19739                 error "${tfile}_ln_other different after migration"
19740
19741         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19742         [ $stripe_count = 2 ] ||
19743                 error "dir strpe_count $d != 2 after migration."
19744
19745         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19746         [ $stripe_count = 2 ] ||
19747                 error "file strpe_count $d != 2 after migration."
19748
19749         #migrate back to MDT0
19750         MDTIDX=0
19751
19752         $LFS migrate -m $MDTIDX $migrate_dir ||
19753                 error "fails on migrating remote dir to MDT0"
19754
19755         echo "migrate back to MDT0, checking.."
19756         for file in $(find $migrate_dir); do
19757                 mdt_index=$($LFS getstripe -m $file)
19758                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19759                         error "$file is not on MDT${MDTIDX}"
19760         done
19761
19762         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19763         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19764                 error " expect $old_dir_flag get $new_dir_flag"
19765
19766         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19767         [ "$old_file_flag" = "$new_file_flag" ] ||
19768                 error " expect $old_file_flag get $new_file_flag"
19769
19770         local new_dir_mode=$(stat -c%f $migrate_dir)
19771         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19772                 error "expect mode $old_dir_mode get $new_dir_mode"
19773
19774         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19775         [ "$old_file_mode" = "$new_file_mode" ] ||
19776                 error "expect mode $old_file_mode get $new_file_mode"
19777
19778         diff /etc/passwd ${migrate_dir}/$tfile ||
19779                 error "$tfile different after migration"
19780
19781         diff /etc/passwd ${other_dir}/luna ||
19782                 error "luna different after migration"
19783
19784         diff /etc/passwd ${migrate_dir}/sofia ||
19785                 error "sofia different after migration"
19786
19787         diff /etc/passwd ${other_dir}/zachary ||
19788                 error "zachary different after migration"
19789
19790         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19791                 error "${tfile}_ln different after migration"
19792
19793         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19794                 error "${tfile}_ln_other different after migration"
19795
19796         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19797         [ $stripe_count = 2 ] ||
19798                 error "dir strpe_count $d != 2 after migration."
19799
19800         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19801         [ $stripe_count = 2 ] ||
19802                 error "file strpe_count $d != 2 after migration."
19803
19804         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19805 }
19806 run_test 230b "migrate directory"
19807
19808 test_230c() {
19809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19810         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19811         remote_mds_nodsh && skip "remote MDS with nodsh"
19812         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19813                 skip "Need MDS version at least 2.11.52"
19814
19815         local MDTIDX=1
19816         local total=3
19817         local mdt_index
19818         local file
19819         local migrate_dir=$DIR/$tdir/migrate_dir
19820
19821         #If migrating directory fails in the middle, all entries of
19822         #the directory is still accessiable.
19823         test_mkdir $DIR/$tdir
19824         test_mkdir -i0 -c1 $migrate_dir
19825         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19826         stat $migrate_dir
19827         createmany -o $migrate_dir/f $total ||
19828                 error "create files under ${migrate_dir} failed"
19829
19830         # fail after migrating top dir, and this will fail only once, so the
19831         # first sub file migration will fail (currently f3), others succeed.
19832         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19833         do_facet mds1 lctl set_param fail_loc=0x1801
19834         local t=$(ls $migrate_dir | wc -l)
19835         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19836                 error "migrate should fail"
19837         local u=$(ls $migrate_dir | wc -l)
19838         [ "$u" == "$t" ] || error "$u != $t during migration"
19839
19840         # add new dir/file should succeed
19841         mkdir $migrate_dir/dir ||
19842                 error "mkdir failed under migrating directory"
19843         touch $migrate_dir/file ||
19844                 error "create file failed under migrating directory"
19845
19846         # add file with existing name should fail
19847         for file in $migrate_dir/f*; do
19848                 stat $file > /dev/null || error "stat $file failed"
19849                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19850                         error "open(O_CREAT|O_EXCL) $file should fail"
19851                 $MULTIOP $file m && error "create $file should fail"
19852                 touch $DIR/$tdir/remote_dir/$tfile ||
19853                         error "touch $tfile failed"
19854                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19855                         error "link $file should fail"
19856                 mdt_index=$($LFS getstripe -m $file)
19857                 if [ $mdt_index == 0 ]; then
19858                         # file failed to migrate is not allowed to rename to
19859                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19860                                 error "rename to $file should fail"
19861                 else
19862                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19863                                 error "rename to $file failed"
19864                 fi
19865                 echo hello >> $file || error "write $file failed"
19866         done
19867
19868         # resume migration with different options should fail
19869         $LFS migrate -m 0 $migrate_dir &&
19870                 error "migrate -m 0 $migrate_dir should fail"
19871
19872         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19873                 error "migrate -c 2 $migrate_dir should fail"
19874
19875         # resume migration should succeed
19876         $LFS migrate -m $MDTIDX $migrate_dir ||
19877                 error "migrate $migrate_dir failed"
19878
19879         echo "Finish migration, then checking.."
19880         for file in $(find $migrate_dir); do
19881                 mdt_index=$($LFS getstripe -m $file)
19882                 [ $mdt_index == $MDTIDX ] ||
19883                         error "$file is not on MDT${MDTIDX}"
19884         done
19885
19886         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19887 }
19888 run_test 230c "check directory accessiblity if migration failed"
19889
19890 test_230d() {
19891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19892         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19893         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19894                 skip "Need MDS version at least 2.11.52"
19895         # LU-11235
19896         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19897
19898         local migrate_dir=$DIR/$tdir/migrate_dir
19899         local old_index
19900         local new_index
19901         local old_count
19902         local new_count
19903         local new_hash
19904         local mdt_index
19905         local i
19906         local j
19907
19908         old_index=$((RANDOM % MDSCOUNT))
19909         old_count=$((MDSCOUNT - old_index))
19910         new_index=$((RANDOM % MDSCOUNT))
19911         new_count=$((MDSCOUNT - new_index))
19912         new_hash=1 # for all_char
19913
19914         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19915         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19916
19917         test_mkdir $DIR/$tdir
19918         test_mkdir -i $old_index -c $old_count $migrate_dir
19919
19920         for ((i=0; i<100; i++)); do
19921                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19922                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19923                         error "create files under remote dir failed $i"
19924         done
19925
19926         echo -n "Migrate from MDT$old_index "
19927         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19928         echo -n "to MDT$new_index"
19929         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19930         echo
19931
19932         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19933         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19934                 error "migrate remote dir error"
19935
19936         echo "Finish migration, then checking.."
19937         for file in $(find $migrate_dir -maxdepth 1); do
19938                 mdt_index=$($LFS getstripe -m $file)
19939                 if [ $mdt_index -lt $new_index ] ||
19940                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19941                         error "$file is on MDT$mdt_index"
19942                 fi
19943         done
19944
19945         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19946 }
19947 run_test 230d "check migrate big directory"
19948
19949 test_230e() {
19950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19951         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19952         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19953                 skip "Need MDS version at least 2.11.52"
19954
19955         local i
19956         local j
19957         local a_fid
19958         local b_fid
19959
19960         mkdir_on_mdt0 $DIR/$tdir
19961         mkdir $DIR/$tdir/migrate_dir
19962         mkdir $DIR/$tdir/other_dir
19963         touch $DIR/$tdir/migrate_dir/a
19964         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19965         ls $DIR/$tdir/other_dir
19966
19967         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19968                 error "migrate dir fails"
19969
19970         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19971         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19972
19973         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19974         [ $mdt_index == 0 ] || error "a is not on MDT0"
19975
19976         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19977                 error "migrate dir fails"
19978
19979         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19980         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19981
19982         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19983         [ $mdt_index == 1 ] || error "a is not on MDT1"
19984
19985         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19986         [ $mdt_index == 1 ] || error "b is not on MDT1"
19987
19988         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19989         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19990
19991         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19992
19993         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19994 }
19995 run_test 230e "migrate mulitple local link files"
19996
19997 test_230f() {
19998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19999         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20000         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20001                 skip "Need MDS version at least 2.11.52"
20002
20003         local a_fid
20004         local ln_fid
20005
20006         mkdir -p $DIR/$tdir
20007         mkdir $DIR/$tdir/migrate_dir
20008         $LFS mkdir -i1 $DIR/$tdir/other_dir
20009         touch $DIR/$tdir/migrate_dir/a
20010         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20011         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20012         ls $DIR/$tdir/other_dir
20013
20014         # a should be migrated to MDT1, since no other links on MDT0
20015         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20016                 error "#1 migrate dir fails"
20017         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20018         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20019         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20020         [ $mdt_index == 1 ] || error "a is not on MDT1"
20021
20022         # a should stay on MDT1, because it is a mulitple link file
20023         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20024                 error "#2 migrate dir fails"
20025         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20026         [ $mdt_index == 1 ] || error "a is not on MDT1"
20027
20028         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20029                 error "#3 migrate dir fails"
20030
20031         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20032         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20033         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20034
20035         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20036         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20037
20038         # a should be migrated to MDT0, since no other links on MDT1
20039         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20040                 error "#4 migrate dir fails"
20041         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20042         [ $mdt_index == 0 ] || error "a is not on MDT0"
20043
20044         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20045 }
20046 run_test 230f "migrate mulitple remote link files"
20047
20048 test_230g() {
20049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20050         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20051         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20052                 skip "Need MDS version at least 2.11.52"
20053
20054         mkdir -p $DIR/$tdir/migrate_dir
20055
20056         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20057                 error "migrating dir to non-exist MDT succeeds"
20058         true
20059 }
20060 run_test 230g "migrate dir to non-exist MDT"
20061
20062 test_230h() {
20063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20064         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20065         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20066                 skip "Need MDS version at least 2.11.52"
20067
20068         local mdt_index
20069
20070         mkdir -p $DIR/$tdir/migrate_dir
20071
20072         $LFS migrate -m1 $DIR &&
20073                 error "migrating mountpoint1 should fail"
20074
20075         $LFS migrate -m1 $DIR/$tdir/.. &&
20076                 error "migrating mountpoint2 should fail"
20077
20078         # same as mv
20079         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20080                 error "migrating $tdir/migrate_dir/.. should fail"
20081
20082         true
20083 }
20084 run_test 230h "migrate .. and root"
20085
20086 test_230i() {
20087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20088         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20089         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20090                 skip "Need MDS version at least 2.11.52"
20091
20092         mkdir -p $DIR/$tdir/migrate_dir
20093
20094         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20095                 error "migration fails with a tailing slash"
20096
20097         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20098                 error "migration fails with two tailing slashes"
20099 }
20100 run_test 230i "lfs migrate -m tolerates trailing slashes"
20101
20102 test_230j() {
20103         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20104         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20105                 skip "Need MDS version at least 2.11.52"
20106
20107         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20108         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20109                 error "create $tfile failed"
20110         cat /etc/passwd > $DIR/$tdir/$tfile
20111
20112         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20113
20114         cmp /etc/passwd $DIR/$tdir/$tfile ||
20115                 error "DoM file mismatch after migration"
20116 }
20117 run_test 230j "DoM file data not changed after dir migration"
20118
20119 test_230k() {
20120         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20121         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20122                 skip "Need MDS version at least 2.11.56"
20123
20124         local total=20
20125         local files_on_starting_mdt=0
20126
20127         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20128         $LFS getdirstripe $DIR/$tdir
20129         for i in $(seq $total); do
20130                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20131                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20132                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20133         done
20134
20135         echo "$files_on_starting_mdt files on MDT0"
20136
20137         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20138         $LFS getdirstripe $DIR/$tdir
20139
20140         files_on_starting_mdt=0
20141         for i in $(seq $total); do
20142                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20143                         error "file $tfile.$i mismatch after migration"
20144                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20145                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20146         done
20147
20148         echo "$files_on_starting_mdt files on MDT1 after migration"
20149         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20150
20151         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20152         $LFS getdirstripe $DIR/$tdir
20153
20154         files_on_starting_mdt=0
20155         for i in $(seq $total); do
20156                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20157                         error "file $tfile.$i mismatch after 2nd migration"
20158                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20159                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20160         done
20161
20162         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20163         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20164
20165         true
20166 }
20167 run_test 230k "file data not changed after dir migration"
20168
20169 test_230l() {
20170         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20171         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20172                 skip "Need MDS version at least 2.11.56"
20173
20174         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20175         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20176                 error "create files under remote dir failed $i"
20177         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20178 }
20179 run_test 230l "readdir between MDTs won't crash"
20180
20181 test_230m() {
20182         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20183         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20184                 skip "Need MDS version at least 2.11.56"
20185
20186         local MDTIDX=1
20187         local mig_dir=$DIR/$tdir/migrate_dir
20188         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20189         local shortstr="b"
20190         local val
20191
20192         echo "Creating files and dirs with xattrs"
20193         test_mkdir $DIR/$tdir
20194         test_mkdir -i0 -c1 $mig_dir
20195         mkdir $mig_dir/dir
20196         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20197                 error "cannot set xattr attr1 on dir"
20198         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20199                 error "cannot set xattr attr2 on dir"
20200         touch $mig_dir/dir/f0
20201         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20202                 error "cannot set xattr attr1 on file"
20203         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20204                 error "cannot set xattr attr2 on file"
20205         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20206         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20207         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20208         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20209         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20210         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20211         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20212         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20213         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20214
20215         echo "Migrating to MDT1"
20216         $LFS migrate -m $MDTIDX $mig_dir ||
20217                 error "fails on migrating dir to MDT1"
20218
20219         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20220         echo "Checking xattrs"
20221         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20222         [ "$val" = $longstr ] ||
20223                 error "expecting xattr1 $longstr on dir, found $val"
20224         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20225         [ "$val" = $shortstr ] ||
20226                 error "expecting xattr2 $shortstr on dir, found $val"
20227         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20228         [ "$val" = $longstr ] ||
20229                 error "expecting xattr1 $longstr on file, found $val"
20230         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20231         [ "$val" = $shortstr ] ||
20232                 error "expecting xattr2 $shortstr on file, found $val"
20233 }
20234 run_test 230m "xattrs not changed after dir migration"
20235
20236 test_230n() {
20237         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20238         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20239                 skip "Need MDS version at least 2.13.53"
20240
20241         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20242         cat /etc/hosts > $DIR/$tdir/$tfile
20243         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20244         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20245
20246         cmp /etc/hosts $DIR/$tdir/$tfile ||
20247                 error "File data mismatch after migration"
20248 }
20249 run_test 230n "Dir migration with mirrored file"
20250
20251 test_230o() {
20252         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20253         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20254                 skip "Need MDS version at least 2.13.52"
20255
20256         local mdts=$(comma_list $(mdts_nodes))
20257         local timeout=100
20258         local restripe_status
20259         local delta
20260         local i
20261
20262         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20263
20264         # in case "crush" hash type is not set
20265         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20266
20267         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20268                            mdt.*MDT0000.enable_dir_restripe)
20269         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20270         stack_trap "do_nodes $mdts $LCTL set_param \
20271                     mdt.*.enable_dir_restripe=$restripe_status"
20272
20273         mkdir $DIR/$tdir
20274         createmany -m $DIR/$tdir/f 100 ||
20275                 error "create files under remote dir failed $i"
20276         createmany -d $DIR/$tdir/d 100 ||
20277                 error "create dirs under remote dir failed $i"
20278
20279         for i in $(seq 2 $MDSCOUNT); do
20280                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20281                 $LFS setdirstripe -c $i $DIR/$tdir ||
20282                         error "split -c $i $tdir failed"
20283                 wait_update $HOSTNAME \
20284                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20285                         error "dir split not finished"
20286                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20287                         awk '/migrate/ {sum += $2} END { print sum }')
20288                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20289                 # delta is around total_files/stripe_count
20290                 (( $delta < 200 / (i - 1) + 4 )) ||
20291                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20292         done
20293 }
20294 run_test 230o "dir split"
20295
20296 test_230p() {
20297         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20298         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20299                 skip "Need MDS version at least 2.13.52"
20300
20301         local mdts=$(comma_list $(mdts_nodes))
20302         local timeout=100
20303         local restripe_status
20304         local delta
20305         local c
20306
20307         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20308
20309         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20310
20311         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20312                            mdt.*MDT0000.enable_dir_restripe)
20313         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20314         stack_trap "do_nodes $mdts $LCTL set_param \
20315                     mdt.*.enable_dir_restripe=$restripe_status"
20316
20317         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20318         createmany -m $DIR/$tdir/f 100 ||
20319                 error "create files under remote dir failed"
20320         createmany -d $DIR/$tdir/d 100 ||
20321                 error "create dirs under remote dir failed"
20322
20323         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20324                 local mdt_hash="crush"
20325
20326                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20327                 $LFS setdirstripe -c $c $DIR/$tdir ||
20328                         error "split -c $c $tdir failed"
20329                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20330                         mdt_hash="$mdt_hash,fixed"
20331                 elif [ $c -eq 1 ]; then
20332                         mdt_hash="none"
20333                 fi
20334                 wait_update $HOSTNAME \
20335                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20336                         error "dir merge not finished"
20337                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20338                         awk '/migrate/ {sum += $2} END { print sum }')
20339                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20340                 # delta is around total_files/stripe_count
20341                 (( delta < 200 / c + 4 )) ||
20342                         error "$delta files migrated >= $((200 / c + 4))"
20343         done
20344 }
20345 run_test 230p "dir merge"
20346
20347 test_230q() {
20348         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20349         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20350                 skip "Need MDS version at least 2.13.52"
20351
20352         local mdts=$(comma_list $(mdts_nodes))
20353         local saved_threshold=$(do_facet mds1 \
20354                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20355         local saved_delta=$(do_facet mds1 \
20356                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20357         local threshold=100
20358         local delta=2
20359         local total=0
20360         local stripe_count=0
20361         local stripe_index
20362         local nr_files
20363         local create
20364
20365         # test with fewer files on ZFS
20366         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20367
20368         stack_trap "do_nodes $mdts $LCTL set_param \
20369                     mdt.*.dir_split_count=$saved_threshold"
20370         stack_trap "do_nodes $mdts $LCTL set_param \
20371                     mdt.*.dir_split_delta=$saved_delta"
20372         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20373         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20374         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20375         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20376         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20377         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20378
20379         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20380         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20381
20382         create=$((threshold * 3 / 2))
20383         while [ $stripe_count -lt $MDSCOUNT ]; do
20384                 createmany -m $DIR/$tdir/f $total $create ||
20385                         error "create sub files failed"
20386                 stat $DIR/$tdir > /dev/null
20387                 total=$((total + create))
20388                 stripe_count=$((stripe_count + delta))
20389                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20390
20391                 wait_update $HOSTNAME \
20392                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20393                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20394
20395                 wait_update $HOSTNAME \
20396                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20397                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20398
20399                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20400                 echo "$nr_files/$total files on MDT$stripe_index after split"
20401                 # allow 10% margin of imbalance with crush hash
20402                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20403                         error "$nr_files files on MDT$stripe_index after split"
20404
20405                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20406                 [ $nr_files -eq $total ] ||
20407                         error "total sub files $nr_files != $total"
20408         done
20409
20410         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20411
20412         echo "fixed layout directory won't auto split"
20413         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20414         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20415                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20416         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20417                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20418 }
20419 run_test 230q "dir auto split"
20420
20421 test_230r() {
20422         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20423         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20424         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20425                 skip "Need MDS version at least 2.13.54"
20426
20427         # maximum amount of local locks:
20428         # parent striped dir - 2 locks
20429         # new stripe in parent to migrate to - 1 lock
20430         # source and target - 2 locks
20431         # Total 5 locks for regular file
20432         mkdir -p $DIR/$tdir
20433         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20434         touch $DIR/$tdir/dir1/eee
20435
20436         # create 4 hardlink for 4 more locks
20437         # Total: 9 locks > RS_MAX_LOCKS (8)
20438         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20439         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20440         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20441         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20442         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20443         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20444         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20445         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20446
20447         cancel_lru_locks mdc
20448
20449         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20450                 error "migrate dir fails"
20451
20452         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20453 }
20454 run_test 230r "migrate with too many local locks"
20455
20456 test_230s() {
20457         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20458                 skip "Need MDS version at least 2.14.52"
20459
20460         local mdts=$(comma_list $(mdts_nodes))
20461         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20462                                 mdt.*MDT0000.enable_dir_restripe)
20463
20464         stack_trap "do_nodes $mdts $LCTL set_param \
20465                     mdt.*.enable_dir_restripe=$restripe_status"
20466
20467         local st
20468         for st in 0 1; do
20469                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20470                 test_mkdir $DIR/$tdir
20471                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20472                         error "$LFS mkdir should return EEXIST if target exists"
20473                 rmdir $DIR/$tdir
20474         done
20475 }
20476 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20477
20478 test_230t()
20479 {
20480         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20481         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20482                 skip "Need MDS version at least 2.14.50"
20483
20484         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20485         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20486         $LFS project -p 1 -s $DIR/$tdir ||
20487                 error "set $tdir project id failed"
20488         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20489                 error "set subdir project id failed"
20490         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20491 }
20492 run_test 230t "migrate directory with project ID set"
20493
20494 test_230u()
20495 {
20496         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20497         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20498                 skip "Need MDS version at least 2.14.53"
20499
20500         local count
20501
20502         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20503         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20504         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20505         for i in $(seq 0 $((MDSCOUNT - 1))); do
20506                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20507                 echo "$count dirs migrated to MDT$i"
20508         done
20509         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20510         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20511 }
20512 run_test 230u "migrate directory by QOS"
20513
20514 test_230v()
20515 {
20516         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20517         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20518                 skip "Need MDS version at least 2.14.53"
20519
20520         local count
20521
20522         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20523         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20524         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20525         for i in $(seq 0 $((MDSCOUNT - 1))); do
20526                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20527                 echo "$count subdirs migrated to MDT$i"
20528                 (( i == 3 )) && (( count > 0 )) &&
20529                         error "subdir shouldn't be migrated to MDT3"
20530         done
20531         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20532         (( count == 3 )) || error "dirs migrated to $count MDTs"
20533 }
20534 run_test 230v "subdir migrated to the MDT where its parent is located"
20535
20536 test_230w() {
20537         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20538         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20539                 skip "Need MDS version at least 2.14.53"
20540
20541         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20542
20543         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20544                 error "migrate failed"
20545
20546         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20547                 error "$tdir stripe count mismatch"
20548
20549         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20550                 error "$tdir/sub is striped"
20551 }
20552 run_test 230w "non-recursive mode dir migration"
20553
20554 test_231a()
20555 {
20556         # For simplicity this test assumes that max_pages_per_rpc
20557         # is the same across all OSCs
20558         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20559         local bulk_size=$((max_pages * PAGE_SIZE))
20560         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20561                                        head -n 1)
20562
20563         mkdir -p $DIR/$tdir
20564         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20565                 error "failed to set stripe with -S ${brw_size}M option"
20566
20567         # clear the OSC stats
20568         $LCTL set_param osc.*.stats=0 &>/dev/null
20569         stop_writeback
20570
20571         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20572         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20573                 oflag=direct &>/dev/null || error "dd failed"
20574
20575         sync; sleep 1; sync # just to be safe
20576         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20577         if [ x$nrpcs != "x1" ]; then
20578                 $LCTL get_param osc.*.stats
20579                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20580         fi
20581
20582         start_writeback
20583         # Drop the OSC cache, otherwise we will read from it
20584         cancel_lru_locks osc
20585
20586         # clear the OSC stats
20587         $LCTL set_param osc.*.stats=0 &>/dev/null
20588
20589         # Client reads $bulk_size.
20590         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20591                 iflag=direct &>/dev/null || error "dd failed"
20592
20593         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20594         if [ x$nrpcs != "x1" ]; then
20595                 $LCTL get_param osc.*.stats
20596                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20597         fi
20598 }
20599 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20600
20601 test_231b() {
20602         mkdir -p $DIR/$tdir
20603         local i
20604         for i in {0..1023}; do
20605                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20606                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20607                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20608         done
20609         sync
20610 }
20611 run_test 231b "must not assert on fully utilized OST request buffer"
20612
20613 test_232a() {
20614         mkdir -p $DIR/$tdir
20615         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20616
20617         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20618         do_facet ost1 $LCTL set_param fail_loc=0x31c
20619
20620         # ignore dd failure
20621         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20622
20623         do_facet ost1 $LCTL set_param fail_loc=0
20624         umount_client $MOUNT || error "umount failed"
20625         mount_client $MOUNT || error "mount failed"
20626         stop ost1 || error "cannot stop ost1"
20627         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20628 }
20629 run_test 232a "failed lock should not block umount"
20630
20631 test_232b() {
20632         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20633                 skip "Need MDS version at least 2.10.58"
20634
20635         mkdir -p $DIR/$tdir
20636         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20637         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20638         sync
20639         cancel_lru_locks osc
20640
20641         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20642         do_facet ost1 $LCTL set_param fail_loc=0x31c
20643
20644         # ignore failure
20645         $LFS data_version $DIR/$tdir/$tfile || true
20646
20647         do_facet ost1 $LCTL set_param fail_loc=0
20648         umount_client $MOUNT || error "umount failed"
20649         mount_client $MOUNT || error "mount failed"
20650         stop ost1 || error "cannot stop ost1"
20651         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20652 }
20653 run_test 232b "failed data version lock should not block umount"
20654
20655 test_233a() {
20656         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20657                 skip "Need MDS version at least 2.3.64"
20658         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20659
20660         local fid=$($LFS path2fid $MOUNT)
20661
20662         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20663                 error "cannot access $MOUNT using its FID '$fid'"
20664 }
20665 run_test 233a "checking that OBF of the FS root succeeds"
20666
20667 test_233b() {
20668         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20669                 skip "Need MDS version at least 2.5.90"
20670         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20671
20672         local fid=$($LFS path2fid $MOUNT/.lustre)
20673
20674         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20675                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20676
20677         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20678         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20679                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20680 }
20681 run_test 233b "checking that OBF of the FS .lustre succeeds"
20682
20683 test_234() {
20684         local p="$TMP/sanityN-$TESTNAME.parameters"
20685         save_lustre_params client "llite.*.xattr_cache" > $p
20686         lctl set_param llite.*.xattr_cache 1 ||
20687                 skip_env "xattr cache is not supported"
20688
20689         mkdir -p $DIR/$tdir || error "mkdir failed"
20690         touch $DIR/$tdir/$tfile || error "touch failed"
20691         # OBD_FAIL_LLITE_XATTR_ENOMEM
20692         $LCTL set_param fail_loc=0x1405
20693         getfattr -n user.attr $DIR/$tdir/$tfile &&
20694                 error "getfattr should have failed with ENOMEM"
20695         $LCTL set_param fail_loc=0x0
20696         rm -rf $DIR/$tdir
20697
20698         restore_lustre_params < $p
20699         rm -f $p
20700 }
20701 run_test 234 "xattr cache should not crash on ENOMEM"
20702
20703 test_235() {
20704         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20705                 skip "Need MDS version at least 2.4.52"
20706
20707         flock_deadlock $DIR/$tfile
20708         local RC=$?
20709         case $RC in
20710                 0)
20711                 ;;
20712                 124) error "process hangs on a deadlock"
20713                 ;;
20714                 *) error "error executing flock_deadlock $DIR/$tfile"
20715                 ;;
20716         esac
20717 }
20718 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20719
20720 #LU-2935
20721 test_236() {
20722         check_swap_layouts_support
20723
20724         local ref1=/etc/passwd
20725         local ref2=/etc/group
20726         local file1=$DIR/$tdir/f1
20727         local file2=$DIR/$tdir/f2
20728
20729         test_mkdir -c1 $DIR/$tdir
20730         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20731         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20732         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20733         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20734         local fd=$(free_fd)
20735         local cmd="exec $fd<>$file2"
20736         eval $cmd
20737         rm $file2
20738         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20739                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20740         cmd="exec $fd>&-"
20741         eval $cmd
20742         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20743
20744         #cleanup
20745         rm -rf $DIR/$tdir
20746 }
20747 run_test 236 "Layout swap on open unlinked file"
20748
20749 # LU-4659 linkea consistency
20750 test_238() {
20751         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20752                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20753                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20754                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20755
20756         touch $DIR/$tfile
20757         ln $DIR/$tfile $DIR/$tfile.lnk
20758         touch $DIR/$tfile.new
20759         mv $DIR/$tfile.new $DIR/$tfile
20760         local fid1=$($LFS path2fid $DIR/$tfile)
20761         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20762         local path1=$($LFS fid2path $FSNAME "$fid1")
20763         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20764         local path2=$($LFS fid2path $FSNAME "$fid2")
20765         [ $tfile.lnk == $path2 ] ||
20766                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20767         rm -f $DIR/$tfile*
20768 }
20769 run_test 238 "Verify linkea consistency"
20770
20771 test_239A() { # was test_239
20772         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20773                 skip "Need MDS version at least 2.5.60"
20774
20775         local list=$(comma_list $(mdts_nodes))
20776
20777         mkdir -p $DIR/$tdir
20778         createmany -o $DIR/$tdir/f- 5000
20779         unlinkmany $DIR/$tdir/f- 5000
20780         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20781                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20782         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20783                         osp.*MDT*.sync_in_flight" | calc_sum)
20784         [ "$changes" -eq 0 ] || error "$changes not synced"
20785 }
20786 run_test 239A "osp_sync test"
20787
20788 test_239a() { #LU-5297
20789         remote_mds_nodsh && skip "remote MDS with nodsh"
20790
20791         touch $DIR/$tfile
20792         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20793         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20794         chgrp $RUNAS_GID $DIR/$tfile
20795         wait_delete_completed
20796 }
20797 run_test 239a "process invalid osp sync record correctly"
20798
20799 test_239b() { #LU-5297
20800         remote_mds_nodsh && skip "remote MDS with nodsh"
20801
20802         touch $DIR/$tfile1
20803         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20804         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20805         chgrp $RUNAS_GID $DIR/$tfile1
20806         wait_delete_completed
20807         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20808         touch $DIR/$tfile2
20809         chgrp $RUNAS_GID $DIR/$tfile2
20810         wait_delete_completed
20811 }
20812 run_test 239b "process osp sync record with ENOMEM error correctly"
20813
20814 test_240() {
20815         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20816         remote_mds_nodsh && skip "remote MDS with nodsh"
20817
20818         mkdir -p $DIR/$tdir
20819
20820         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20821                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20822         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20823                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20824
20825         umount_client $MOUNT || error "umount failed"
20826         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20827         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20828         mount_client $MOUNT || error "failed to mount client"
20829
20830         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20831         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20832 }
20833 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20834
20835 test_241_bio() {
20836         local count=$1
20837         local bsize=$2
20838
20839         for LOOP in $(seq $count); do
20840                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20841                 cancel_lru_locks $OSC || true
20842         done
20843 }
20844
20845 test_241_dio() {
20846         local count=$1
20847         local bsize=$2
20848
20849         for LOOP in $(seq $1); do
20850                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20851                         2>/dev/null
20852         done
20853 }
20854
20855 test_241a() { # was test_241
20856         local bsize=$PAGE_SIZE
20857
20858         (( bsize < 40960 )) && bsize=40960
20859         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20860         ls -la $DIR/$tfile
20861         cancel_lru_locks $OSC
20862         test_241_bio 1000 $bsize &
20863         PID=$!
20864         test_241_dio 1000 $bsize
20865         wait $PID
20866 }
20867 run_test 241a "bio vs dio"
20868
20869 test_241b() {
20870         local bsize=$PAGE_SIZE
20871
20872         (( bsize < 40960 )) && bsize=40960
20873         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20874         ls -la $DIR/$tfile
20875         test_241_dio 1000 $bsize &
20876         PID=$!
20877         test_241_dio 1000 $bsize
20878         wait $PID
20879 }
20880 run_test 241b "dio vs dio"
20881
20882 test_242() {
20883         remote_mds_nodsh && skip "remote MDS with nodsh"
20884
20885         mkdir_on_mdt0 $DIR/$tdir
20886         touch $DIR/$tdir/$tfile
20887
20888         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20889         do_facet mds1 lctl set_param fail_loc=0x105
20890         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20891
20892         do_facet mds1 lctl set_param fail_loc=0
20893         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20894 }
20895 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20896
20897 test_243()
20898 {
20899         test_mkdir $DIR/$tdir
20900         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20901 }
20902 run_test 243 "various group lock tests"
20903
20904 test_244a()
20905 {
20906         test_mkdir $DIR/$tdir
20907         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20908         sendfile_grouplock $DIR/$tdir/$tfile || \
20909                 error "sendfile+grouplock failed"
20910         rm -rf $DIR/$tdir
20911 }
20912 run_test 244a "sendfile with group lock tests"
20913
20914 test_244b()
20915 {
20916         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20917
20918         local threads=50
20919         local size=$((1024*1024))
20920
20921         test_mkdir $DIR/$tdir
20922         for i in $(seq 1 $threads); do
20923                 local file=$DIR/$tdir/file_$((i / 10))
20924                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20925                 local pids[$i]=$!
20926         done
20927         for i in $(seq 1 $threads); do
20928                 wait ${pids[$i]}
20929         done
20930 }
20931 run_test 244b "multi-threaded write with group lock"
20932
20933 test_245a() {
20934         local flagname="multi_mod_rpcs"
20935         local connect_data_name="max_mod_rpcs"
20936         local out
20937
20938         # check if multiple modify RPCs flag is set
20939         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20940                 grep "connect_flags:")
20941         echo "$out"
20942
20943         echo "$out" | grep -qw $flagname
20944         if [ $? -ne 0 ]; then
20945                 echo "connect flag $flagname is not set"
20946                 return
20947         fi
20948
20949         # check if multiple modify RPCs data is set
20950         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20951         echo "$out"
20952
20953         echo "$out" | grep -qw $connect_data_name ||
20954                 error "import should have connect data $connect_data_name"
20955 }
20956 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
20957
20958 test_245b() {
20959         local flagname="multi_mod_rpcs"
20960         local connect_data_name="max_mod_rpcs"
20961         local out
20962
20963         remote_mds_nodsh && skip "remote MDS with nodsh"
20964         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
20965
20966         # check if multiple modify RPCs flag is set
20967         out=$(do_facet mds1 \
20968               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
20969               grep "connect_flags:")
20970         echo "$out"
20971
20972         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
20973
20974         # check if multiple modify RPCs data is set
20975         out=$(do_facet mds1 \
20976               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
20977
20978         [[ "$out" =~ $connect_data_name ]] ||
20979                 {
20980                         echo "$out"
20981                         error "missing connect data $connect_data_name"
20982                 }
20983 }
20984 run_test 245b "check osp connection flag/data: multiple modify RPCs"
20985
20986 cleanup_247() {
20987         local submount=$1
20988
20989         trap 0
20990         umount_client $submount
20991         rmdir $submount
20992 }
20993
20994 test_247a() {
20995         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20996                 grep -q subtree ||
20997                 skip_env "Fileset feature is not supported"
20998
20999         local submount=${MOUNT}_$tdir
21000
21001         mkdir $MOUNT/$tdir
21002         mkdir -p $submount || error "mkdir $submount failed"
21003         FILESET="$FILESET/$tdir" mount_client $submount ||
21004                 error "mount $submount failed"
21005         trap "cleanup_247 $submount" EXIT
21006         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21007         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21008                 error "read $MOUNT/$tdir/$tfile failed"
21009         cleanup_247 $submount
21010 }
21011 run_test 247a "mount subdir as fileset"
21012
21013 test_247b() {
21014         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21015                 skip_env "Fileset feature is not supported"
21016
21017         local submount=${MOUNT}_$tdir
21018
21019         rm -rf $MOUNT/$tdir
21020         mkdir -p $submount || error "mkdir $submount failed"
21021         SKIP_FILESET=1
21022         FILESET="$FILESET/$tdir" mount_client $submount &&
21023                 error "mount $submount should fail"
21024         rmdir $submount
21025 }
21026 run_test 247b "mount subdir that dose not exist"
21027
21028 test_247c() {
21029         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21030                 skip_env "Fileset feature is not supported"
21031
21032         local submount=${MOUNT}_$tdir
21033
21034         mkdir -p $MOUNT/$tdir/dir1
21035         mkdir -p $submount || error "mkdir $submount failed"
21036         trap "cleanup_247 $submount" EXIT
21037         FILESET="$FILESET/$tdir" mount_client $submount ||
21038                 error "mount $submount failed"
21039         local fid=$($LFS path2fid $MOUNT/)
21040         $LFS fid2path $submount $fid && error "fid2path should fail"
21041         cleanup_247 $submount
21042 }
21043 run_test 247c "running fid2path outside subdirectory root"
21044
21045 test_247d() {
21046         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21047                 skip "Fileset feature is not supported"
21048
21049         local submount=${MOUNT}_$tdir
21050
21051         mkdir -p $MOUNT/$tdir/dir1
21052         mkdir -p $submount || error "mkdir $submount failed"
21053         FILESET="$FILESET/$tdir" mount_client $submount ||
21054                 error "mount $submount failed"
21055         trap "cleanup_247 $submount" EXIT
21056
21057         local td=$submount/dir1
21058         local fid=$($LFS path2fid $td)
21059         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21060
21061         # check that we get the same pathname back
21062         local rootpath
21063         local found
21064         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21065                 echo "$rootpath $fid"
21066                 found=$($LFS fid2path $rootpath "$fid")
21067                 [ -n "$found" ] || error "fid2path should succeed"
21068                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21069         done
21070         # check wrong root path format
21071         rootpath=$submount"_wrong"
21072         found=$($LFS fid2path $rootpath "$fid")
21073         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21074
21075         cleanup_247 $submount
21076 }
21077 run_test 247d "running fid2path inside subdirectory root"
21078
21079 # LU-8037
21080 test_247e() {
21081         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21082                 grep -q subtree ||
21083                 skip "Fileset feature is not supported"
21084
21085         local submount=${MOUNT}_$tdir
21086
21087         mkdir $MOUNT/$tdir
21088         mkdir -p $submount || error "mkdir $submount failed"
21089         FILESET="$FILESET/.." mount_client $submount &&
21090                 error "mount $submount should fail"
21091         rmdir $submount
21092 }
21093 run_test 247e "mount .. as fileset"
21094
21095 test_247f() {
21096         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21097         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21098                 skip "Need at least version 2.13.52"
21099         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21100                 skip "Need at least version 2.14.50"
21101         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21102                 grep -q subtree ||
21103                 skip "Fileset feature is not supported"
21104
21105         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21106         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21107                 error "mkdir remote failed"
21108         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21109                 error "mkdir remote/subdir failed"
21110         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21111                 error "mkdir striped failed"
21112         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21113
21114         local submount=${MOUNT}_$tdir
21115
21116         mkdir -p $submount || error "mkdir $submount failed"
21117         stack_trap "rmdir $submount"
21118
21119         local dir
21120         local stat
21121         local fileset=$FILESET
21122         local mdts=$(comma_list $(mdts_nodes))
21123
21124         stat=$(do_facet mds1 $LCTL get_param -n \
21125                 mdt.*MDT0000.enable_remote_subdir_mount)
21126         stack_trap "do_nodes $mdts $LCTL set_param \
21127                 mdt.*.enable_remote_subdir_mount=$stat"
21128
21129         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21130         stack_trap "umount_client $submount"
21131         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21132                 error "mount remote dir $dir should fail"
21133
21134         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21135                 $tdir/striped/. ; do
21136                 FILESET="$fileset/$dir" mount_client $submount ||
21137                         error "mount $dir failed"
21138                 umount_client $submount
21139         done
21140
21141         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21142         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21143                 error "mount $tdir/remote failed"
21144 }
21145 run_test 247f "mount striped or remote directory as fileset"
21146
21147 test_247g() {
21148         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21149         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21150                 skip "Need at least version 2.14.50"
21151
21152         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21153                 error "mkdir $tdir failed"
21154         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21155
21156         local submount=${MOUNT}_$tdir
21157
21158         mkdir -p $submount || error "mkdir $submount failed"
21159         stack_trap "rmdir $submount"
21160
21161         FILESET="$fileset/$tdir" mount_client $submount ||
21162                 error "mount $dir failed"
21163         stack_trap "umount $submount"
21164
21165         local mdts=$(comma_list $(mdts_nodes))
21166
21167         local nrpcs
21168
21169         stat $submount > /dev/null
21170         cancel_lru_locks $MDC
21171         stat $submount > /dev/null
21172         stat $submount/$tfile > /dev/null
21173         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21174         stat $submount/$tfile > /dev/null
21175         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21176                 awk '/getattr/ {sum += $2} END {print sum}')
21177
21178         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21179 }
21180 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21181
21182 test_248a() {
21183         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21184         [ -z "$fast_read_sav" ] && skip "no fast read support"
21185
21186         # create a large file for fast read verification
21187         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21188
21189         # make sure the file is created correctly
21190         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21191                 { rm -f $DIR/$tfile; skip "file creation error"; }
21192
21193         echo "Test 1: verify that fast read is 4 times faster on cache read"
21194
21195         # small read with fast read enabled
21196         $LCTL set_param -n llite.*.fast_read=1
21197         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21198                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21199                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21200         # small read with fast read disabled
21201         $LCTL set_param -n llite.*.fast_read=0
21202         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21203                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21204                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21205
21206         # verify that fast read is 4 times faster for cache read
21207         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21208                 error_not_in_vm "fast read was not 4 times faster: " \
21209                            "$t_fast vs $t_slow"
21210
21211         echo "Test 2: verify the performance between big and small read"
21212         $LCTL set_param -n llite.*.fast_read=1
21213
21214         # 1k non-cache read
21215         cancel_lru_locks osc
21216         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21217                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21218                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21219
21220         # 1M non-cache read
21221         cancel_lru_locks osc
21222         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21223                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21224                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21225
21226         # verify that big IO is not 4 times faster than small IO
21227         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21228                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21229
21230         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21231         rm -f $DIR/$tfile
21232 }
21233 run_test 248a "fast read verification"
21234
21235 test_248b() {
21236         # Default short_io_bytes=16384, try both smaller and larger sizes.
21237         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21238         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21239         echo "bs=53248 count=113 normal buffered write"
21240         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21241                 error "dd of initial data file failed"
21242         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21243
21244         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21245         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21246                 error "dd with sync normal writes failed"
21247         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21248
21249         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21250         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21251                 error "dd with sync small writes failed"
21252         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21253
21254         cancel_lru_locks osc
21255
21256         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21257         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21258         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21259         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21260                 iflag=direct || error "dd with O_DIRECT small read failed"
21261         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21262         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21263                 error "compare $TMP/$tfile.1 failed"
21264
21265         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21266         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21267
21268         # just to see what the maximum tunable value is, and test parsing
21269         echo "test invalid parameter 2MB"
21270         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21271                 error "too-large short_io_bytes allowed"
21272         echo "test maximum parameter 512KB"
21273         # if we can set a larger short_io_bytes, run test regardless of version
21274         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21275                 # older clients may not allow setting it this large, that's OK
21276                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21277                         skip "Need at least client version 2.13.50"
21278                 error "medium short_io_bytes failed"
21279         fi
21280         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21281         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21282
21283         echo "test large parameter 64KB"
21284         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21285         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21286
21287         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21288         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21289                 error "dd with sync large writes failed"
21290         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21291
21292         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21293         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21294         num=$((113 * 4096 / PAGE_SIZE))
21295         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21296         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21297                 error "dd with O_DIRECT large writes failed"
21298         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21299                 error "compare $DIR/$tfile.3 failed"
21300
21301         cancel_lru_locks osc
21302
21303         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21304         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21305                 error "dd with O_DIRECT large read failed"
21306         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21307                 error "compare $TMP/$tfile.2 failed"
21308
21309         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21310         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21311                 error "dd with O_DIRECT large read failed"
21312         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21313                 error "compare $TMP/$tfile.3 failed"
21314 }
21315 run_test 248b "test short_io read and write for both small and large sizes"
21316
21317 test_249() { # LU-7890
21318         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21319                 skip "Need at least version 2.8.54"
21320
21321         rm -f $DIR/$tfile
21322         $LFS setstripe -c 1 $DIR/$tfile
21323         # Offset 2T == 4k * 512M
21324         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21325                 error "dd to 2T offset failed"
21326 }
21327 run_test 249 "Write above 2T file size"
21328
21329 test_250() {
21330         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21331          && skip "no 16TB file size limit on ZFS"
21332
21333         $LFS setstripe -c 1 $DIR/$tfile
21334         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21335         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21336         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21337         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21338                 conv=notrunc,fsync && error "append succeeded"
21339         return 0
21340 }
21341 run_test 250 "Write above 16T limit"
21342
21343 test_251() {
21344         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21345
21346         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21347         #Skip once - writing the first stripe will succeed
21348         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21349         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21350                 error "short write happened"
21351
21352         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21353         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21354                 error "short read happened"
21355
21356         rm -f $DIR/$tfile
21357 }
21358 run_test 251 "Handling short read and write correctly"
21359
21360 test_252() {
21361         remote_mds_nodsh && skip "remote MDS with nodsh"
21362         remote_ost_nodsh && skip "remote OST with nodsh"
21363         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21364                 skip_env "ldiskfs only test"
21365         fi
21366
21367         local tgt
21368         local dev
21369         local out
21370         local uuid
21371         local num
21372         local gen
21373
21374         # check lr_reader on OST0000
21375         tgt=ost1
21376         dev=$(facet_device $tgt)
21377         out=$(do_facet $tgt $LR_READER $dev)
21378         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21379         echo "$out"
21380         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21381         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21382                 error "Invalid uuid returned by $LR_READER on target $tgt"
21383         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21384
21385         # check lr_reader -c on MDT0000
21386         tgt=mds1
21387         dev=$(facet_device $tgt)
21388         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21389                 skip "$LR_READER does not support additional options"
21390         fi
21391         out=$(do_facet $tgt $LR_READER -c $dev)
21392         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21393         echo "$out"
21394         num=$(echo "$out" | grep -c "mdtlov")
21395         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21396                 error "Invalid number of mdtlov clients returned by $LR_READER"
21397         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21398
21399         # check lr_reader -cr on MDT0000
21400         out=$(do_facet $tgt $LR_READER -cr $dev)
21401         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21402         echo "$out"
21403         echo "$out" | grep -q "^reply_data:$" ||
21404                 error "$LR_READER should have returned 'reply_data' section"
21405         num=$(echo "$out" | grep -c "client_generation")
21406         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21407 }
21408 run_test 252 "check lr_reader tool"
21409
21410 test_253() {
21411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21412         remote_mds_nodsh && skip "remote MDS with nodsh"
21413         remote_mgs_nodsh && skip "remote MGS with nodsh"
21414
21415         local ostidx=0
21416         local rc=0
21417         local ost_name=$(ostname_from_index $ostidx)
21418
21419         # on the mdt's osc
21420         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21421         do_facet $SINGLEMDS $LCTL get_param -n \
21422                 osp.$mdtosc_proc1.reserved_mb_high ||
21423                 skip  "remote MDS does not support reserved_mb_high"
21424
21425         rm -rf $DIR/$tdir
21426         wait_mds_ost_sync
21427         wait_delete_completed
21428         mkdir $DIR/$tdir
21429
21430         pool_add $TESTNAME || error "Pool creation failed"
21431         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21432
21433         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21434                 error "Setstripe failed"
21435
21436         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21437
21438         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21439                     grep "watermarks")
21440         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21441
21442         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21443                         osp.$mdtosc_proc1.prealloc_status)
21444         echo "prealloc_status $oa_status"
21445
21446         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21447                 error "File creation should fail"
21448
21449         #object allocation was stopped, but we still able to append files
21450         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21451                 oflag=append || error "Append failed"
21452
21453         rm -f $DIR/$tdir/$tfile.0
21454
21455         # For this test, we want to delete the files we created to go out of
21456         # space but leave the watermark, so we remain nearly out of space
21457         ost_watermarks_enospc_delete_files $tfile $ostidx
21458
21459         wait_delete_completed
21460
21461         sleep_maxage
21462
21463         for i in $(seq 10 12); do
21464                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21465                         2>/dev/null || error "File creation failed after rm"
21466         done
21467
21468         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21469                         osp.$mdtosc_proc1.prealloc_status)
21470         echo "prealloc_status $oa_status"
21471
21472         if (( oa_status != 0 )); then
21473                 error "Object allocation still disable after rm"
21474         fi
21475 }
21476 run_test 253 "Check object allocation limit"
21477
21478 test_254() {
21479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21480         remote_mds_nodsh && skip "remote MDS with nodsh"
21481
21482         local mdt=$(facet_svc $SINGLEMDS)
21483
21484         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21485                 skip "MDS does not support changelog_size"
21486
21487         local cl_user
21488
21489         changelog_register || error "changelog_register failed"
21490
21491         changelog_clear 0 || error "changelog_clear failed"
21492
21493         local size1=$(do_facet $SINGLEMDS \
21494                       $LCTL get_param -n mdd.$mdt.changelog_size)
21495         echo "Changelog size $size1"
21496
21497         rm -rf $DIR/$tdir
21498         $LFS mkdir -i 0 $DIR/$tdir
21499         # change something
21500         mkdir -p $DIR/$tdir/pics/2008/zachy
21501         touch $DIR/$tdir/pics/2008/zachy/timestamp
21502         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21503         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21504         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21505         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21506         rm $DIR/$tdir/pics/desktop.jpg
21507
21508         local size2=$(do_facet $SINGLEMDS \
21509                       $LCTL get_param -n mdd.$mdt.changelog_size)
21510         echo "Changelog size after work $size2"
21511
21512         (( $size2 > $size1 )) ||
21513                 error "new Changelog size=$size2 less than old size=$size1"
21514 }
21515 run_test 254 "Check changelog size"
21516
21517 ladvise_no_type()
21518 {
21519         local type=$1
21520         local file=$2
21521
21522         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21523                 awk -F: '{print $2}' | grep $type > /dev/null
21524         if [ $? -ne 0 ]; then
21525                 return 0
21526         fi
21527         return 1
21528 }
21529
21530 ladvise_no_ioctl()
21531 {
21532         local file=$1
21533
21534         lfs ladvise -a willread $file > /dev/null 2>&1
21535         if [ $? -eq 0 ]; then
21536                 return 1
21537         fi
21538
21539         lfs ladvise -a willread $file 2>&1 |
21540                 grep "Inappropriate ioctl for device" > /dev/null
21541         if [ $? -eq 0 ]; then
21542                 return 0
21543         fi
21544         return 1
21545 }
21546
21547 percent() {
21548         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21549 }
21550
21551 # run a random read IO workload
21552 # usage: random_read_iops <filename> <filesize> <iosize>
21553 random_read_iops() {
21554         local file=$1
21555         local fsize=$2
21556         local iosize=${3:-4096}
21557
21558         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21559                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21560 }
21561
21562 drop_file_oss_cache() {
21563         local file="$1"
21564         local nodes="$2"
21565
21566         $LFS ladvise -a dontneed $file 2>/dev/null ||
21567                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21568 }
21569
21570 ladvise_willread_performance()
21571 {
21572         local repeat=10
21573         local average_origin=0
21574         local average_cache=0
21575         local average_ladvise=0
21576
21577         for ((i = 1; i <= $repeat; i++)); do
21578                 echo "Iter $i/$repeat: reading without willread hint"
21579                 cancel_lru_locks osc
21580                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21581                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21582                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21583                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21584
21585                 cancel_lru_locks osc
21586                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21587                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21588                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21589
21590                 cancel_lru_locks osc
21591                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21592                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21593                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21594                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21595                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21596         done
21597         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21598         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21599         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21600
21601         speedup_cache=$(percent $average_cache $average_origin)
21602         speedup_ladvise=$(percent $average_ladvise $average_origin)
21603
21604         echo "Average uncached read: $average_origin"
21605         echo "Average speedup with OSS cached read: " \
21606                 "$average_cache = +$speedup_cache%"
21607         echo "Average speedup with ladvise willread: " \
21608                 "$average_ladvise = +$speedup_ladvise%"
21609
21610         local lowest_speedup=20
21611         if (( ${average_cache%.*} < $lowest_speedup )); then
21612                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21613                      " got $average_cache%. Skipping ladvise willread check."
21614                 return 0
21615         fi
21616
21617         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21618         # it is still good to run until then to exercise 'ladvise willread'
21619         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21620                 [ "$ost1_FSTYPE" = "zfs" ] &&
21621                 echo "osd-zfs does not support dontneed or drop_caches" &&
21622                 return 0
21623
21624         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21625         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21626                 error_not_in_vm "Speedup with willread is less than " \
21627                         "$lowest_speedup%, got $average_ladvise%"
21628 }
21629
21630 test_255a() {
21631         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21632                 skip "lustre < 2.8.54 does not support ladvise "
21633         remote_ost_nodsh && skip "remote OST with nodsh"
21634
21635         stack_trap "rm -f $DIR/$tfile"
21636         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21637
21638         ladvise_no_type willread $DIR/$tfile &&
21639                 skip "willread ladvise is not supported"
21640
21641         ladvise_no_ioctl $DIR/$tfile &&
21642                 skip "ladvise ioctl is not supported"
21643
21644         local size_mb=100
21645         local size=$((size_mb * 1048576))
21646         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21647                 error "dd to $DIR/$tfile failed"
21648
21649         lfs ladvise -a willread $DIR/$tfile ||
21650                 error "Ladvise failed with no range argument"
21651
21652         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21653                 error "Ladvise failed with no -l or -e argument"
21654
21655         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21656                 error "Ladvise failed with only -e argument"
21657
21658         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21659                 error "Ladvise failed with only -l argument"
21660
21661         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21662                 error "End offset should not be smaller than start offset"
21663
21664         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21665                 error "End offset should not be equal to start offset"
21666
21667         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21668                 error "Ladvise failed with overflowing -s argument"
21669
21670         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21671                 error "Ladvise failed with overflowing -e argument"
21672
21673         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21674                 error "Ladvise failed with overflowing -l argument"
21675
21676         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21677                 error "Ladvise succeeded with conflicting -l and -e arguments"
21678
21679         echo "Synchronous ladvise should wait"
21680         local delay=4
21681 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21682         do_nodes $(comma_list $(osts_nodes)) \
21683                 $LCTL set_param fail_val=$delay fail_loc=0x237
21684
21685         local start_ts=$SECONDS
21686         lfs ladvise -a willread $DIR/$tfile ||
21687                 error "Ladvise failed with no range argument"
21688         local end_ts=$SECONDS
21689         local inteval_ts=$((end_ts - start_ts))
21690
21691         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21692                 error "Synchronous advice didn't wait reply"
21693         fi
21694
21695         echo "Asynchronous ladvise shouldn't wait"
21696         local start_ts=$SECONDS
21697         lfs ladvise -a willread -b $DIR/$tfile ||
21698                 error "Ladvise failed with no range argument"
21699         local end_ts=$SECONDS
21700         local inteval_ts=$((end_ts - start_ts))
21701
21702         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21703                 error "Asynchronous advice blocked"
21704         fi
21705
21706         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21707         ladvise_willread_performance
21708 }
21709 run_test 255a "check 'lfs ladvise -a willread'"
21710
21711 facet_meminfo() {
21712         local facet=$1
21713         local info=$2
21714
21715         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21716 }
21717
21718 test_255b() {
21719         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21720                 skip "lustre < 2.8.54 does not support ladvise "
21721         remote_ost_nodsh && skip "remote OST with nodsh"
21722
21723         stack_trap "rm -f $DIR/$tfile"
21724         lfs setstripe -c 1 -i 0 $DIR/$tfile
21725
21726         ladvise_no_type dontneed $DIR/$tfile &&
21727                 skip "dontneed ladvise is not supported"
21728
21729         ladvise_no_ioctl $DIR/$tfile &&
21730                 skip "ladvise ioctl is not supported"
21731
21732         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21733                 [ "$ost1_FSTYPE" = "zfs" ] &&
21734                 skip "zfs-osd does not support 'ladvise dontneed'"
21735
21736         local size_mb=100
21737         local size=$((size_mb * 1048576))
21738         # In order to prevent disturbance of other processes, only check 3/4
21739         # of the memory usage
21740         local kibibytes=$((size_mb * 1024 * 3 / 4))
21741
21742         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21743                 error "dd to $DIR/$tfile failed"
21744
21745         #force write to complete before dropping OST cache & checking memory
21746         sync
21747
21748         local total=$(facet_meminfo ost1 MemTotal)
21749         echo "Total memory: $total KiB"
21750
21751         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21752         local before_read=$(facet_meminfo ost1 Cached)
21753         echo "Cache used before read: $before_read KiB"
21754
21755         lfs ladvise -a willread $DIR/$tfile ||
21756                 error "Ladvise willread failed"
21757         local after_read=$(facet_meminfo ost1 Cached)
21758         echo "Cache used after read: $after_read KiB"
21759
21760         lfs ladvise -a dontneed $DIR/$tfile ||
21761                 error "Ladvise dontneed again failed"
21762         local no_read=$(facet_meminfo ost1 Cached)
21763         echo "Cache used after dontneed ladvise: $no_read KiB"
21764
21765         if [ $total -lt $((before_read + kibibytes)) ]; then
21766                 echo "Memory is too small, abort checking"
21767                 return 0
21768         fi
21769
21770         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21771                 error "Ladvise willread should use more memory" \
21772                         "than $kibibytes KiB"
21773         fi
21774
21775         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21776                 error "Ladvise dontneed should release more memory" \
21777                         "than $kibibytes KiB"
21778         fi
21779 }
21780 run_test 255b "check 'lfs ladvise -a dontneed'"
21781
21782 test_255c() {
21783         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21784                 skip "lustre < 2.10.50 does not support lockahead"
21785
21786         local ost1_imp=$(get_osc_import_name client ost1)
21787         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21788                          cut -d'.' -f2)
21789         local count
21790         local new_count
21791         local difference
21792         local i
21793         local rc
21794
21795         test_mkdir -p $DIR/$tdir
21796         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21797
21798         #test 10 returns only success/failure
21799         i=10
21800         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21801         rc=$?
21802         if [ $rc -eq 255 ]; then
21803                 error "Ladvise test${i} failed, ${rc}"
21804         fi
21805
21806         #test 11 counts lock enqueue requests, all others count new locks
21807         i=11
21808         count=$(do_facet ost1 \
21809                 $LCTL get_param -n ost.OSS.ost.stats)
21810         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21811
21812         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21813         rc=$?
21814         if [ $rc -eq 255 ]; then
21815                 error "Ladvise test${i} failed, ${rc}"
21816         fi
21817
21818         new_count=$(do_facet ost1 \
21819                 $LCTL get_param -n ost.OSS.ost.stats)
21820         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21821                    awk '{ print $2 }')
21822
21823         difference="$((new_count - count))"
21824         if [ $difference -ne $rc ]; then
21825                 error "Ladvise test${i}, bad enqueue count, returned " \
21826                       "${rc}, actual ${difference}"
21827         fi
21828
21829         for i in $(seq 12 21); do
21830                 # If we do not do this, we run the risk of having too many
21831                 # locks and starting lock cancellation while we are checking
21832                 # lock counts.
21833                 cancel_lru_locks osc
21834
21835                 count=$($LCTL get_param -n \
21836                        ldlm.namespaces.$imp_name.lock_unused_count)
21837
21838                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21839                 rc=$?
21840                 if [ $rc -eq 255 ]; then
21841                         error "Ladvise test ${i} failed, ${rc}"
21842                 fi
21843
21844                 new_count=$($LCTL get_param -n \
21845                        ldlm.namespaces.$imp_name.lock_unused_count)
21846                 difference="$((new_count - count))"
21847
21848                 # Test 15 output is divided by 100 to map down to valid return
21849                 if [ $i -eq 15 ]; then
21850                         rc="$((rc * 100))"
21851                 fi
21852
21853                 if [ $difference -ne $rc ]; then
21854                         error "Ladvise test ${i}, bad lock count, returned " \
21855                               "${rc}, actual ${difference}"
21856                 fi
21857         done
21858
21859         #test 22 returns only success/failure
21860         i=22
21861         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21862         rc=$?
21863         if [ $rc -eq 255 ]; then
21864                 error "Ladvise test${i} failed, ${rc}"
21865         fi
21866 }
21867 run_test 255c "suite of ladvise lockahead tests"
21868
21869 test_256() {
21870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21871         remote_mds_nodsh && skip "remote MDS with nodsh"
21872         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21873         changelog_users $SINGLEMDS | grep "^cl" &&
21874                 skip "active changelog user"
21875
21876         local cl_user
21877         local cat_sl
21878         local mdt_dev
21879
21880         mdt_dev=$(facet_device $SINGLEMDS)
21881         echo $mdt_dev
21882
21883         changelog_register || error "changelog_register failed"
21884
21885         rm -rf $DIR/$tdir
21886         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
21887
21888         changelog_clear 0 || error "changelog_clear failed"
21889
21890         # change something
21891         touch $DIR/$tdir/{1..10}
21892
21893         # stop the MDT
21894         stop $SINGLEMDS || error "Fail to stop MDT"
21895
21896         # remount the MDT
21897         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21898                 error "Fail to start MDT"
21899
21900         #after mount new plainllog is used
21901         touch $DIR/$tdir/{11..19}
21902         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21903         stack_trap "rm -f $tmpfile"
21904         cat_sl=$(do_facet $SINGLEMDS "sync; \
21905                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21906                  llog_reader $tmpfile | grep -c type=1064553b")
21907         do_facet $SINGLEMDS llog_reader $tmpfile
21908
21909         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21910
21911         changelog_clear 0 || error "changelog_clear failed"
21912
21913         cat_sl=$(do_facet $SINGLEMDS "sync; \
21914                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21915                  llog_reader $tmpfile | grep -c type=1064553b")
21916
21917         if (( cat_sl == 2 )); then
21918                 error "Empty plain llog was not deleted from changelog catalog"
21919         elif (( cat_sl != 1 )); then
21920                 error "Active plain llog shouldn't be deleted from catalog"
21921         fi
21922 }
21923 run_test 256 "Check llog delete for empty and not full state"
21924
21925 test_257() {
21926         remote_mds_nodsh && skip "remote MDS with nodsh"
21927         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21928                 skip "Need MDS version at least 2.8.55"
21929
21930         test_mkdir $DIR/$tdir
21931
21932         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21933                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21934         stat $DIR/$tdir
21935
21936 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21937         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21938         local facet=mds$((mdtidx + 1))
21939         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21940         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21941
21942         stop $facet || error "stop MDS failed"
21943         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21944                 error "start MDS fail"
21945         wait_recovery_complete $facet
21946 }
21947 run_test 257 "xattr locks are not lost"
21948
21949 # Verify we take the i_mutex when security requires it
21950 test_258a() {
21951 #define OBD_FAIL_IMUTEX_SEC 0x141c
21952         $LCTL set_param fail_loc=0x141c
21953         touch $DIR/$tfile
21954         chmod u+s $DIR/$tfile
21955         chmod a+rwx $DIR/$tfile
21956         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21957         RC=$?
21958         if [ $RC -ne 0 ]; then
21959                 error "error, failed to take i_mutex, rc=$?"
21960         fi
21961         rm -f $DIR/$tfile
21962 }
21963 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21964
21965 # Verify we do NOT take the i_mutex in the normal case
21966 test_258b() {
21967 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21968         $LCTL set_param fail_loc=0x141d
21969         touch $DIR/$tfile
21970         chmod a+rwx $DIR
21971         chmod a+rw $DIR/$tfile
21972         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21973         RC=$?
21974         if [ $RC -ne 0 ]; then
21975                 error "error, took i_mutex unnecessarily, rc=$?"
21976         fi
21977         rm -f $DIR/$tfile
21978
21979 }
21980 run_test 258b "verify i_mutex security behavior"
21981
21982 test_259() {
21983         local file=$DIR/$tfile
21984         local before
21985         local after
21986
21987         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21988
21989         stack_trap "rm -f $file" EXIT
21990
21991         wait_delete_completed
21992         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21993         echo "before: $before"
21994
21995         $LFS setstripe -i 0 -c 1 $file
21996         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21997         sync_all_data
21998         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21999         echo "after write: $after"
22000
22001 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22002         do_facet ost1 $LCTL set_param fail_loc=0x2301
22003         $TRUNCATE $file 0
22004         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22005         echo "after truncate: $after"
22006
22007         stop ost1
22008         do_facet ost1 $LCTL set_param fail_loc=0
22009         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22010         sleep 2
22011         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22012         echo "after restart: $after"
22013         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22014                 error "missing truncate?"
22015
22016         return 0
22017 }
22018 run_test 259 "crash at delayed truncate"
22019
22020 test_260() {
22021 #define OBD_FAIL_MDC_CLOSE               0x806
22022         $LCTL set_param fail_loc=0x80000806
22023         touch $DIR/$tfile
22024
22025 }
22026 run_test 260 "Check mdc_close fail"
22027
22028 ### Data-on-MDT sanity tests ###
22029 test_270a() {
22030         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22031                 skip "Need MDS version at least 2.10.55 for DoM"
22032
22033         # create DoM file
22034         local dom=$DIR/$tdir/dom_file
22035         local tmp=$DIR/$tdir/tmp_file
22036
22037         mkdir_on_mdt0 $DIR/$tdir
22038
22039         # basic checks for DoM component creation
22040         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22041                 error "Can set MDT layout to non-first entry"
22042
22043         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22044                 error "Can define multiple entries as MDT layout"
22045
22046         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22047
22048         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22049         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22050         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22051
22052         local mdtidx=$($LFS getstripe -m $dom)
22053         local mdtname=MDT$(printf %04x $mdtidx)
22054         local facet=mds$((mdtidx + 1))
22055         local space_check=1
22056
22057         # Skip free space checks with ZFS
22058         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22059
22060         # write
22061         sync
22062         local size_tmp=$((65536 * 3))
22063         local mdtfree1=$(do_facet $facet \
22064                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22065
22066         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22067         # check also direct IO along write
22068         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22069         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22070         sync
22071         cmp $tmp $dom || error "file data is different"
22072         [ $(stat -c%s $dom) == $size_tmp ] ||
22073                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22074         if [ $space_check == 1 ]; then
22075                 local mdtfree2=$(do_facet $facet \
22076                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22077
22078                 # increase in usage from by $size_tmp
22079                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22080                         error "MDT free space wrong after write: " \
22081                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22082         fi
22083
22084         # truncate
22085         local size_dom=10000
22086
22087         $TRUNCATE $dom $size_dom
22088         [ $(stat -c%s $dom) == $size_dom ] ||
22089                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22090         if [ $space_check == 1 ]; then
22091                 mdtfree1=$(do_facet $facet \
22092                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22093                 # decrease in usage from $size_tmp to new $size_dom
22094                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22095                   $(((size_tmp - size_dom) / 1024)) ] ||
22096                         error "MDT free space is wrong after truncate: " \
22097                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22098         fi
22099
22100         # append
22101         cat $tmp >> $dom
22102         sync
22103         size_dom=$((size_dom + size_tmp))
22104         [ $(stat -c%s $dom) == $size_dom ] ||
22105                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22106         if [ $space_check == 1 ]; then
22107                 mdtfree2=$(do_facet $facet \
22108                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22109                 # increase in usage by $size_tmp from previous
22110                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22111                         error "MDT free space is wrong after append: " \
22112                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22113         fi
22114
22115         # delete
22116         rm $dom
22117         if [ $space_check == 1 ]; then
22118                 mdtfree1=$(do_facet $facet \
22119                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22120                 # decrease in usage by $size_dom from previous
22121                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22122                         error "MDT free space is wrong after removal: " \
22123                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22124         fi
22125
22126         # combined striping
22127         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22128                 error "Can't create DoM + OST striping"
22129
22130         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22131         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22132         # check also direct IO along write
22133         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22134         sync
22135         cmp $tmp $dom || error "file data is different"
22136         [ $(stat -c%s $dom) == $size_tmp ] ||
22137                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22138         rm $dom $tmp
22139
22140         return 0
22141 }
22142 run_test 270a "DoM: basic functionality tests"
22143
22144 test_270b() {
22145         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22146                 skip "Need MDS version at least 2.10.55"
22147
22148         local dom=$DIR/$tdir/dom_file
22149         local max_size=1048576
22150
22151         mkdir -p $DIR/$tdir
22152         $LFS setstripe -E $max_size -L mdt $dom
22153
22154         # truncate over the limit
22155         $TRUNCATE $dom $(($max_size + 1)) &&
22156                 error "successful truncate over the maximum size"
22157         # write over the limit
22158         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22159                 error "successful write over the maximum size"
22160         # append over the limit
22161         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22162         echo "12345" >> $dom && error "successful append over the maximum size"
22163         rm $dom
22164
22165         return 0
22166 }
22167 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22168
22169 test_270c() {
22170         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22171                 skip "Need MDS version at least 2.10.55"
22172
22173         mkdir -p $DIR/$tdir
22174         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22175
22176         # check files inherit DoM EA
22177         touch $DIR/$tdir/first
22178         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22179                 error "bad pattern"
22180         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22181                 error "bad stripe count"
22182         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22183                 error "bad stripe size"
22184
22185         # check directory inherits DoM EA and uses it as default
22186         mkdir $DIR/$tdir/subdir
22187         touch $DIR/$tdir/subdir/second
22188         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22189                 error "bad pattern in sub-directory"
22190         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22191                 error "bad stripe count in sub-directory"
22192         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22193                 error "bad stripe size in sub-directory"
22194         return 0
22195 }
22196 run_test 270c "DoM: DoM EA inheritance tests"
22197
22198 test_270d() {
22199         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22200                 skip "Need MDS version at least 2.10.55"
22201
22202         mkdir -p $DIR/$tdir
22203         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22204
22205         # inherit default DoM striping
22206         mkdir $DIR/$tdir/subdir
22207         touch $DIR/$tdir/subdir/f1
22208
22209         # change default directory striping
22210         $LFS setstripe -c 1 $DIR/$tdir/subdir
22211         touch $DIR/$tdir/subdir/f2
22212         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22213                 error "wrong default striping in file 2"
22214         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22215                 error "bad pattern in file 2"
22216         return 0
22217 }
22218 run_test 270d "DoM: change striping from DoM to RAID0"
22219
22220 test_270e() {
22221         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22222                 skip "Need MDS version at least 2.10.55"
22223
22224         mkdir -p $DIR/$tdir/dom
22225         mkdir -p $DIR/$tdir/norm
22226         DOMFILES=20
22227         NORMFILES=10
22228         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22229         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22230
22231         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22232         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22233
22234         # find DoM files by layout
22235         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22236         [ $NUM -eq  $DOMFILES ] ||
22237                 error "lfs find -L: found $NUM, expected $DOMFILES"
22238         echo "Test 1: lfs find 20 DOM files by layout: OK"
22239
22240         # there should be 1 dir with default DOM striping
22241         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22242         [ $NUM -eq  1 ] ||
22243                 error "lfs find -L: found $NUM, expected 1 dir"
22244         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22245
22246         # find DoM files by stripe size
22247         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22248         [ $NUM -eq  $DOMFILES ] ||
22249                 error "lfs find -S: found $NUM, expected $DOMFILES"
22250         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22251
22252         # find files by stripe offset except DoM files
22253         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22254         [ $NUM -eq  $NORMFILES ] ||
22255                 error "lfs find -i: found $NUM, expected $NORMFILES"
22256         echo "Test 5: lfs find no DOM files by stripe index: OK"
22257         return 0
22258 }
22259 run_test 270e "DoM: lfs find with DoM files test"
22260
22261 test_270f() {
22262         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22263                 skip "Need MDS version at least 2.10.55"
22264
22265         local mdtname=${FSNAME}-MDT0000-mdtlov
22266         local dom=$DIR/$tdir/dom_file
22267         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22268                                                 lod.$mdtname.dom_stripesize)
22269         local dom_limit=131072
22270
22271         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22272         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22273                                                 lod.$mdtname.dom_stripesize)
22274         [ ${dom_limit} -eq ${dom_current} ] ||
22275                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22276
22277         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22278         $LFS setstripe -d $DIR/$tdir
22279         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22280                 error "Can't set directory default striping"
22281
22282         # exceed maximum stripe size
22283         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22284                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22285         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22286                 error "Able to create DoM component size more than LOD limit"
22287
22288         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22289         dom_current=$(do_facet mds1 $LCTL get_param -n \
22290                                                 lod.$mdtname.dom_stripesize)
22291         [ 0 -eq ${dom_current} ] ||
22292                 error "Can't set zero DoM stripe limit"
22293         rm $dom
22294
22295         # attempt to create DoM file on server with disabled DoM should
22296         # remove DoM entry from layout and be succeed
22297         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22298                 error "Can't create DoM file (DoM is disabled)"
22299         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22300                 error "File has DoM component while DoM is disabled"
22301         rm $dom
22302
22303         # attempt to create DoM file with only DoM stripe should return error
22304         $LFS setstripe -E $dom_limit -L mdt $dom &&
22305                 error "Able to create DoM-only file while DoM is disabled"
22306
22307         # too low values to be aligned with smallest stripe size 64K
22308         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22309         dom_current=$(do_facet mds1 $LCTL get_param -n \
22310                                                 lod.$mdtname.dom_stripesize)
22311         [ 30000 -eq ${dom_current} ] &&
22312                 error "Can set too small DoM stripe limit"
22313
22314         # 64K is a minimal stripe size in Lustre, expect limit of that size
22315         [ 65536 -eq ${dom_current} ] ||
22316                 error "Limit is not set to 64K but ${dom_current}"
22317
22318         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22319         dom_current=$(do_facet mds1 $LCTL get_param -n \
22320                                                 lod.$mdtname.dom_stripesize)
22321         echo $dom_current
22322         [ 2147483648 -eq ${dom_current} ] &&
22323                 error "Can set too large DoM stripe limit"
22324
22325         do_facet mds1 $LCTL set_param -n \
22326                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22327         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22328                 error "Can't create DoM component size after limit change"
22329         do_facet mds1 $LCTL set_param -n \
22330                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22331         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22332                 error "Can't create DoM file after limit decrease"
22333         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22334                 error "Can create big DoM component after limit decrease"
22335         touch ${dom}_def ||
22336                 error "Can't create file with old default layout"
22337
22338         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22339         return 0
22340 }
22341 run_test 270f "DoM: maximum DoM stripe size checks"
22342
22343 test_270g() {
22344         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22345                 skip "Need MDS version at least 2.13.52"
22346         local dom=$DIR/$tdir/$tfile
22347
22348         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22349         local lodname=${FSNAME}-MDT0000-mdtlov
22350
22351         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22352         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22353         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22354         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22355
22356         local dom_limit=1024
22357         local dom_threshold="50%"
22358
22359         $LFS setstripe -d $DIR/$tdir
22360         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22361                 error "Can't set directory default striping"
22362
22363         do_facet mds1 $LCTL set_param -n \
22364                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22365         # set 0 threshold and create DOM file to change tunable stripesize
22366         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22367         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22368                 error "Failed to create $dom file"
22369         # now tunable dom_cur_stripesize should reach maximum
22370         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22371                                         lod.${lodname}.dom_stripesize_cur_kb)
22372         [[ $dom_current == $dom_limit ]] ||
22373                 error "Current DOM stripesize is not maximum"
22374         rm $dom
22375
22376         # set threshold for further tests
22377         do_facet mds1 $LCTL set_param -n \
22378                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22379         echo "DOM threshold is $dom_threshold free space"
22380         local dom_def
22381         local dom_set
22382         # Spoof bfree to exceed threshold
22383         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22384         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22385         for spfree in 40 20 0 15 30 55; do
22386                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22387                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22388                         error "Failed to create $dom file"
22389                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22390                                         lod.${lodname}.dom_stripesize_cur_kb)
22391                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22392                 [[ $dom_def != $dom_current ]] ||
22393                         error "Default stripe size was not changed"
22394                 if (( spfree > 0 )) ; then
22395                         dom_set=$($LFS getstripe -S $dom)
22396                         (( dom_set == dom_def * 1024 )) ||
22397                                 error "DOM component size is still old"
22398                 else
22399                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22400                                 error "DoM component is set with no free space"
22401                 fi
22402                 rm $dom
22403                 dom_current=$dom_def
22404         done
22405 }
22406 run_test 270g "DoM: default DoM stripe size depends on free space"
22407
22408 test_270h() {
22409         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22410                 skip "Need MDS version at least 2.13.53"
22411
22412         local mdtname=${FSNAME}-MDT0000-mdtlov
22413         local dom=$DIR/$tdir/$tfile
22414         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22415
22416         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22417         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22418
22419         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22420         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22421                 error "can't create OST file"
22422         # mirrored file with DOM entry in the second mirror
22423         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22424                 error "can't create mirror with DoM component"
22425
22426         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22427
22428         # DOM component in the middle and has other enries in the same mirror,
22429         # should succeed but lost DoM component
22430         $LFS setstripe --copy=${dom}_1 $dom ||
22431                 error "Can't create file from OST|DOM mirror layout"
22432         # check new file has no DoM layout after all
22433         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22434                 error "File has DoM component while DoM is disabled"
22435 }
22436 run_test 270h "DoM: DoM stripe removal when disabled on server"
22437
22438 test_270i() {
22439         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22440                 skip "Need MDS version at least 2.14.54"
22441
22442         mkdir $DIR/$tdir
22443         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22444                 error "setstripe should fail" || true
22445 }
22446 run_test 270i "DoM: setting invalid DoM striping should fail"
22447
22448 test_271a() {
22449         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22450                 skip "Need MDS version at least 2.10.55"
22451
22452         local dom=$DIR/$tdir/dom
22453
22454         mkdir -p $DIR/$tdir
22455
22456         $LFS setstripe -E 1024K -L mdt $dom
22457
22458         lctl set_param -n mdc.*.stats=clear
22459         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22460         cat $dom > /dev/null
22461         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22462         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22463         ls $dom
22464         rm -f $dom
22465 }
22466 run_test 271a "DoM: data is cached for read after write"
22467
22468 test_271b() {
22469         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22470                 skip "Need MDS version at least 2.10.55"
22471
22472         local dom=$DIR/$tdir/dom
22473
22474         mkdir -p $DIR/$tdir
22475
22476         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22477
22478         lctl set_param -n mdc.*.stats=clear
22479         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22480         cancel_lru_locks mdc
22481         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22482         # second stat to check size is cached on client
22483         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22484         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22485         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22486         rm -f $dom
22487 }
22488 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22489
22490 test_271ba() {
22491         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22492                 skip "Need MDS version at least 2.10.55"
22493
22494         local dom=$DIR/$tdir/dom
22495
22496         mkdir -p $DIR/$tdir
22497
22498         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22499
22500         lctl set_param -n mdc.*.stats=clear
22501         lctl set_param -n osc.*.stats=clear
22502         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22503         cancel_lru_locks mdc
22504         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22505         # second stat to check size is cached on client
22506         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22507         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22508         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22509         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22510         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22511         rm -f $dom
22512 }
22513 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22514
22515
22516 get_mdc_stats() {
22517         local mdtidx=$1
22518         local param=$2
22519         local mdt=MDT$(printf %04x $mdtidx)
22520
22521         if [ -z $param ]; then
22522                 lctl get_param -n mdc.*$mdt*.stats
22523         else
22524                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22525         fi
22526 }
22527
22528 test_271c() {
22529         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22530                 skip "Need MDS version at least 2.10.55"
22531
22532         local dom=$DIR/$tdir/dom
22533
22534         mkdir -p $DIR/$tdir
22535
22536         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22537
22538         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22539         local facet=mds$((mdtidx + 1))
22540
22541         cancel_lru_locks mdc
22542         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22543         createmany -o $dom 1000
22544         lctl set_param -n mdc.*.stats=clear
22545         smalliomany -w $dom 1000 200
22546         get_mdc_stats $mdtidx
22547         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22548         # Each file has 1 open, 1 IO enqueues, total 2000
22549         # but now we have also +1 getxattr for security.capability, total 3000
22550         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22551         unlinkmany $dom 1000
22552
22553         cancel_lru_locks mdc
22554         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22555         createmany -o $dom 1000
22556         lctl set_param -n mdc.*.stats=clear
22557         smalliomany -w $dom 1000 200
22558         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22559         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22560         # for OPEN and IO lock.
22561         [ $((enq - enq_2)) -ge 1000 ] ||
22562                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22563         unlinkmany $dom 1000
22564         return 0
22565 }
22566 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22567
22568 cleanup_271def_tests() {
22569         trap 0
22570         rm -f $1
22571 }
22572
22573 test_271d() {
22574         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22575                 skip "Need MDS version at least 2.10.57"
22576
22577         local dom=$DIR/$tdir/dom
22578         local tmp=$TMP/$tfile
22579         trap "cleanup_271def_tests $tmp" EXIT
22580
22581         mkdir -p $DIR/$tdir
22582
22583         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22584
22585         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22586
22587         cancel_lru_locks mdc
22588         dd if=/dev/urandom of=$tmp bs=1000 count=1
22589         dd if=$tmp of=$dom bs=1000 count=1
22590         cancel_lru_locks mdc
22591
22592         cat /etc/hosts >> $tmp
22593         lctl set_param -n mdc.*.stats=clear
22594
22595         # append data to the same file it should update local page
22596         echo "Append to the same page"
22597         cat /etc/hosts >> $dom
22598         local num=$(get_mdc_stats $mdtidx ost_read)
22599         local ra=$(get_mdc_stats $mdtidx req_active)
22600         local rw=$(get_mdc_stats $mdtidx req_waittime)
22601
22602         [ -z $num ] || error "$num READ RPC occured"
22603         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22604         echo "... DONE"
22605
22606         # compare content
22607         cmp $tmp $dom || error "file miscompare"
22608
22609         cancel_lru_locks mdc
22610         lctl set_param -n mdc.*.stats=clear
22611
22612         echo "Open and read file"
22613         cat $dom > /dev/null
22614         local num=$(get_mdc_stats $mdtidx ost_read)
22615         local ra=$(get_mdc_stats $mdtidx req_active)
22616         local rw=$(get_mdc_stats $mdtidx req_waittime)
22617
22618         [ -z $num ] || error "$num READ RPC occured"
22619         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22620         echo "... DONE"
22621
22622         # compare content
22623         cmp $tmp $dom || error "file miscompare"
22624
22625         return 0
22626 }
22627 run_test 271d "DoM: read on open (1K file in reply buffer)"
22628
22629 test_271f() {
22630         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22631                 skip "Need MDS version at least 2.10.57"
22632
22633         local dom=$DIR/$tdir/dom
22634         local tmp=$TMP/$tfile
22635         trap "cleanup_271def_tests $tmp" EXIT
22636
22637         mkdir -p $DIR/$tdir
22638
22639         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22640
22641         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22642
22643         cancel_lru_locks mdc
22644         dd if=/dev/urandom of=$tmp bs=265000 count=1
22645         dd if=$tmp of=$dom bs=265000 count=1
22646         cancel_lru_locks mdc
22647         cat /etc/hosts >> $tmp
22648         lctl set_param -n mdc.*.stats=clear
22649
22650         echo "Append to the same page"
22651         cat /etc/hosts >> $dom
22652         local num=$(get_mdc_stats $mdtidx ost_read)
22653         local ra=$(get_mdc_stats $mdtidx req_active)
22654         local rw=$(get_mdc_stats $mdtidx req_waittime)
22655
22656         [ -z $num ] || error "$num READ RPC occured"
22657         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22658         echo "... DONE"
22659
22660         # compare content
22661         cmp $tmp $dom || error "file miscompare"
22662
22663         cancel_lru_locks mdc
22664         lctl set_param -n mdc.*.stats=clear
22665
22666         echo "Open and read file"
22667         cat $dom > /dev/null
22668         local num=$(get_mdc_stats $mdtidx ost_read)
22669         local ra=$(get_mdc_stats $mdtidx req_active)
22670         local rw=$(get_mdc_stats $mdtidx req_waittime)
22671
22672         [ -z $num ] && num=0
22673         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22674         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22675         echo "... DONE"
22676
22677         # compare content
22678         cmp $tmp $dom || error "file miscompare"
22679
22680         return 0
22681 }
22682 run_test 271f "DoM: read on open (200K file and read tail)"
22683
22684 test_271g() {
22685         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22686                 skip "Skipping due to old client or server version"
22687
22688         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22689         # to get layout
22690         $CHECKSTAT -t file $DIR1/$tfile
22691
22692         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22693         MULTIOP_PID=$!
22694         sleep 1
22695         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22696         $LCTL set_param fail_loc=0x80000314
22697         rm $DIR1/$tfile || error "Unlink fails"
22698         RC=$?
22699         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22700         [ $RC -eq 0 ] || error "Failed write to stale object"
22701 }
22702 run_test 271g "Discard DoM data vs client flush race"
22703
22704 test_272a() {
22705         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22706                 skip "Need MDS version at least 2.11.50"
22707
22708         local dom=$DIR/$tdir/dom
22709         mkdir -p $DIR/$tdir
22710
22711         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22712         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22713                 error "failed to write data into $dom"
22714         local old_md5=$(md5sum $dom)
22715
22716         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22717                 error "failed to migrate to the same DoM component"
22718
22719         local new_md5=$(md5sum $dom)
22720
22721         [ "$old_md5" == "$new_md5" ] ||
22722                 error "md5sum differ: $old_md5, $new_md5"
22723
22724         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22725                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22726 }
22727 run_test 272a "DoM migration: new layout with the same DOM component"
22728
22729 test_272b() {
22730         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22731                 skip "Need MDS version at least 2.11.50"
22732
22733         local dom=$DIR/$tdir/dom
22734         mkdir -p $DIR/$tdir
22735         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22736
22737         local mdtidx=$($LFS getstripe -m $dom)
22738         local mdtname=MDT$(printf %04x $mdtidx)
22739         local facet=mds$((mdtidx + 1))
22740
22741         local mdtfree1=$(do_facet $facet \
22742                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22743         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22744                 error "failed to write data into $dom"
22745         local old_md5=$(md5sum $dom)
22746         cancel_lru_locks mdc
22747         local mdtfree1=$(do_facet $facet \
22748                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22749
22750         $LFS migrate -c2 $dom ||
22751                 error "failed to migrate to the new composite layout"
22752         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22753                 error "MDT stripe was not removed"
22754
22755         cancel_lru_locks mdc
22756         local new_md5=$(md5sum $dom)
22757         [ "$old_md5" == "$new_md5" ] ||
22758                 error "$old_md5 != $new_md5"
22759
22760         # Skip free space checks with ZFS
22761         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22762                 local mdtfree2=$(do_facet $facet \
22763                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22764                 [ $mdtfree2 -gt $mdtfree1 ] ||
22765                         error "MDT space is not freed after migration"
22766         fi
22767         return 0
22768 }
22769 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22770
22771 test_272c() {
22772         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22773                 skip "Need MDS version at least 2.11.50"
22774
22775         local dom=$DIR/$tdir/$tfile
22776         mkdir -p $DIR/$tdir
22777         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22778
22779         local mdtidx=$($LFS getstripe -m $dom)
22780         local mdtname=MDT$(printf %04x $mdtidx)
22781         local facet=mds$((mdtidx + 1))
22782
22783         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22784                 error "failed to write data into $dom"
22785         local old_md5=$(md5sum $dom)
22786         cancel_lru_locks mdc
22787         local mdtfree1=$(do_facet $facet \
22788                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22789
22790         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22791                 error "failed to migrate to the new composite layout"
22792         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22793                 error "MDT stripe was not removed"
22794
22795         cancel_lru_locks mdc
22796         local new_md5=$(md5sum $dom)
22797         [ "$old_md5" == "$new_md5" ] ||
22798                 error "$old_md5 != $new_md5"
22799
22800         # Skip free space checks with ZFS
22801         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22802                 local mdtfree2=$(do_facet $facet \
22803                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22804                 [ $mdtfree2 -gt $mdtfree1 ] ||
22805                         error "MDS space is not freed after migration"
22806         fi
22807         return 0
22808 }
22809 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22810
22811 test_272d() {
22812         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22813                 skip "Need MDS version at least 2.12.55"
22814
22815         local dom=$DIR/$tdir/$tfile
22816         mkdir -p $DIR/$tdir
22817         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22818
22819         local mdtidx=$($LFS getstripe -m $dom)
22820         local mdtname=MDT$(printf %04x $mdtidx)
22821         local facet=mds$((mdtidx + 1))
22822
22823         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22824                 error "failed to write data into $dom"
22825         local old_md5=$(md5sum $dom)
22826         cancel_lru_locks mdc
22827         local mdtfree1=$(do_facet $facet \
22828                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22829
22830         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22831                 error "failed mirroring to the new composite layout"
22832         $LFS mirror resync $dom ||
22833                 error "failed mirror resync"
22834         $LFS mirror split --mirror-id 1 -d $dom ||
22835                 error "failed mirror split"
22836
22837         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22838                 error "MDT stripe was not removed"
22839
22840         cancel_lru_locks mdc
22841         local new_md5=$(md5sum $dom)
22842         [ "$old_md5" == "$new_md5" ] ||
22843                 error "$old_md5 != $new_md5"
22844
22845         # Skip free space checks with ZFS
22846         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22847                 local mdtfree2=$(do_facet $facet \
22848                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22849                 [ $mdtfree2 -gt $mdtfree1 ] ||
22850                         error "MDS space is not freed after DOM mirror deletion"
22851         fi
22852         return 0
22853 }
22854 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22855
22856 test_272e() {
22857         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22858                 skip "Need MDS version at least 2.12.55"
22859
22860         local dom=$DIR/$tdir/$tfile
22861         mkdir -p $DIR/$tdir
22862         $LFS setstripe -c 2 $dom
22863
22864         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22865                 error "failed to write data into $dom"
22866         local old_md5=$(md5sum $dom)
22867         cancel_lru_locks
22868
22869         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22870                 error "failed mirroring to the DOM layout"
22871         $LFS mirror resync $dom ||
22872                 error "failed mirror resync"
22873         $LFS mirror split --mirror-id 1 -d $dom ||
22874                 error "failed mirror split"
22875
22876         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22877                 error "MDT stripe wasn't set"
22878
22879         cancel_lru_locks
22880         local new_md5=$(md5sum $dom)
22881         [ "$old_md5" == "$new_md5" ] ||
22882                 error "$old_md5 != $new_md5"
22883
22884         return 0
22885 }
22886 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22887
22888 test_272f() {
22889         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22890                 skip "Need MDS version at least 2.12.55"
22891
22892         local dom=$DIR/$tdir/$tfile
22893         mkdir -p $DIR/$tdir
22894         $LFS setstripe -c 2 $dom
22895
22896         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22897                 error "failed to write data into $dom"
22898         local old_md5=$(md5sum $dom)
22899         cancel_lru_locks
22900
22901         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22902                 error "failed migrating to the DOM file"
22903
22904         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22905                 error "MDT stripe wasn't set"
22906
22907         cancel_lru_locks
22908         local new_md5=$(md5sum $dom)
22909         [ "$old_md5" != "$new_md5" ] &&
22910                 error "$old_md5 != $new_md5"
22911
22912         return 0
22913 }
22914 run_test 272f "DoM migration: OST-striped file to DOM file"
22915
22916 test_273a() {
22917         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22918                 skip "Need MDS version at least 2.11.50"
22919
22920         # Layout swap cannot be done if either file has DOM component,
22921         # this will never be supported, migration should be used instead
22922
22923         local dom=$DIR/$tdir/$tfile
22924         mkdir -p $DIR/$tdir
22925
22926         $LFS setstripe -c2 ${dom}_plain
22927         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22928         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22929                 error "can swap layout with DoM component"
22930         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22931                 error "can swap layout with DoM component"
22932
22933         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22934         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22935                 error "can swap layout with DoM component"
22936         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22937                 error "can swap layout with DoM component"
22938         return 0
22939 }
22940 run_test 273a "DoM: layout swapping should fail with DOM"
22941
22942 test_273b() {
22943         mkdir -p $DIR/$tdir
22944         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22945
22946 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22947         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22948
22949         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22950 }
22951 run_test 273b "DoM: race writeback and object destroy"
22952
22953 test_275() {
22954         remote_ost_nodsh && skip "remote OST with nodsh"
22955         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22956                 skip "Need OST version >= 2.10.57"
22957
22958         local file=$DIR/$tfile
22959         local oss
22960
22961         oss=$(comma_list $(osts_nodes))
22962
22963         dd if=/dev/urandom of=$file bs=1M count=2 ||
22964                 error "failed to create a file"
22965         cancel_lru_locks osc
22966
22967         #lock 1
22968         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22969                 error "failed to read a file"
22970
22971 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22972         $LCTL set_param fail_loc=0x8000031f
22973
22974         cancel_lru_locks osc &
22975         sleep 1
22976
22977 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22978         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22979         #IO takes another lock, but matches the PENDING one
22980         #and places it to the IO RPC
22981         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22982                 error "failed to read a file with PENDING lock"
22983 }
22984 run_test 275 "Read on a canceled duplicate lock"
22985
22986 test_276() {
22987         remote_ost_nodsh && skip "remote OST with nodsh"
22988         local pid
22989
22990         do_facet ost1 "(while true; do \
22991                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22992                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22993         pid=$!
22994
22995         for LOOP in $(seq 20); do
22996                 stop ost1
22997                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22998         done
22999         kill -9 $pid
23000         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23001                 rm $TMP/sanity_276_pid"
23002 }
23003 run_test 276 "Race between mount and obd_statfs"
23004
23005 test_277() {
23006         $LCTL set_param ldlm.namespaces.*.lru_size=0
23007         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23008         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23009                         grep ^used_mb | awk '{print $2}')
23010         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23011         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23012                 oflag=direct conv=notrunc
23013         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23014                         grep ^used_mb | awk '{print $2}')
23015         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23016 }
23017 run_test 277 "Direct IO shall drop page cache"
23018
23019 test_278() {
23020         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23021         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23022         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23023                 skip "needs the same host for mdt1 mdt2" && return
23024
23025         local pid1
23026         local pid2
23027
23028 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23029         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23030         stop mds2 &
23031         pid2=$!
23032
23033         stop mds1
23034
23035         echo "Starting MDTs"
23036         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23037         wait $pid2
23038 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23039 #will return NULL
23040         do_facet mds2 $LCTL set_param fail_loc=0
23041
23042         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23043         wait_recovery_complete mds2
23044 }
23045 run_test 278 "Race starting MDS between MDTs stop/start"
23046
23047 test_280() {
23048         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23049                 skip "Need MGS version at least 2.13.52"
23050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23051         combined_mgs_mds || skip "needs combined MGS/MDT"
23052
23053         umount_client $MOUNT
23054 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23055         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23056
23057         mount_client $MOUNT &
23058         sleep 1
23059         stop mgs || error "stop mgs failed"
23060         #for a race mgs would crash
23061         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23062         # make sure we unmount client before remounting
23063         wait
23064         umount_client $MOUNT
23065         mount_client $MOUNT || error "mount client failed"
23066 }
23067 run_test 280 "Race between MGS umount and client llog processing"
23068
23069 cleanup_test_300() {
23070         trap 0
23071         umask $SAVE_UMASK
23072 }
23073 test_striped_dir() {
23074         local mdt_index=$1
23075         local stripe_count
23076         local stripe_index
23077
23078         mkdir -p $DIR/$tdir
23079
23080         SAVE_UMASK=$(umask)
23081         trap cleanup_test_300 RETURN EXIT
23082
23083         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23084                                                 $DIR/$tdir/striped_dir ||
23085                 error "set striped dir error"
23086
23087         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23088         [ "$mode" = "755" ] || error "expect 755 got $mode"
23089
23090         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23091                 error "getdirstripe failed"
23092         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23093         if [ "$stripe_count" != "2" ]; then
23094                 error "1:stripe_count is $stripe_count, expect 2"
23095         fi
23096         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23097         if [ "$stripe_count" != "2" ]; then
23098                 error "2:stripe_count is $stripe_count, expect 2"
23099         fi
23100
23101         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23102         if [ "$stripe_index" != "$mdt_index" ]; then
23103                 error "stripe_index is $stripe_index, expect $mdt_index"
23104         fi
23105
23106         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23107                 error "nlink error after create striped dir"
23108
23109         mkdir $DIR/$tdir/striped_dir/a
23110         mkdir $DIR/$tdir/striped_dir/b
23111
23112         stat $DIR/$tdir/striped_dir/a ||
23113                 error "create dir under striped dir failed"
23114         stat $DIR/$tdir/striped_dir/b ||
23115                 error "create dir under striped dir failed"
23116
23117         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23118                 error "nlink error after mkdir"
23119
23120         rmdir $DIR/$tdir/striped_dir/a
23121         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23122                 error "nlink error after rmdir"
23123
23124         rmdir $DIR/$tdir/striped_dir/b
23125         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23126                 error "nlink error after rmdir"
23127
23128         chattr +i $DIR/$tdir/striped_dir
23129         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23130                 error "immutable flags not working under striped dir!"
23131         chattr -i $DIR/$tdir/striped_dir
23132
23133         rmdir $DIR/$tdir/striped_dir ||
23134                 error "rmdir striped dir error"
23135
23136         cleanup_test_300
23137
23138         true
23139 }
23140
23141 test_300a() {
23142         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23143                 skip "skipped for lustre < 2.7.0"
23144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23145         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23146
23147         test_striped_dir 0 || error "failed on striped dir on MDT0"
23148         test_striped_dir 1 || error "failed on striped dir on MDT0"
23149 }
23150 run_test 300a "basic striped dir sanity test"
23151
23152 test_300b() {
23153         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23154                 skip "skipped for lustre < 2.7.0"
23155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23156         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23157
23158         local i
23159         local mtime1
23160         local mtime2
23161         local mtime3
23162
23163         test_mkdir $DIR/$tdir || error "mkdir fail"
23164         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23165                 error "set striped dir error"
23166         for i in {0..9}; do
23167                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23168                 sleep 1
23169                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23170                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23171                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23172                 sleep 1
23173                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23174                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23175                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23176         done
23177         true
23178 }
23179 run_test 300b "check ctime/mtime for striped dir"
23180
23181 test_300c() {
23182         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23183                 skip "skipped for lustre < 2.7.0"
23184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23185         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23186
23187         local file_count
23188
23189         mkdir_on_mdt0 $DIR/$tdir
23190         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23191                 error "set striped dir error"
23192
23193         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23194                 error "chown striped dir failed"
23195
23196         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23197                 error "create 5k files failed"
23198
23199         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23200
23201         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23202
23203         rm -rf $DIR/$tdir
23204 }
23205 run_test 300c "chown && check ls under striped directory"
23206
23207 test_300d() {
23208         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23209                 skip "skipped for lustre < 2.7.0"
23210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23211         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23212
23213         local stripe_count
23214         local file
23215
23216         mkdir -p $DIR/$tdir
23217         $LFS setstripe -c 2 $DIR/$tdir
23218
23219         #local striped directory
23220         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23221                 error "set striped dir error"
23222         #look at the directories for debug purposes
23223         ls -l $DIR/$tdir
23224         $LFS getdirstripe $DIR/$tdir
23225         ls -l $DIR/$tdir/striped_dir
23226         $LFS getdirstripe $DIR/$tdir/striped_dir
23227         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23228                 error "create 10 files failed"
23229
23230         #remote striped directory
23231         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23232                 error "set striped dir error"
23233         #look at the directories for debug purposes
23234         ls -l $DIR/$tdir
23235         $LFS getdirstripe $DIR/$tdir
23236         ls -l $DIR/$tdir/remote_striped_dir
23237         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23238         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23239                 error "create 10 files failed"
23240
23241         for file in $(find $DIR/$tdir); do
23242                 stripe_count=$($LFS getstripe -c $file)
23243                 [ $stripe_count -eq 2 ] ||
23244                         error "wrong stripe $stripe_count for $file"
23245         done
23246
23247         rm -rf $DIR/$tdir
23248 }
23249 run_test 300d "check default stripe under striped directory"
23250
23251 test_300e() {
23252         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23253                 skip "Need MDS version at least 2.7.55"
23254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23255         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23256
23257         local stripe_count
23258         local file
23259
23260         mkdir -p $DIR/$tdir
23261
23262         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23263                 error "set striped dir error"
23264
23265         touch $DIR/$tdir/striped_dir/a
23266         touch $DIR/$tdir/striped_dir/b
23267         touch $DIR/$tdir/striped_dir/c
23268
23269         mkdir $DIR/$tdir/striped_dir/dir_a
23270         mkdir $DIR/$tdir/striped_dir/dir_b
23271         mkdir $DIR/$tdir/striped_dir/dir_c
23272
23273         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23274                 error "set striped adir under striped dir error"
23275
23276         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23277                 error "set striped bdir under striped dir error"
23278
23279         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23280                 error "set striped cdir under striped dir error"
23281
23282         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23283                 error "rename dir under striped dir fails"
23284
23285         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23286                 error "rename dir under different stripes fails"
23287
23288         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23289                 error "rename file under striped dir should succeed"
23290
23291         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23292                 error "rename dir under striped dir should succeed"
23293
23294         rm -rf $DIR/$tdir
23295 }
23296 run_test 300e "check rename under striped directory"
23297
23298 test_300f() {
23299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23300         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23301         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23302                 skip "Need MDS version at least 2.7.55"
23303
23304         local stripe_count
23305         local file
23306
23307         rm -rf $DIR/$tdir
23308         mkdir -p $DIR/$tdir
23309
23310         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23311                 error "set striped dir error"
23312
23313         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23314                 error "set striped dir error"
23315
23316         touch $DIR/$tdir/striped_dir/a
23317         mkdir $DIR/$tdir/striped_dir/dir_a
23318         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23319                 error "create striped dir under striped dir fails"
23320
23321         touch $DIR/$tdir/striped_dir1/b
23322         mkdir $DIR/$tdir/striped_dir1/dir_b
23323         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23324                 error "create striped dir under striped dir fails"
23325
23326         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23327                 error "rename dir under different striped dir should fail"
23328
23329         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23330                 error "rename striped dir under diff striped dir should fail"
23331
23332         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23333                 error "rename file under diff striped dirs fails"
23334
23335         rm -rf $DIR/$tdir
23336 }
23337 run_test 300f "check rename cross striped directory"
23338
23339 test_300_check_default_striped_dir()
23340 {
23341         local dirname=$1
23342         local default_count=$2
23343         local default_index=$3
23344         local stripe_count
23345         local stripe_index
23346         local dir_stripe_index
23347         local dir
23348
23349         echo "checking $dirname $default_count $default_index"
23350         $LFS setdirstripe -D -c $default_count -i $default_index \
23351                                 -H all_char $DIR/$tdir/$dirname ||
23352                 error "set default stripe on striped dir error"
23353         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23354         [ $stripe_count -eq $default_count ] ||
23355                 error "expect $default_count get $stripe_count for $dirname"
23356
23357         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23358         [ $stripe_index -eq $default_index ] ||
23359                 error "expect $default_index get $stripe_index for $dirname"
23360
23361         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23362                                                 error "create dirs failed"
23363
23364         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23365         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23366         for dir in $(find $DIR/$tdir/$dirname/*); do
23367                 stripe_count=$($LFS getdirstripe -c $dir)
23368                 (( $stripe_count == $default_count )) ||
23369                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23370                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23371                 error "stripe count $default_count != $stripe_count for $dir"
23372
23373                 stripe_index=$($LFS getdirstripe -i $dir)
23374                 [ $default_index -eq -1 ] ||
23375                         [ $stripe_index -eq $default_index ] ||
23376                         error "$stripe_index != $default_index for $dir"
23377
23378                 #check default stripe
23379                 stripe_count=$($LFS getdirstripe -D -c $dir)
23380                 [ $stripe_count -eq $default_count ] ||
23381                 error "default count $default_count != $stripe_count for $dir"
23382
23383                 stripe_index=$($LFS getdirstripe -D -i $dir)
23384                 [ $stripe_index -eq $default_index ] ||
23385                 error "default index $default_index != $stripe_index for $dir"
23386         done
23387         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23388 }
23389
23390 test_300g() {
23391         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23392         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23393                 skip "Need MDS version at least 2.7.55"
23394
23395         local dir
23396         local stripe_count
23397         local stripe_index
23398
23399         mkdir_on_mdt0 $DIR/$tdir
23400         mkdir $DIR/$tdir/normal_dir
23401
23402         #Checking when client cache stripe index
23403         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23404         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23405                 error "create striped_dir failed"
23406
23407         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23408                 error "create dir0 fails"
23409         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23410         [ $stripe_index -eq 0 ] ||
23411                 error "dir0 expect index 0 got $stripe_index"
23412
23413         mkdir $DIR/$tdir/striped_dir/dir1 ||
23414                 error "create dir1 fails"
23415         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23416         [ $stripe_index -eq 1 ] ||
23417                 error "dir1 expect index 1 got $stripe_index"
23418
23419         #check default stripe count/stripe index
23420         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23421         test_300_check_default_striped_dir normal_dir 1 0
23422         test_300_check_default_striped_dir normal_dir -1 1
23423         test_300_check_default_striped_dir normal_dir 2 -1
23424
23425         #delete default stripe information
23426         echo "delete default stripeEA"
23427         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23428                 error "set default stripe on striped dir error"
23429
23430         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23431         for dir in $(find $DIR/$tdir/normal_dir/*); do
23432                 stripe_count=$($LFS getdirstripe -c $dir)
23433                 [ $stripe_count -eq 0 ] ||
23434                         error "expect 1 get $stripe_count for $dir"
23435         done
23436 }
23437 run_test 300g "check default striped directory for normal directory"
23438
23439 test_300h() {
23440         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23441         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23442                 skip "Need MDS version at least 2.7.55"
23443
23444         local dir
23445         local stripe_count
23446
23447         mkdir $DIR/$tdir
23448         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23449                 error "set striped dir error"
23450
23451         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23452         test_300_check_default_striped_dir striped_dir 1 0
23453         test_300_check_default_striped_dir striped_dir -1 1
23454         test_300_check_default_striped_dir striped_dir 2 -1
23455
23456         #delete default stripe information
23457         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23458                 error "set default stripe on striped dir error"
23459
23460         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23461         for dir in $(find $DIR/$tdir/striped_dir/*); do
23462                 stripe_count=$($LFS getdirstripe -c $dir)
23463                 [ $stripe_count -eq 0 ] ||
23464                         error "expect 1 get $stripe_count for $dir"
23465         done
23466 }
23467 run_test 300h "check default striped directory for striped directory"
23468
23469 test_300i() {
23470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23471         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23472         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23473                 skip "Need MDS version at least 2.7.55"
23474
23475         local stripe_count
23476         local file
23477
23478         mkdir $DIR/$tdir
23479
23480         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23481                 error "set striped dir error"
23482
23483         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23484                 error "create files under striped dir failed"
23485
23486         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23487                 error "set striped hashdir error"
23488
23489         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23490                 error "create dir0 under hash dir failed"
23491         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23492                 error "create dir1 under hash dir failed"
23493         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23494                 error "create dir2 under hash dir failed"
23495
23496         # unfortunately, we need to umount to clear dir layout cache for now
23497         # once we fully implement dir layout, we can drop this
23498         umount_client $MOUNT || error "umount failed"
23499         mount_client $MOUNT || error "mount failed"
23500
23501         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23502         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23503         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23504
23505         #set the stripe to be unknown hash type
23506         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23507         $LCTL set_param fail_loc=0x1901
23508         for ((i = 0; i < 10; i++)); do
23509                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23510                         error "stat f-$i failed"
23511                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23512         done
23513
23514         touch $DIR/$tdir/striped_dir/f0 &&
23515                 error "create under striped dir with unknown hash should fail"
23516
23517         $LCTL set_param fail_loc=0
23518
23519         umount_client $MOUNT || error "umount failed"
23520         mount_client $MOUNT || error "mount failed"
23521
23522         return 0
23523 }
23524 run_test 300i "client handle unknown hash type striped directory"
23525
23526 test_300j() {
23527         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23529         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23530                 skip "Need MDS version at least 2.7.55"
23531
23532         local stripe_count
23533         local file
23534
23535         mkdir $DIR/$tdir
23536
23537         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23538         $LCTL set_param fail_loc=0x1702
23539         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23540                 error "set striped dir error"
23541
23542         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23543                 error "create files under striped dir failed"
23544
23545         $LCTL set_param fail_loc=0
23546
23547         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23548
23549         return 0
23550 }
23551 run_test 300j "test large update record"
23552
23553 test_300k() {
23554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23555         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23556         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23557                 skip "Need MDS version at least 2.7.55"
23558
23559         # this test needs a huge transaction
23560         local kb
23561         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23562              osd*.$FSNAME-MDT0000.kbytestotal")
23563         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23564
23565         local stripe_count
23566         local file
23567
23568         mkdir $DIR/$tdir
23569
23570         #define OBD_FAIL_LARGE_STRIPE   0x1703
23571         $LCTL set_param fail_loc=0x1703
23572         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23573                 error "set striped dir error"
23574         $LCTL set_param fail_loc=0
23575
23576         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23577                 error "getstripeddir fails"
23578         rm -rf $DIR/$tdir/striped_dir ||
23579                 error "unlink striped dir fails"
23580
23581         return 0
23582 }
23583 run_test 300k "test large striped directory"
23584
23585 test_300l() {
23586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23587         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23588         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23589                 skip "Need MDS version at least 2.7.55"
23590
23591         local stripe_index
23592
23593         test_mkdir -p $DIR/$tdir/striped_dir
23594         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23595                         error "chown $RUNAS_ID failed"
23596         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23597                 error "set default striped dir failed"
23598
23599         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23600         $LCTL set_param fail_loc=0x80000158
23601         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23602
23603         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23604         [ $stripe_index -eq 1 ] ||
23605                 error "expect 1 get $stripe_index for $dir"
23606 }
23607 run_test 300l "non-root user to create dir under striped dir with stale layout"
23608
23609 test_300m() {
23610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23611         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23612         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23613                 skip "Need MDS version at least 2.7.55"
23614
23615         mkdir -p $DIR/$tdir/striped_dir
23616         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23617                 error "set default stripes dir error"
23618
23619         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23620
23621         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23622         [ $stripe_count -eq 0 ] ||
23623                         error "expect 0 get $stripe_count for a"
23624
23625         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23626                 error "set default stripes dir error"
23627
23628         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23629
23630         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23631         [ $stripe_count -eq 0 ] ||
23632                         error "expect 0 get $stripe_count for b"
23633
23634         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23635                 error "set default stripes dir error"
23636
23637         mkdir $DIR/$tdir/striped_dir/c &&
23638                 error "default stripe_index is invalid, mkdir c should fails"
23639
23640         rm -rf $DIR/$tdir || error "rmdir fails"
23641 }
23642 run_test 300m "setstriped directory on single MDT FS"
23643
23644 cleanup_300n() {
23645         local list=$(comma_list $(mdts_nodes))
23646
23647         trap 0
23648         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23649 }
23650
23651 test_300n() {
23652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23653         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23654         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23655                 skip "Need MDS version at least 2.7.55"
23656         remote_mds_nodsh && skip "remote MDS with nodsh"
23657
23658         local stripe_index
23659         local list=$(comma_list $(mdts_nodes))
23660
23661         trap cleanup_300n RETURN EXIT
23662         mkdir -p $DIR/$tdir
23663         chmod 777 $DIR/$tdir
23664         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23665                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23666                 error "create striped dir succeeds with gid=0"
23667
23668         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23669         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23670                 error "create striped dir fails with gid=-1"
23671
23672         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23673         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23674                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23675                 error "set default striped dir succeeds with gid=0"
23676
23677
23678         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23679         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23680                 error "set default striped dir fails with gid=-1"
23681
23682
23683         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23684         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23685                                         error "create test_dir fails"
23686         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23687                                         error "create test_dir1 fails"
23688         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23689                                         error "create test_dir2 fails"
23690         cleanup_300n
23691 }
23692 run_test 300n "non-root user to create dir under striped dir with default EA"
23693
23694 test_300o() {
23695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23696         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23697         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23698                 skip "Need MDS version at least 2.7.55"
23699
23700         local numfree1
23701         local numfree2
23702
23703         mkdir -p $DIR/$tdir
23704
23705         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23706         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23707         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23708                 skip "not enough free inodes $numfree1 $numfree2"
23709         fi
23710
23711         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23712         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23713         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23714                 skip "not enough free space $numfree1 $numfree2"
23715         fi
23716
23717         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23718                 error "setdirstripe fails"
23719
23720         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23721                 error "create dirs fails"
23722
23723         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23724         ls $DIR/$tdir/striped_dir > /dev/null ||
23725                 error "ls striped dir fails"
23726         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23727                 error "unlink big striped dir fails"
23728 }
23729 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23730
23731 test_300p() {
23732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23733         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23734         remote_mds_nodsh && skip "remote MDS with nodsh"
23735
23736         mkdir_on_mdt0 $DIR/$tdir
23737
23738         #define OBD_FAIL_OUT_ENOSPC     0x1704
23739         do_facet mds2 lctl set_param fail_loc=0x80001704
23740         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23741                  && error "create striped directory should fail"
23742
23743         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23744
23745         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23746         true
23747 }
23748 run_test 300p "create striped directory without space"
23749
23750 test_300q() {
23751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23752         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23753
23754         local fd=$(free_fd)
23755         local cmd="exec $fd<$tdir"
23756         cd $DIR
23757         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23758         eval $cmd
23759         cmd="exec $fd<&-"
23760         trap "eval $cmd" EXIT
23761         cd $tdir || error "cd $tdir fails"
23762         rmdir  ../$tdir || error "rmdir $tdir fails"
23763         mkdir local_dir && error "create dir succeeds"
23764         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23765         eval $cmd
23766         return 0
23767 }
23768 run_test 300q "create remote directory under orphan directory"
23769
23770 test_300r() {
23771         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23772                 skip "Need MDS version at least 2.7.55" && return
23773         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23774
23775         mkdir $DIR/$tdir
23776
23777         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23778                 error "set striped dir error"
23779
23780         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23781                 error "getstripeddir fails"
23782
23783         local stripe_count
23784         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23785                       awk '/lmv_stripe_count:/ { print $2 }')
23786
23787         [ $MDSCOUNT -ne $stripe_count ] &&
23788                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23789
23790         rm -rf $DIR/$tdir/striped_dir ||
23791                 error "unlink striped dir fails"
23792 }
23793 run_test 300r "test -1 striped directory"
23794
23795 test_300s_helper() {
23796         local count=$1
23797
23798         local stripe_dir=$DIR/$tdir/striped_dir.$count
23799
23800         $LFS mkdir -c $count $stripe_dir ||
23801                 error "lfs mkdir -c error"
23802
23803         $LFS getdirstripe $stripe_dir ||
23804                 error "lfs getdirstripe fails"
23805
23806         local stripe_count
23807         stripe_count=$($LFS getdirstripe $stripe_dir |
23808                       awk '/lmv_stripe_count:/ { print $2 }')
23809
23810         [ $count -ne $stripe_count ] &&
23811                 error_noexit "bad stripe count $stripe_count expected $count"
23812
23813         local dupe_stripes
23814         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23815                 awk '/0x/ {count[$1] += 1}; END {
23816                         for (idx in count) {
23817                                 if (count[idx]>1) {
23818                                         print "index " idx " count " count[idx]
23819                                 }
23820                         }
23821                 }')
23822
23823         if [[ -n "$dupe_stripes" ]] ; then
23824                 lfs getdirstripe $stripe_dir
23825                 error_noexit "Dupe MDT above: $dupe_stripes "
23826         fi
23827
23828         rm -rf $stripe_dir ||
23829                 error_noexit "unlink $stripe_dir fails"
23830 }
23831
23832 test_300s() {
23833         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23834                 skip "Need MDS version at least 2.7.55" && return
23835         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23836
23837         mkdir $DIR/$tdir
23838         for count in $(seq 2 $MDSCOUNT); do
23839                 test_300s_helper $count
23840         done
23841 }
23842 run_test 300s "test lfs mkdir -c without -i"
23843
23844 test_300t() {
23845         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
23846                 skip "need MDS 2.14.55 or later"
23847         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
23848
23849         local testdir="$DIR/$tdir/striped_dir"
23850         local dir1=$testdir/dir1
23851         local dir2=$testdir/dir2
23852
23853         mkdir -p $testdir
23854
23855         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
23856                 error "failed to set default stripe count for $testdir"
23857
23858         mkdir $dir1
23859         local stripe_count=$($LFS getdirstripe -c $dir1)
23860
23861         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
23862
23863         local max_count=$((MDSCOUNT - 1))
23864         local mdts=$(comma_list $(mdts_nodes))
23865
23866         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
23867         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
23868
23869         mkdir $dir2
23870         stripe_count=$($LFS getdirstripe -c $dir2)
23871
23872         (( $stripe_count == $max_count )) || error "wrong stripe count"
23873 }
23874 run_test 300t "test max_mdt_stripecount"
23875
23876 prepare_remote_file() {
23877         mkdir $DIR/$tdir/src_dir ||
23878                 error "create remote source failed"
23879
23880         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23881                  error "cp to remote source failed"
23882         touch $DIR/$tdir/src_dir/a
23883
23884         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23885                 error "create remote target dir failed"
23886
23887         touch $DIR/$tdir/tgt_dir/b
23888
23889         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23890                 error "rename dir cross MDT failed!"
23891
23892         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23893                 error "src_child still exists after rename"
23894
23895         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23896                 error "missing file(a) after rename"
23897
23898         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23899                 error "diff after rename"
23900 }
23901
23902 test_310a() {
23903         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
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         #open-unlink file
23913         $OPENUNLINK $remote_file $remote_file ||
23914                 error "openunlink $remote_file failed"
23915         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23916 }
23917 run_test 310a "open unlink remote file"
23918
23919 test_310b() {
23920         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23922
23923         local remote_file=$DIR/$tdir/tgt_dir/b
23924
23925         mkdir -p $DIR/$tdir
23926
23927         prepare_remote_file || error "prepare remote file failed"
23928
23929         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23930         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23931         $CHECKSTAT -t file $remote_file || error "check file failed"
23932 }
23933 run_test 310b "unlink remote file with multiple links while open"
23934
23935 test_310c() {
23936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23937         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23938
23939         local remote_file=$DIR/$tdir/tgt_dir/b
23940
23941         mkdir -p $DIR/$tdir
23942
23943         prepare_remote_file || error "prepare remote file failed"
23944
23945         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23946         multiop_bg_pause $remote_file O_uc ||
23947                         error "mulitop failed for remote file"
23948         MULTIPID=$!
23949         $MULTIOP $DIR/$tfile Ouc
23950         kill -USR1 $MULTIPID
23951         wait $MULTIPID
23952 }
23953 run_test 310c "open-unlink remote file with multiple links"
23954
23955 #LU-4825
23956 test_311() {
23957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23958         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23959         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23960                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23961         remote_mds_nodsh && skip "remote MDS with nodsh"
23962
23963         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23964         local mdts=$(comma_list $(mdts_nodes))
23965
23966         mkdir -p $DIR/$tdir
23967         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23968         createmany -o $DIR/$tdir/$tfile. 1000
23969
23970         # statfs data is not real time, let's just calculate it
23971         old_iused=$((old_iused + 1000))
23972
23973         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23974                         osp.*OST0000*MDT0000.create_count")
23975         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23976                                 osp.*OST0000*MDT0000.max_create_count")
23977         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23978
23979         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23980         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23981         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23982
23983         unlinkmany $DIR/$tdir/$tfile. 1000
23984
23985         do_nodes $mdts "$LCTL set_param -n \
23986                         osp.*OST0000*.max_create_count=$max_count"
23987         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23988                 do_nodes $mdts "$LCTL set_param -n \
23989                                 osp.*OST0000*.create_count=$count"
23990         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23991                         grep "=0" && error "create_count is zero"
23992
23993         local new_iused
23994         for i in $(seq 120); do
23995                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23996                 # system may be too busy to destroy all objs in time, use
23997                 # a somewhat small value to not fail autotest
23998                 [ $((old_iused - new_iused)) -gt 400 ] && break
23999                 sleep 1
24000         done
24001
24002         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24003         [ $((old_iused - new_iused)) -gt 400 ] ||
24004                 error "objs not destroyed after unlink"
24005 }
24006 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24007
24008 zfs_oid_to_objid()
24009 {
24010         local ost=$1
24011         local objid=$2
24012
24013         local vdevdir=$(dirname $(facet_vdevice $ost))
24014         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24015         local zfs_zapid=$(do_facet $ost $cmd |
24016                           grep -w "/O/0/d$((objid%32))" -C 5 |
24017                           awk '/Object/{getline; print $1}')
24018         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24019                           awk "/$objid = /"'{printf $3}')
24020
24021         echo $zfs_objid
24022 }
24023
24024 zfs_object_blksz() {
24025         local ost=$1
24026         local objid=$2
24027
24028         local vdevdir=$(dirname $(facet_vdevice $ost))
24029         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24030         local blksz=$(do_facet $ost $cmd $objid |
24031                       awk '/dblk/{getline; printf $4}')
24032
24033         case "${blksz: -1}" in
24034                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24035                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24036                 *) ;;
24037         esac
24038
24039         echo $blksz
24040 }
24041
24042 test_312() { # LU-4856
24043         remote_ost_nodsh && skip "remote OST with nodsh"
24044         [ "$ost1_FSTYPE" = "zfs" ] ||
24045                 skip_env "the test only applies to zfs"
24046
24047         local max_blksz=$(do_facet ost1 \
24048                           $ZFS get -p recordsize $(facet_device ost1) |
24049                           awk '!/VALUE/{print $3}')
24050
24051         # to make life a little bit easier
24052         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24053         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24054
24055         local tf=$DIR/$tdir/$tfile
24056         touch $tf
24057         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24058
24059         # Get ZFS object id
24060         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24061         # block size change by sequential overwrite
24062         local bs
24063
24064         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24065                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24066
24067                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24068                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24069         done
24070         rm -f $tf
24071
24072         # block size change by sequential append write
24073         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24074         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24075         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24076         local count
24077
24078         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24079                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24080                         oflag=sync conv=notrunc
24081
24082                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24083                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24084                         error "blksz error, actual $blksz, " \
24085                                 "expected: 2 * $count * $PAGE_SIZE"
24086         done
24087         rm -f $tf
24088
24089         # random write
24090         touch $tf
24091         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24092         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24093
24094         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24095         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24096         [ $blksz -eq $PAGE_SIZE ] ||
24097                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24098
24099         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24100         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24101         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24102
24103         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24104         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24105         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24106 }
24107 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24108
24109 test_313() {
24110         remote_ost_nodsh && skip "remote OST with nodsh"
24111
24112         local file=$DIR/$tfile
24113
24114         rm -f $file
24115         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24116
24117         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24118         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24119         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24120                 error "write should failed"
24121         do_facet ost1 "$LCTL set_param fail_loc=0"
24122         rm -f $file
24123 }
24124 run_test 313 "io should fail after last_rcvd update fail"
24125
24126 test_314() {
24127         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24128
24129         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24130         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24131         rm -f $DIR/$tfile
24132         wait_delete_completed
24133         do_facet ost1 "$LCTL set_param fail_loc=0"
24134 }
24135 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24136
24137 test_315() { # LU-618
24138         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24139
24140         local file=$DIR/$tfile
24141         rm -f $file
24142
24143         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24144                 error "multiop file write failed"
24145         $MULTIOP $file oO_RDONLY:r4063232_c &
24146         PID=$!
24147
24148         sleep 2
24149
24150         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24151         kill -USR1 $PID
24152
24153         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24154         rm -f $file
24155 }
24156 run_test 315 "read should be accounted"
24157
24158 test_316() {
24159         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24160         large_xattr_enabled || skip "ea_inode feature disabled"
24161
24162         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24163         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24164         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24165         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24166
24167         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24168 }
24169 run_test 316 "lfs migrate of file with large_xattr enabled"
24170
24171 test_317() {
24172         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24173                 skip "Need MDS version at least 2.11.53"
24174         if [ "$ost1_FSTYPE" == "zfs" ]; then
24175                 skip "LU-10370: no implementation for ZFS"
24176         fi
24177
24178         local trunc_sz
24179         local grant_blk_size
24180
24181         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24182                         awk '/grant_block_size:/ { print $2; exit; }')
24183         #
24184         # Create File of size 5M. Truncate it to below size's and verify
24185         # blocks count.
24186         #
24187         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24188                 error "Create file $DIR/$tfile failed"
24189         stack_trap "rm -f $DIR/$tfile" EXIT
24190
24191         for trunc_sz in 2097152 4097 4000 509 0; do
24192                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24193                         error "truncate $tfile to $trunc_sz failed"
24194                 local sz=$(stat --format=%s $DIR/$tfile)
24195                 local blk=$(stat --format=%b $DIR/$tfile)
24196                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24197                                      grant_blk_size) * 8))
24198
24199                 if [[ $blk -ne $trunc_blk ]]; then
24200                         $(which stat) $DIR/$tfile
24201                         error "Expected Block $trunc_blk got $blk for $tfile"
24202                 fi
24203
24204                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24205                         error "Expected Size $trunc_sz got $sz for $tfile"
24206         done
24207
24208         #
24209         # sparse file test
24210         # Create file with a hole and write actual 65536 bytes which aligned
24211         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24212         #
24213         local bs=65536
24214         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24215                 error "Create file : $DIR/$tfile"
24216
24217         #
24218         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24219         # blocks. The block count must drop to 8.
24220         #
24221         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24222                 ((bs - grant_blk_size) + 1)))
24223         $TRUNCATE $DIR/$tfile $trunc_sz ||
24224                 error "truncate $tfile to $trunc_sz failed"
24225
24226         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24227         sz=$(stat --format=%s $DIR/$tfile)
24228         blk=$(stat --format=%b $DIR/$tfile)
24229
24230         if [[ $blk -ne $trunc_bsz ]]; then
24231                 $(which stat) $DIR/$tfile
24232                 error "Expected Block $trunc_bsz got $blk for $tfile"
24233         fi
24234
24235         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24236                 error "Expected Size $trunc_sz got $sz for $tfile"
24237 }
24238 run_test 317 "Verify blocks get correctly update after truncate"
24239
24240 test_318() {
24241         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24242         local old_max_active=$($LCTL get_param -n \
24243                             ${llite_name}.max_read_ahead_async_active \
24244                             2>/dev/null)
24245
24246         $LCTL set_param llite.*.max_read_ahead_async_active=256
24247         local max_active=$($LCTL get_param -n \
24248                            ${llite_name}.max_read_ahead_async_active \
24249                            2>/dev/null)
24250         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24251
24252         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24253                 error "set max_read_ahead_async_active should succeed"
24254
24255         $LCTL set_param llite.*.max_read_ahead_async_active=512
24256         max_active=$($LCTL get_param -n \
24257                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24258         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24259
24260         # restore @max_active
24261         [ $old_max_active -ne 0 ] && $LCTL set_param \
24262                 llite.*.max_read_ahead_async_active=$old_max_active
24263
24264         local old_threshold=$($LCTL get_param -n \
24265                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24266         local max_per_file_mb=$($LCTL get_param -n \
24267                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24268
24269         local invalid=$(($max_per_file_mb + 1))
24270         $LCTL set_param \
24271                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24272                         && error "set $invalid should fail"
24273
24274         local valid=$(($invalid - 1))
24275         $LCTL set_param \
24276                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24277                         error "set $valid should succeed"
24278         local threshold=$($LCTL get_param -n \
24279                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24280         [ $threshold -eq $valid ] || error \
24281                 "expect threshold $valid got $threshold"
24282         $LCTL set_param \
24283                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24284 }
24285 run_test 318 "Verify async readahead tunables"
24286
24287 test_319() {
24288         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24289
24290         local before=$(date +%s)
24291         local evict
24292         local mdir=$DIR/$tdir
24293         local file=$mdir/xxx
24294
24295         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24296         touch $file
24297
24298 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24299         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24300         $LFS migrate -m1 $mdir &
24301
24302         sleep 1
24303         dd if=$file of=/dev/null
24304         wait
24305         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24306           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24307
24308         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24309 }
24310 run_test 319 "lost lease lock on migrate error"
24311
24312 test_398a() { # LU-4198
24313         local ost1_imp=$(get_osc_import_name client ost1)
24314         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24315                          cut -d'.' -f2)
24316
24317         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24318         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24319
24320         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24321         # request a new lock on client
24322         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24323
24324         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24325         #local lock_count=$($LCTL get_param -n \
24326         #                  ldlm.namespaces.$imp_name.lru_size)
24327         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24328
24329         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24330
24331         # no lock cached, should use lockless DIO and not enqueue new lock
24332         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24333                 conv=notrunc ||
24334                 error "dio write failed"
24335         lock_count=$($LCTL get_param -n \
24336                      ldlm.namespaces.$imp_name.lru_size)
24337         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24338
24339         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24340
24341         # no lock cached, should use locked DIO append
24342         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24343                 conv=notrunc || error "DIO append failed"
24344         lock_count=$($LCTL get_param -n \
24345                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24346         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24347 }
24348 run_test 398a "direct IO should cancel lock otherwise lockless"
24349
24350 test_398b() { # LU-4198
24351         which fio || skip_env "no fio installed"
24352         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24353
24354         local size=48
24355         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24356
24357         local njobs=4
24358         # Single page, multiple pages, stripe size, 4*stripe size
24359         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24360                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24361                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24362                         --numjobs=$njobs --fallocate=none \
24363                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24364                         --filename=$DIR/$tfile &
24365                 bg_pid=$!
24366
24367                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24368                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24369                         --numjobs=$njobs --fallocate=none \
24370                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24371                         --filename=$DIR/$tfile || true
24372                 wait $bg_pid
24373         done
24374
24375         evict=$(do_facet client $LCTL get_param \
24376                 osc.$FSNAME-OST*-osc-*/state |
24377             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24378
24379         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24380                 (do_facet client $LCTL get_param \
24381                         osc.$FSNAME-OST*-osc-*/state;
24382                     error "eviction happened: $evict before:$before")
24383
24384         rm -f $DIR/$tfile
24385 }
24386 run_test 398b "DIO and buffer IO race"
24387
24388 test_398c() { # LU-4198
24389         local ost1_imp=$(get_osc_import_name client ost1)
24390         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24391                          cut -d'.' -f2)
24392
24393         which fio || skip_env "no fio installed"
24394
24395         saved_debug=$($LCTL get_param -n debug)
24396         $LCTL set_param debug=0
24397
24398         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24399         ((size /= 1024)) # by megabytes
24400         ((size /= 2)) # write half of the OST at most
24401         [ $size -gt 40 ] && size=40 #reduce test time anyway
24402
24403         $LFS setstripe -c 1 $DIR/$tfile
24404
24405         # it seems like ldiskfs reserves more space than necessary if the
24406         # writing blocks are not mapped, so it extends the file firstly
24407         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24408         cancel_lru_locks osc
24409
24410         # clear and verify rpc_stats later
24411         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24412
24413         local njobs=4
24414         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24415         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24416                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24417                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24418                 --filename=$DIR/$tfile
24419         [ $? -eq 0 ] || error "fio write error"
24420
24421         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24422                 error "Locks were requested while doing AIO"
24423
24424         # get the percentage of 1-page I/O
24425         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24426                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24427                 awk '{print $7}')
24428         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24429
24430         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24431         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24432                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24433                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24434                 --filename=$DIR/$tfile
24435         [ $? -eq 0 ] || error "fio mixed read write error"
24436
24437         echo "AIO with large block size ${size}M"
24438         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24439                 --numjobs=1 --fallocate=none --ioengine=libaio \
24440                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24441                 --filename=$DIR/$tfile
24442         [ $? -eq 0 ] || error "fio large block size failed"
24443
24444         rm -f $DIR/$tfile
24445         $LCTL set_param debug="$saved_debug"
24446 }
24447 run_test 398c "run fio to test AIO"
24448
24449 test_398d() { #  LU-13846
24450         which aiocp || skip_env "no aiocp installed"
24451         local aio_file=$DIR/$tfile.aio
24452
24453         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24454
24455         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24456         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24457         stack_trap "rm -f $DIR/$tfile $aio_file"
24458
24459         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24460
24461         # make sure we don't crash and fail properly
24462         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24463                 error "aio not aligned with PAGE SIZE should fail"
24464
24465         rm -f $DIR/$tfile $aio_file
24466 }
24467 run_test 398d "run aiocp to verify block size > stripe size"
24468
24469 test_398e() {
24470         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24471         touch $DIR/$tfile.new
24472         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24473 }
24474 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24475
24476 test_398f() { #  LU-14687
24477         which aiocp || skip_env "no aiocp installed"
24478         local aio_file=$DIR/$tfile.aio
24479
24480         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24481
24482         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24483         stack_trap "rm -f $DIR/$tfile $aio_file"
24484
24485         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24486         $LCTL set_param fail_loc=0x1418
24487         # make sure we don't crash and fail properly
24488         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24489                 error "aio with page allocation failure succeeded"
24490         $LCTL set_param fail_loc=0
24491         diff $DIR/$tfile $aio_file
24492         [[ $? != 0 ]] || error "no diff after failed aiocp"
24493 }
24494 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24495
24496 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24497 # stripe and i/o size must be > stripe size
24498 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24499 # single RPC in flight.  This test shows async DIO submission is working by
24500 # showing multiple RPCs in flight.
24501 test_398g() { #  LU-13798
24502         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24503
24504         # We need to do some i/o first to acquire enough grant to put our RPCs
24505         # in flight; otherwise a new connection may not have enough grant
24506         # available
24507         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24508                 error "parallel dio failed"
24509         stack_trap "rm -f $DIR/$tfile"
24510
24511         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24512         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24513         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24514         stack_trap "$LCTL set_param -n $pages_per_rpc"
24515
24516         # Recreate file so it's empty
24517         rm -f $DIR/$tfile
24518         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24519         #Pause rpc completion to guarantee we see multiple rpcs in flight
24520         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24521         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24522         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24523
24524         # Clear rpc stats
24525         $LCTL set_param osc.*.rpc_stats=c
24526
24527         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24528                 error "parallel dio failed"
24529         stack_trap "rm -f $DIR/$tfile"
24530
24531         $LCTL get_param osc.*-OST0000-*.rpc_stats
24532         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24533                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24534                 grep "8:" | awk '{print $8}')
24535         # We look at the "8 rpcs in flight" field, and verify A) it is present
24536         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24537         # as expected for an 8M DIO to a file with 1M stripes.
24538         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24539
24540         # Verify turning off parallel dio works as expected
24541         # Clear rpc stats
24542         $LCTL set_param osc.*.rpc_stats=c
24543         $LCTL set_param llite.*.parallel_dio=0
24544         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24545
24546         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24547                 error "dio with parallel dio disabled failed"
24548
24549         # Ideally, we would see only one RPC in flight here, but there is an
24550         # unavoidable race between i/o completion and RPC in flight counting,
24551         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24552         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24553         # So instead we just verify it's always < 8.
24554         $LCTL get_param osc.*-OST0000-*.rpc_stats
24555         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24556                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24557                 grep '^$' -B1 | grep . | awk '{print $1}')
24558         [ $ret != "8:" ] ||
24559                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24560 }
24561 run_test 398g "verify parallel dio async RPC submission"
24562
24563 test_398h() { #  LU-13798
24564         local dio_file=$DIR/$tfile.dio
24565
24566         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24567
24568         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24569         stack_trap "rm -f $DIR/$tfile $dio_file"
24570
24571         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24572                 error "parallel dio failed"
24573         diff $DIR/$tfile $dio_file
24574         [[ $? == 0 ]] || error "file diff after aiocp"
24575 }
24576 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24577
24578 test_398i() { #  LU-13798
24579         local dio_file=$DIR/$tfile.dio
24580
24581         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24582
24583         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24584         stack_trap "rm -f $DIR/$tfile $dio_file"
24585
24586         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24587         $LCTL set_param fail_loc=0x1418
24588         # make sure we don't crash and fail properly
24589         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24590                 error "parallel dio page allocation failure succeeded"
24591         diff $DIR/$tfile $dio_file
24592         [[ $? != 0 ]] || error "no diff after failed aiocp"
24593 }
24594 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24595
24596 test_398j() { #  LU-13798
24597         # Stripe size > RPC size but less than i/o size tests split across
24598         # stripes and RPCs for individual i/o op
24599         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24600
24601         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24602         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24603         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24604         stack_trap "$LCTL set_param -n $pages_per_rpc"
24605
24606         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24607                 error "parallel dio write failed"
24608         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24609
24610         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24611                 error "parallel dio read failed"
24612         diff $DIR/$tfile $DIR/$tfile.2
24613         [[ $? == 0 ]] || error "file diff after parallel dio read"
24614 }
24615 run_test 398j "test parallel dio where stripe size > rpc_size"
24616
24617 test_398k() { #  LU-13798
24618         wait_delete_completed
24619         wait_mds_ost_sync
24620
24621         # 4 stripe file; we will cause out of space on OST0
24622         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24623
24624         # Fill OST0 (if it's not too large)
24625         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24626                    head -n1)
24627         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24628                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24629         fi
24630         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24631         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24632                 error "dd should fill OST0"
24633         stack_trap "rm -f $DIR/$tfile.1"
24634
24635         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24636         err=$?
24637
24638         ls -la $DIR/$tfile
24639         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24640                 error "file is not 0 bytes in size"
24641
24642         # dd above should not succeed, but don't error until here so we can
24643         # get debug info above
24644         [[ $err != 0 ]] ||
24645                 error "parallel dio write with enospc succeeded"
24646         stack_trap "rm -f $DIR/$tfile"
24647 }
24648 run_test 398k "test enospc on first stripe"
24649
24650 test_398l() { #  LU-13798
24651         wait_delete_completed
24652         wait_mds_ost_sync
24653
24654         # 4 stripe file; we will cause out of space on OST0
24655         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24656         # happens on the second i/o chunk we issue
24657         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24658
24659         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24660         stack_trap "rm -f $DIR/$tfile"
24661
24662         # Fill OST0 (if it's not too large)
24663         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24664                    head -n1)
24665         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24666                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24667         fi
24668         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24669         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24670                 error "dd should fill OST0"
24671         stack_trap "rm -f $DIR/$tfile.1"
24672
24673         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24674         err=$?
24675         stack_trap "rm -f $DIR/$tfile.2"
24676
24677         # Check that short write completed as expected
24678         ls -la $DIR/$tfile.2
24679         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24680                 error "file is not 1M in size"
24681
24682         # dd above should not succeed, but don't error until here so we can
24683         # get debug info above
24684         [[ $err != 0 ]] ||
24685                 error "parallel dio write with enospc succeeded"
24686
24687         # Truncate source file to same length as output file and diff them
24688         $TRUNCATE $DIR/$tfile 1048576
24689         diff $DIR/$tfile $DIR/$tfile.2
24690         [[ $? == 0 ]] || error "data incorrect after short write"
24691 }
24692 run_test 398l "test enospc on intermediate stripe/RPC"
24693
24694 test_398m() { #  LU-13798
24695         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24696
24697         # Set up failure on OST0, the first stripe:
24698         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24699         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24700         # So this fail_val specifies OST0
24701         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24702         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24703
24704         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24705                 error "parallel dio write with failure on first stripe succeeded"
24706         stack_trap "rm -f $DIR/$tfile"
24707         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24708
24709         # Place data in file for read
24710         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24711                 error "parallel dio write failed"
24712
24713         # Fail read on OST0, first stripe
24714         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24715         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24716         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24717                 error "parallel dio read with error on first stripe succeeded"
24718         rm -f $DIR/$tfile.2
24719         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24720
24721         # Switch to testing on OST1, second stripe
24722         # Clear file contents, maintain striping
24723         echo > $DIR/$tfile
24724         # Set up failure on OST1, second stripe:
24725         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24726         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24727
24728         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24729                 error "parallel dio write with failure on first stripe succeeded"
24730         stack_trap "rm -f $DIR/$tfile"
24731         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24732
24733         # Place data in file for read
24734         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24735                 error "parallel dio write failed"
24736
24737         # Fail read on OST1, second stripe
24738         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24739         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24740         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24741                 error "parallel dio read with error on first stripe succeeded"
24742         rm -f $DIR/$tfile.2
24743         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24744 }
24745 run_test 398m "test RPC failures with parallel dio"
24746
24747 # Parallel submission of DIO should not cause problems for append, but it's
24748 # important to verify.
24749 test_398n() { #  LU-13798
24750         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24751
24752         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24753                 error "dd to create source file failed"
24754         stack_trap "rm -f $DIR/$tfile"
24755
24756         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24757                 error "parallel dio write with failure on second stripe succeeded"
24758         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24759         diff $DIR/$tfile $DIR/$tfile.1
24760         [[ $? == 0 ]] || error "data incorrect after append"
24761
24762 }
24763 run_test 398n "test append with parallel DIO"
24764
24765 test_fake_rw() {
24766         local read_write=$1
24767         if [ "$read_write" = "write" ]; then
24768                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24769         elif [ "$read_write" = "read" ]; then
24770                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24771         else
24772                 error "argument error"
24773         fi
24774
24775         # turn off debug for performance testing
24776         local saved_debug=$($LCTL get_param -n debug)
24777         $LCTL set_param debug=0
24778
24779         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24780
24781         # get ost1 size - $FSNAME-OST0000
24782         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24783         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24784         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24785
24786         if [ "$read_write" = "read" ]; then
24787                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24788         fi
24789
24790         local start_time=$(date +%s.%N)
24791         $dd_cmd bs=1M count=$blocks oflag=sync ||
24792                 error "real dd $read_write error"
24793         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24794
24795         if [ "$read_write" = "write" ]; then
24796                 rm -f $DIR/$tfile
24797         fi
24798
24799         # define OBD_FAIL_OST_FAKE_RW           0x238
24800         do_facet ost1 $LCTL set_param fail_loc=0x238
24801
24802         local start_time=$(date +%s.%N)
24803         $dd_cmd bs=1M count=$blocks oflag=sync ||
24804                 error "fake dd $read_write error"
24805         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24806
24807         if [ "$read_write" = "write" ]; then
24808                 # verify file size
24809                 cancel_lru_locks osc
24810                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24811                         error "$tfile size not $blocks MB"
24812         fi
24813         do_facet ost1 $LCTL set_param fail_loc=0
24814
24815         echo "fake $read_write $duration_fake vs. normal $read_write" \
24816                 "$duration in seconds"
24817         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24818                 error_not_in_vm "fake write is slower"
24819
24820         $LCTL set_param -n debug="$saved_debug"
24821         rm -f $DIR/$tfile
24822 }
24823 test_399a() { # LU-7655 for OST fake write
24824         remote_ost_nodsh && skip "remote OST with nodsh"
24825
24826         test_fake_rw write
24827 }
24828 run_test 399a "fake write should not be slower than normal write"
24829
24830 test_399b() { # LU-8726 for OST fake read
24831         remote_ost_nodsh && skip "remote OST with nodsh"
24832         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24833                 skip_env "ldiskfs only test"
24834         fi
24835
24836         test_fake_rw read
24837 }
24838 run_test 399b "fake read should not be slower than normal read"
24839
24840 test_400a() { # LU-1606, was conf-sanity test_74
24841         if ! which $CC > /dev/null 2>&1; then
24842                 skip_env "$CC is not installed"
24843         fi
24844
24845         local extra_flags=''
24846         local out=$TMP/$tfile
24847         local prefix=/usr/include/lustre
24848         local prog
24849
24850         # Oleg removes c files in his test rig so test if any c files exist
24851         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24852                 skip_env "Needed c test files are missing"
24853
24854         if ! [[ -d $prefix ]]; then
24855                 # Assume we're running in tree and fixup the include path.
24856                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24857                 extra_flags+=" -L$LUSTRE/utils/.lib"
24858         fi
24859
24860         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24861                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24862                         error "client api broken"
24863         done
24864         rm -f $out
24865 }
24866 run_test 400a "Lustre client api program can compile and link"
24867
24868 test_400b() { # LU-1606, LU-5011
24869         local header
24870         local out=$TMP/$tfile
24871         local prefix=/usr/include/linux/lustre
24872
24873         # We use a hard coded prefix so that this test will not fail
24874         # when run in tree. There are headers in lustre/include/lustre/
24875         # that are not packaged (like lustre_idl.h) and have more
24876         # complicated include dependencies (like config.h and lnet/types.h).
24877         # Since this test about correct packaging we just skip them when
24878         # they don't exist (see below) rather than try to fixup cppflags.
24879
24880         if ! which $CC > /dev/null 2>&1; then
24881                 skip_env "$CC is not installed"
24882         fi
24883
24884         for header in $prefix/*.h; do
24885                 if ! [[ -f "$header" ]]; then
24886                         continue
24887                 fi
24888
24889                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24890                         continue # lustre_ioctl.h is internal header
24891                 fi
24892
24893                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24894                         error "cannot compile '$header'"
24895         done
24896         rm -f $out
24897 }
24898 run_test 400b "packaged headers can be compiled"
24899
24900 test_401a() { #LU-7437
24901         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24902         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24903
24904         #count the number of parameters by "list_param -R"
24905         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24906         #count the number of parameters by listing proc files
24907         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24908         echo "proc_dirs='$proc_dirs'"
24909         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24910         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24911                       sort -u | wc -l)
24912
24913         [ $params -eq $procs ] ||
24914                 error "found $params parameters vs. $procs proc files"
24915
24916         # test the list_param -D option only returns directories
24917         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24918         #count the number of parameters by listing proc directories
24919         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24920                 sort -u | wc -l)
24921
24922         [ $params -eq $procs ] ||
24923                 error "found $params parameters vs. $procs proc files"
24924 }
24925 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24926
24927 test_401b() {
24928         # jobid_var may not allow arbitrary values, so use jobid_name
24929         # if available
24930         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24931                 local testname=jobid_name tmp='testing%p'
24932         else
24933                 local testname=jobid_var tmp=testing
24934         fi
24935
24936         local save=$($LCTL get_param -n $testname)
24937
24938         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24939                 error "no error returned when setting bad parameters"
24940
24941         local jobid_new=$($LCTL get_param -n foe $testname baz)
24942         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24943
24944         $LCTL set_param -n fog=bam $testname=$save bat=fog
24945         local jobid_old=$($LCTL get_param -n foe $testname bag)
24946         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24947 }
24948 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24949
24950 test_401c() {
24951         # jobid_var may not allow arbitrary values, so use jobid_name
24952         # if available
24953         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24954                 local testname=jobid_name
24955         else
24956                 local testname=jobid_var
24957         fi
24958
24959         local jobid_var_old=$($LCTL get_param -n $testname)
24960         local jobid_var_new
24961
24962         $LCTL set_param $testname= &&
24963                 error "no error returned for 'set_param a='"
24964
24965         jobid_var_new=$($LCTL get_param -n $testname)
24966         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24967                 error "$testname was changed by setting without value"
24968
24969         $LCTL set_param $testname &&
24970                 error "no error returned for 'set_param a'"
24971
24972         jobid_var_new=$($LCTL get_param -n $testname)
24973         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24974                 error "$testname was changed by setting without value"
24975 }
24976 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24977
24978 test_401d() {
24979         # jobid_var may not allow arbitrary values, so use jobid_name
24980         # if available
24981         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24982                 local testname=jobid_name new_value='foo=bar%p'
24983         else
24984                 local testname=jobid_var new_valuie=foo=bar
24985         fi
24986
24987         local jobid_var_old=$($LCTL get_param -n $testname)
24988         local jobid_var_new
24989
24990         $LCTL set_param $testname=$new_value ||
24991                 error "'set_param a=b' did not accept a value containing '='"
24992
24993         jobid_var_new=$($LCTL get_param -n $testname)
24994         [[ "$jobid_var_new" == "$new_value" ]] ||
24995                 error "'set_param a=b' failed on a value containing '='"
24996
24997         # Reset the $testname to test the other format
24998         $LCTL set_param $testname=$jobid_var_old
24999         jobid_var_new=$($LCTL get_param -n $testname)
25000         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25001                 error "failed to reset $testname"
25002
25003         $LCTL set_param $testname $new_value ||
25004                 error "'set_param a b' did not accept a value containing '='"
25005
25006         jobid_var_new=$($LCTL get_param -n $testname)
25007         [[ "$jobid_var_new" == "$new_value" ]] ||
25008                 error "'set_param a b' failed on a value containing '='"
25009
25010         $LCTL set_param $testname $jobid_var_old
25011         jobid_var_new=$($LCTL get_param -n $testname)
25012         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25013                 error "failed to reset $testname"
25014 }
25015 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25016
25017 test_401e() { # LU-14779
25018         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25019                 error "lctl list_param MGC* failed"
25020         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25021         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25022                 error "lctl get_param lru_size failed"
25023 }
25024 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25025
25026 test_402() {
25027         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25028         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25029                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25030         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25031                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25032                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25033         remote_mds_nodsh && skip "remote MDS with nodsh"
25034
25035         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25036 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25037         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25038         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25039                 echo "Touch failed - OK"
25040 }
25041 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25042
25043 test_403() {
25044         local file1=$DIR/$tfile.1
25045         local file2=$DIR/$tfile.2
25046         local tfile=$TMP/$tfile
25047
25048         rm -f $file1 $file2 $tfile
25049
25050         touch $file1
25051         ln $file1 $file2
25052
25053         # 30 sec OBD_TIMEOUT in ll_getattr()
25054         # right before populating st_nlink
25055         $LCTL set_param fail_loc=0x80001409
25056         stat -c %h $file1 > $tfile &
25057
25058         # create an alias, drop all locks and reclaim the dentry
25059         < $file2
25060         cancel_lru_locks mdc
25061         cancel_lru_locks osc
25062         sysctl -w vm.drop_caches=2
25063
25064         wait
25065
25066         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25067
25068         rm -f $tfile $file1 $file2
25069 }
25070 run_test 403 "i_nlink should not drop to zero due to aliasing"
25071
25072 test_404() { # LU-6601
25073         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25074                 skip "Need server version newer than 2.8.52"
25075         remote_mds_nodsh && skip "remote MDS with nodsh"
25076
25077         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25078                 awk '/osp .*-osc-MDT/ { print $4}')
25079
25080         local osp
25081         for osp in $mosps; do
25082                 echo "Deactivate: " $osp
25083                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25084                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25085                         awk -vp=$osp '$4 == p { print $2 }')
25086                 [ $stat = IN ] || {
25087                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25088                         error "deactivate error"
25089                 }
25090                 echo "Activate: " $osp
25091                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25092                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25093                         awk -vp=$osp '$4 == p { print $2 }')
25094                 [ $stat = UP ] || {
25095                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25096                         error "activate error"
25097                 }
25098         done
25099 }
25100 run_test 404 "validate manual {de}activated works properly for OSPs"
25101
25102 test_405() {
25103         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25104         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25105                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25106                         skip "Layout swap lock is not supported"
25107
25108         check_swap_layouts_support
25109         check_swap_layout_no_dom $DIR
25110
25111         test_mkdir $DIR/$tdir
25112         swap_lock_test -d $DIR/$tdir ||
25113                 error "One layout swap locked test failed"
25114 }
25115 run_test 405 "Various layout swap lock tests"
25116
25117 test_406() {
25118         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25119         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25120         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25122         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25123                 skip "Need MDS version at least 2.8.50"
25124
25125         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25126         local test_pool=$TESTNAME
25127
25128         pool_add $test_pool || error "pool_add failed"
25129         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25130                 error "pool_add_targets failed"
25131
25132         save_layout_restore_at_exit $MOUNT
25133
25134         # parent set default stripe count only, child will stripe from both
25135         # parent and fs default
25136         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25137                 error "setstripe $MOUNT failed"
25138         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25139         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25140         for i in $(seq 10); do
25141                 local f=$DIR/$tdir/$tfile.$i
25142                 touch $f || error "touch failed"
25143                 local count=$($LFS getstripe -c $f)
25144                 [ $count -eq $OSTCOUNT ] ||
25145                         error "$f stripe count $count != $OSTCOUNT"
25146                 local offset=$($LFS getstripe -i $f)
25147                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25148                 local size=$($LFS getstripe -S $f)
25149                 [ $size -eq $((def_stripe_size * 2)) ] ||
25150                         error "$f stripe size $size != $((def_stripe_size * 2))"
25151                 local pool=$($LFS getstripe -p $f)
25152                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25153         done
25154
25155         # change fs default striping, delete parent default striping, now child
25156         # will stripe from new fs default striping only
25157         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25158                 error "change $MOUNT default stripe failed"
25159         $LFS setstripe -c 0 $DIR/$tdir ||
25160                 error "delete $tdir default stripe failed"
25161         for i in $(seq 11 20); do
25162                 local f=$DIR/$tdir/$tfile.$i
25163                 touch $f || error "touch $f failed"
25164                 local count=$($LFS getstripe -c $f)
25165                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25166                 local offset=$($LFS getstripe -i $f)
25167                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25168                 local size=$($LFS getstripe -S $f)
25169                 [ $size -eq $def_stripe_size ] ||
25170                         error "$f stripe size $size != $def_stripe_size"
25171                 local pool=$($LFS getstripe -p $f)
25172                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25173         done
25174
25175         unlinkmany $DIR/$tdir/$tfile. 1 20
25176
25177         local f=$DIR/$tdir/$tfile
25178         pool_remove_all_targets $test_pool $f
25179         pool_remove $test_pool $f
25180 }
25181 run_test 406 "DNE support fs default striping"
25182
25183 test_407() {
25184         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25185         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25186                 skip "Need MDS version at least 2.8.55"
25187         remote_mds_nodsh && skip "remote MDS with nodsh"
25188
25189         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25190                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25191         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25192                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25193         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25194
25195         #define OBD_FAIL_DT_TXN_STOP    0x2019
25196         for idx in $(seq $MDSCOUNT); do
25197                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25198         done
25199         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25200         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25201                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25202         true
25203 }
25204 run_test 407 "transaction fail should cause operation fail"
25205
25206 test_408() {
25207         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25208
25209         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25210         lctl set_param fail_loc=0x8000040a
25211         # let ll_prepare_partial_page() fail
25212         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25213
25214         rm -f $DIR/$tfile
25215
25216         # create at least 100 unused inodes so that
25217         # shrink_icache_memory(0) should not return 0
25218         touch $DIR/$tfile-{0..100}
25219         rm -f $DIR/$tfile-{0..100}
25220         sync
25221
25222         echo 2 > /proc/sys/vm/drop_caches
25223 }
25224 run_test 408 "drop_caches should not hang due to page leaks"
25225
25226 test_409()
25227 {
25228         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25229
25230         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25231         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25232         touch $DIR/$tdir/guard || error "(2) Fail to create"
25233
25234         local PREFIX=$(str_repeat 'A' 128)
25235         echo "Create 1K hard links start at $(date)"
25236         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25237                 error "(3) Fail to hard link"
25238
25239         echo "Links count should be right although linkEA overflow"
25240         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25241         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25242         [ $linkcount -eq 1001 ] ||
25243                 error "(5) Unexpected hard links count: $linkcount"
25244
25245         echo "List all links start at $(date)"
25246         ls -l $DIR/$tdir/foo > /dev/null ||
25247                 error "(6) Fail to list $DIR/$tdir/foo"
25248
25249         echo "Unlink hard links start at $(date)"
25250         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25251                 error "(7) Fail to unlink"
25252         echo "Unlink hard links finished at $(date)"
25253 }
25254 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25255
25256 test_410()
25257 {
25258         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25259                 skip "Need client version at least 2.9.59"
25260         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25261                 skip "Need MODULES build"
25262
25263         # Create a file, and stat it from the kernel
25264         local testfile=$DIR/$tfile
25265         touch $testfile
25266
25267         local run_id=$RANDOM
25268         local my_ino=$(stat --format "%i" $testfile)
25269
25270         # Try to insert the module. This will always fail as the
25271         # module is designed to not be inserted.
25272         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25273             &> /dev/null
25274
25275         # Anything but success is a test failure
25276         dmesg | grep -q \
25277             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25278             error "no inode match"
25279 }
25280 run_test 410 "Test inode number returned from kernel thread"
25281
25282 cleanup_test411_cgroup() {
25283         trap 0
25284         rmdir "$1"
25285 }
25286
25287 test_411() {
25288         local cg_basedir=/sys/fs/cgroup/memory
25289         # LU-9966
25290         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25291                 skip "no setup for cgroup"
25292
25293         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25294                 error "test file creation failed"
25295         cancel_lru_locks osc
25296
25297         # Create a very small memory cgroup to force a slab allocation error
25298         local cgdir=$cg_basedir/osc_slab_alloc
25299         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25300         trap "cleanup_test411_cgroup $cgdir" EXIT
25301         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25302         echo 1M > $cgdir/memory.limit_in_bytes
25303
25304         # Should not LBUG, just be killed by oom-killer
25305         # dd will return 0 even allocation failure in some environment.
25306         # So don't check return value
25307         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25308         cleanup_test411_cgroup $cgdir
25309
25310         return 0
25311 }
25312 run_test 411 "Slab allocation error with cgroup does not LBUG"
25313
25314 test_412() {
25315         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25316         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25317                 skip "Need server version at least 2.10.55"
25318
25319         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25320                 error "mkdir failed"
25321         $LFS getdirstripe $DIR/$tdir
25322         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25323         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25324                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25325         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25326         [ $stripe_count -eq 2 ] ||
25327                 error "expect 2 get $stripe_count"
25328
25329         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25330
25331         local index
25332         local index2
25333
25334         # subdirs should be on the same MDT as parent
25335         for i in $(seq 0 $((MDSCOUNT - 1))); do
25336                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25337                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25338                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25339                 (( index == i )) || error "mdt$i/sub on MDT$index"
25340         done
25341
25342         # stripe offset -1, ditto
25343         for i in {1..10}; do
25344                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25345                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25346                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25347                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25348                 (( index == index2 )) ||
25349                         error "qos$i on MDT$index, sub on MDT$index2"
25350         done
25351
25352         local testdir=$DIR/$tdir/inherit
25353
25354         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25355         # inherit 2 levels
25356         for i in 1 2; do
25357                 testdir=$testdir/s$i
25358                 mkdir $testdir || error "mkdir $testdir failed"
25359                 index=$($LFS getstripe -m $testdir)
25360                 (( index == 1 )) ||
25361                         error "$testdir on MDT$index"
25362         done
25363
25364         # not inherit any more
25365         testdir=$testdir/s3
25366         mkdir $testdir || error "mkdir $testdir failed"
25367         getfattr -d -m dmv $testdir | grep dmv &&
25368                 error "default LMV set on $testdir" || true
25369 }
25370 run_test 412 "mkdir on specific MDTs"
25371
25372 generate_uneven_mdts() {
25373         local threshold=$1
25374         local lmv_qos_maxage
25375         local lod_qos_maxage
25376         local ffree
25377         local bavail
25378         local max
25379         local min
25380         local max_index
25381         local min_index
25382         local tmp
25383         local i
25384
25385         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25386         $LCTL set_param lmv.*.qos_maxage=1
25387         stack_trap "$LCTL set_param \
25388                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25389         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25390                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25391         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25392                 lod.*.mdt_qos_maxage=1
25393         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25394                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25395
25396         echo
25397         echo "Check for uneven MDTs: "
25398
25399         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25400         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25401         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25402
25403         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25404         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25405         max_index=0
25406         min_index=0
25407         for ((i = 1; i < ${#ffree[@]}; i++)); do
25408                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25409                 if [ $tmp -gt $max ]; then
25410                         max=$tmp
25411                         max_index=$i
25412                 fi
25413                 if [ $tmp -lt $min ]; then
25414                         min=$tmp
25415                         min_index=$i
25416                 fi
25417         done
25418
25419         (( ${ffree[min_index]} > 0 )) ||
25420                 skip "no free files in MDT$min_index"
25421         (( ${ffree[min_index]} < 10000000 )) ||
25422                 skip "too many free files in MDT$min_index"
25423
25424         # Check if we need to generate uneven MDTs
25425         local diff=$(((max - min) * 100 / min))
25426         local testdir=$DIR/$tdir-fillmdt
25427         local start
25428
25429         mkdir -p $testdir
25430
25431         i=0
25432         while (( diff < threshold )); do
25433                 # generate uneven MDTs, create till $threshold% diff
25434                 echo -n "weight diff=$diff% must be > $threshold% ..."
25435                 echo "Fill MDT$min_index with 1000 files: loop $i"
25436                 testdir=$DIR/$tdir-fillmdt/$i
25437                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25438                         error "mkdir $testdir failed"
25439                 $LFS setstripe -E 1M -L mdt $testdir ||
25440                         error "setstripe $testdir failed"
25441                 start=$SECONDS
25442                 for F in f.{0..999}; do
25443                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25444                                 /dev/null 2>&1 || error "dd $F failed"
25445                 done
25446
25447                 # wait for QOS to update
25448                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25449
25450                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25451                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25452                 max=$(((${ffree[max_index]} >> 8) *
25453                         (${bavail[max_index]} * bsize >> 16)))
25454                 min=$(((${ffree[min_index]} >> 8) *
25455                         (${bavail[min_index]} * bsize >> 16)))
25456                 diff=$(((max - min) * 100 / min))
25457                 i=$((i + 1))
25458         done
25459
25460         echo "MDT filesfree available: ${ffree[*]}"
25461         echo "MDT blocks available: ${bavail[*]}"
25462         echo "weight diff=$diff%"
25463 }
25464
25465 test_qos_mkdir() {
25466         local mkdir_cmd=$1
25467         local stripe_count=$2
25468         local mdts=$(comma_list $(mdts_nodes))
25469
25470         local testdir
25471         local lmv_qos_prio_free
25472         local lmv_qos_threshold_rr
25473         local lmv_qos_maxage
25474         local lod_qos_prio_free
25475         local lod_qos_threshold_rr
25476         local lod_qos_maxage
25477         local count
25478         local i
25479
25480         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25481         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25482         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25483                 head -n1)
25484         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25485         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25486         stack_trap "$LCTL set_param \
25487                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25488         stack_trap "$LCTL set_param \
25489                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25490         stack_trap "$LCTL set_param \
25491                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25492
25493         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25494                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25495         lod_qos_prio_free=${lod_qos_prio_free%%%}
25496         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25497                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25498         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25499         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25500                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25501         stack_trap "do_nodes $mdts $LCTL set_param \
25502                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25503         stack_trap "do_nodes $mdts $LCTL set_param \
25504                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25505         stack_trap "do_nodes $mdts $LCTL set_param \
25506                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25507
25508         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25509         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25510
25511         testdir=$DIR/$tdir-s$stripe_count/rr
25512
25513         local stripe_index=$($LFS getstripe -m $testdir)
25514         local test_mkdir_rr=true
25515
25516         getfattr -d -m dmv -e hex $testdir | grep dmv
25517         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25518                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25519                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25520                         test_mkdir_rr=false
25521         fi
25522
25523         echo
25524         $test_mkdir_rr &&
25525                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25526                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25527
25528         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25529         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25530                 eval $mkdir_cmd $testdir/subdir$i ||
25531                         error "$mkdir_cmd subdir$i failed"
25532         done
25533
25534         for (( i = 0; i < $MDSCOUNT; i++ )); do
25535                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25536                 echo "$count directories created on MDT$i"
25537                 if $test_mkdir_rr; then
25538                         (( $count == 100 )) ||
25539                                 error "subdirs are not evenly distributed"
25540                 elif (( $i == $stripe_index )); then
25541                         (( $count == 100 * MDSCOUNT )) ||
25542                                 error "$count subdirs created on MDT$i"
25543                 else
25544                         (( $count == 0 )) ||
25545                                 error "$count subdirs created on MDT$i"
25546                 fi
25547
25548                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25549                         count=$($LFS getdirstripe $testdir/* |
25550                                 grep -c -P "^\s+$i\t")
25551                         echo "$count stripes created on MDT$i"
25552                         # deviation should < 5% of average
25553                         (( $count >= 95 * stripe_count &&
25554                            $count <= 105 * stripe_count)) ||
25555                                 error "stripes are not evenly distributed"
25556                 fi
25557         done
25558
25559         echo
25560         echo "Check for uneven MDTs: "
25561
25562         local ffree
25563         local bavail
25564         local max
25565         local min
25566         local max_index
25567         local min_index
25568         local tmp
25569
25570         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25571         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25572         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25573
25574         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25575         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25576         max_index=0
25577         min_index=0
25578         for ((i = 1; i < ${#ffree[@]}; i++)); do
25579                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25580                 if [ $tmp -gt $max ]; then
25581                         max=$tmp
25582                         max_index=$i
25583                 fi
25584                 if [ $tmp -lt $min ]; then
25585                         min=$tmp
25586                         min_index=$i
25587                 fi
25588         done
25589
25590         (( ${ffree[min_index]} > 0 )) ||
25591                 skip "no free files in MDT$min_index"
25592         (( ${ffree[min_index]} < 10000000 )) ||
25593                 skip "too many free files in MDT$min_index"
25594
25595         echo "MDT filesfree available: ${ffree[*]}"
25596         echo "MDT blocks available: ${bavail[*]}"
25597         echo "weight diff=$(((max - min) * 100 / min))%"
25598         echo
25599         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25600
25601         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25602         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25603         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25604         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25605         # decrease statfs age, so that it can be updated in time
25606         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25607         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25608
25609         sleep 1
25610
25611         testdir=$DIR/$tdir-s$stripe_count/qos
25612         local num=200
25613
25614         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25615         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25616                 eval $mkdir_cmd $testdir/subdir$i ||
25617                         error "$mkdir_cmd subdir$i failed"
25618         done
25619
25620         max=0
25621         for (( i = 0; i < $MDSCOUNT; i++ )); do
25622                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25623                 (( count > max )) && max=$count
25624                 echo "$count directories created on MDT$i"
25625         done
25626
25627         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25628
25629         # D-value should > 10% of averge
25630         (( max - min > num / 10 )) ||
25631                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25632
25633         # ditto for stripes
25634         if (( stripe_count > 1 )); then
25635                 max=0
25636                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25637                         count=$($LFS getdirstripe $testdir/* |
25638                                 grep -c -P "^\s+$i\t")
25639                         (( count > max )) && max=$count
25640                         echo "$count stripes created on MDT$i"
25641                 done
25642
25643                 min=$($LFS getdirstripe $testdir/* |
25644                         grep -c -P "^\s+$min_index\t")
25645                 (( max - min > num * stripe_count / 10 )) ||
25646                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25647         fi
25648 }
25649
25650 most_full_mdt() {
25651         local ffree
25652         local bavail
25653         local bsize
25654         local min
25655         local min_index
25656         local tmp
25657
25658         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25659         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25660         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25661
25662         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25663         min_index=0
25664         for ((i = 1; i < ${#ffree[@]}; i++)); do
25665                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25666                 (( tmp < min )) && min=$tmp && min_index=$i
25667         done
25668
25669         echo -n $min_index
25670 }
25671
25672 test_413a() {
25673         [ $MDSCOUNT -lt 2 ] &&
25674                 skip "We need at least 2 MDTs for this test"
25675
25676         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25677                 skip "Need server version at least 2.12.52"
25678
25679         local stripe_count
25680
25681         generate_uneven_mdts 100
25682         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25683                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25684                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25685                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25686                         error "mkdir failed"
25687                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25688         done
25689 }
25690 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25691
25692 test_413b() {
25693         [ $MDSCOUNT -lt 2 ] &&
25694                 skip "We need at least 2 MDTs for this test"
25695
25696         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25697                 skip "Need server version at least 2.12.52"
25698
25699         local testdir
25700         local stripe_count
25701
25702         generate_uneven_mdts 100
25703         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25704                 testdir=$DIR/$tdir-s$stripe_count
25705                 mkdir $testdir || error "mkdir $testdir failed"
25706                 mkdir $testdir/rr || error "mkdir rr failed"
25707                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25708                         error "mkdir qos failed"
25709                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25710                         $testdir/rr || error "setdirstripe rr failed"
25711                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25712                         error "setdirstripe failed"
25713                 test_qos_mkdir "mkdir" $stripe_count
25714         done
25715 }
25716 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25717
25718 test_413c() {
25719         (( $MDSCOUNT >= 2 )) ||
25720                 skip "We need at least 2 MDTs for this test"
25721
25722         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25723                 skip "Need server version at least 2.14.51"
25724
25725         local testdir
25726         local inherit
25727         local inherit_rr
25728
25729         testdir=$DIR/${tdir}-s1
25730         mkdir $testdir || error "mkdir $testdir failed"
25731         mkdir $testdir/rr || error "mkdir rr failed"
25732         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25733         # default max_inherit is -1, default max_inherit_rr is 0
25734         $LFS setdirstripe -D -c 1 $testdir/rr ||
25735                 error "setdirstripe rr failed"
25736         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25737                 error "setdirstripe qos failed"
25738         test_qos_mkdir "mkdir" 1
25739
25740         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25741         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25742         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25743         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25744         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25745
25746         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25747         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25748         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25749         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25750         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25751         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25752         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25753                 error "level2 shouldn't have default LMV" || true
25754 }
25755 run_test 413c "mkdir with default LMV max inherit rr"
25756
25757 test_413d() {
25758         (( MDSCOUNT >= 2 )) ||
25759                 skip "We need at least 2 MDTs for this test"
25760
25761         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25762                 skip "Need server version at least 2.14.51"
25763
25764         local lmv_qos_threshold_rr
25765
25766         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25767                 head -n1)
25768         stack_trap "$LCTL set_param \
25769                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25770
25771         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25772         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25773         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25774                 error "$tdir shouldn't have default LMV"
25775         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25776                 error "mkdir sub failed"
25777
25778         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25779
25780         (( count == 100 )) || error "$count subdirs on MDT0"
25781 }
25782 run_test 413d "inherit ROOT default LMV"
25783
25784 test_413e() {
25785         (( MDSCOUNT >= 2 )) ||
25786                 skip "We need at least 2 MDTs for this test"
25787         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25788                 skip "Need server version at least 2.14.55"
25789
25790         local testdir=$DIR/$tdir
25791         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25792         local max_inherit
25793         local sub_max_inherit
25794
25795         mkdir -p $testdir || error "failed to create $testdir"
25796
25797         # set default max-inherit to -1 if stripe count is 0 or 1
25798         $LFS setdirstripe -D -c 1 $testdir ||
25799                 error "failed to set default LMV"
25800         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25801         (( max_inherit == -1 )) ||
25802                 error "wrong max_inherit value $max_inherit"
25803
25804         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25805         $LFS setdirstripe -D -c -1 $testdir ||
25806                 error "failed to set default LMV"
25807         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25808         (( max_inherit > 0 )) ||
25809                 error "wrong max_inherit value $max_inherit"
25810
25811         # and the subdir will decrease the max_inherit by 1
25812         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25813         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
25814         (( sub_max_inherit == max_inherit - 1)) ||
25815                 error "wrong max-inherit of subdir $sub_max_inherit"
25816
25817         # check specified --max-inherit and warning message
25818         stack_trap "rm -f $tmpfile"
25819         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
25820                 error "failed to set default LMV"
25821         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25822         (( max_inherit == -1 )) ||
25823                 error "wrong max_inherit value $max_inherit"
25824
25825         # check the warning messages
25826         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
25827                 error "failed to detect warning string"
25828         fi
25829 }
25830 run_test 413e "check default max-inherit value"
25831
25832 test_fs_dmv_inherit()
25833 {
25834         local testdir=$DIR/$tdir
25835
25836         local count
25837         local inherit
25838         local inherit_rr
25839
25840         for i in 1 2 3; do
25841                 mkdir $testdir || error "mkdir $testdir failed"
25842                 count=$($LFS getdirstripe -D -c $testdir)
25843                 (( count == 1 )) ||
25844                         error "$testdir default LMV count mismatch $count != 1"
25845                 inherit=$($LFS getdirstripe -D -X $testdir)
25846                 (( inherit == 3 - i )) ||
25847                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
25848                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
25849                 (( inherit_rr == 3 - i )) ||
25850                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
25851                 testdir=$testdir/sub
25852         done
25853
25854         mkdir $testdir || error "mkdir $testdir failed"
25855         count=$($LFS getdirstripe -D -c $testdir)
25856         (( count == 0 )) ||
25857                 error "$testdir default LMV count not zero: $count"
25858 }
25859
25860 test_413f() {
25861         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
25862
25863         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25864                 skip "Need server version at least 2.14.55"
25865
25866         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
25867                 error "dump $DIR default LMV failed"
25868         stack_trap "setfattr --restore=$TMP/dmv.ea"
25869
25870         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
25871                 error "set $DIR default LMV failed"
25872
25873         test_fs_dmv_inherit
25874 }
25875 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
25876
25877 test_413g() {
25878         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
25879
25880         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
25881         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
25882                 error "dump $DIR default LMV failed"
25883         stack_trap "setfattr --restore=$TMP/dmv.ea"
25884
25885         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
25886                 error "set $DIR default LMV failed"
25887
25888         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
25889                 error "mount $MOUNT2 failed"
25890         stack_trap "umount_client $MOUNT2"
25891
25892         local saved_DIR=$DIR
25893
25894         export DIR=$MOUNT2
25895
25896         stack_trap "export DIR=$saved_DIR"
25897
25898         # first check filesystem-wide default LMV inheritance
25899         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
25900
25901         # then check subdirs are spread to all MDTs
25902         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
25903
25904         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
25905
25906         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
25907 }
25908 run_test 413g "enforce ROOT default LMV on subdir mount"
25909
25910 test_413z() {
25911         local pids=""
25912         local subdir
25913         local pid
25914
25915         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25916                 unlinkmany $subdir/f. 1000 &
25917                 pids="$pids $!"
25918         done
25919
25920         for pid in $pids; do
25921                 wait $pid
25922         done
25923 }
25924 run_test 413z "413 test cleanup"
25925
25926 test_414() {
25927 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25928         $LCTL set_param fail_loc=0x80000521
25929         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25930         rm -f $DIR/$tfile
25931 }
25932 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25933
25934 test_415() {
25935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25936         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25937                 skip "Need server version at least 2.11.52"
25938
25939         # LU-11102
25940         local total
25941         local setattr_pid
25942         local start_time
25943         local end_time
25944         local duration
25945
25946         total=500
25947         # this test may be slow on ZFS
25948         [ "$mds1_FSTYPE" == "zfs" ] && total=50
25949
25950         # though this test is designed for striped directory, let's test normal
25951         # directory too since lock is always saved as CoS lock.
25952         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25953         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25954
25955         (
25956                 while true; do
25957                         touch $DIR/$tdir
25958                 done
25959         ) &
25960         setattr_pid=$!
25961
25962         start_time=$(date +%s)
25963         for i in $(seq $total); do
25964                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25965                         > /dev/null
25966         done
25967         end_time=$(date +%s)
25968         duration=$((end_time - start_time))
25969
25970         kill -9 $setattr_pid
25971
25972         echo "rename $total files took $duration sec"
25973         [ $duration -lt 100 ] || error "rename took $duration sec"
25974 }
25975 run_test 415 "lock revoke is not missing"
25976
25977 test_416() {
25978         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25979                 skip "Need server version at least 2.11.55"
25980
25981         # define OBD_FAIL_OSD_TXN_START    0x19a
25982         do_facet mds1 lctl set_param fail_loc=0x19a
25983
25984         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25985
25986         true
25987 }
25988 run_test 416 "transaction start failure won't cause system hung"
25989
25990 cleanup_417() {
25991         trap 0
25992         do_nodes $(comma_list $(mdts_nodes)) \
25993                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25994         do_nodes $(comma_list $(mdts_nodes)) \
25995                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25996         do_nodes $(comma_list $(mdts_nodes)) \
25997                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25998 }
25999
26000 test_417() {
26001         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26002         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26003                 skip "Need MDS version at least 2.11.56"
26004
26005         trap cleanup_417 RETURN EXIT
26006
26007         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26008         do_nodes $(comma_list $(mdts_nodes)) \
26009                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26010         $LFS migrate -m 0 $DIR/$tdir.1 &&
26011                 error "migrate dir $tdir.1 should fail"
26012
26013         do_nodes $(comma_list $(mdts_nodes)) \
26014                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26015         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26016                 error "create remote dir $tdir.2 should fail"
26017
26018         do_nodes $(comma_list $(mdts_nodes)) \
26019                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26020         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26021                 error "create striped dir $tdir.3 should fail"
26022         true
26023 }
26024 run_test 417 "disable remote dir, striped dir and dir migration"
26025
26026 # Checks that the outputs of df [-i] and lfs df [-i] match
26027 #
26028 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26029 check_lfs_df() {
26030         local dir=$2
26031         local inodes
26032         local df_out
26033         local lfs_df_out
26034         local count
26035         local passed=false
26036
26037         # blocks or inodes
26038         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26039
26040         for count in {1..100}; do
26041                 do_nodes "$CLIENTS" \
26042                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26043                 sync; sleep 0.2
26044
26045                 # read the lines of interest
26046                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26047                         error "df $inodes $dir | tail -n +2 failed"
26048                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26049                         error "lfs df $inodes $dir | grep summary: failed"
26050
26051                 # skip first substrings of each output as they are different
26052                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26053                 # compare the two outputs
26054                 passed=true
26055                 #  skip "available" on MDT until LU-13997 is fixed.
26056                 #for i in {1..5}; do
26057                 for i in 1 2 4 5; do
26058                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26059                 done
26060                 $passed && break
26061         done
26062
26063         if ! $passed; then
26064                 df -P $inodes $dir
26065                 echo
26066                 lfs df $inodes $dir
26067                 error "df and lfs df $1 output mismatch: "      \
26068                       "df ${inodes}: ${df_out[*]}, "            \
26069                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26070         fi
26071 }
26072
26073 test_418() {
26074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26075
26076         local dir=$DIR/$tdir
26077         local numfiles=$((RANDOM % 4096 + 2))
26078         local numblocks=$((RANDOM % 256 + 1))
26079
26080         wait_delete_completed
26081         test_mkdir $dir
26082
26083         # check block output
26084         check_lfs_df blocks $dir
26085         # check inode output
26086         check_lfs_df inodes $dir
26087
26088         # create a single file and retest
26089         echo "Creating a single file and testing"
26090         createmany -o $dir/$tfile- 1 &>/dev/null ||
26091                 error "creating 1 file in $dir failed"
26092         check_lfs_df blocks $dir
26093         check_lfs_df inodes $dir
26094
26095         # create a random number of files
26096         echo "Creating $((numfiles - 1)) files and testing"
26097         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26098                 error "creating $((numfiles - 1)) files in $dir failed"
26099
26100         # write a random number of blocks to the first test file
26101         echo "Writing $numblocks 4K blocks and testing"
26102         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26103                 count=$numblocks &>/dev/null ||
26104                 error "dd to $dir/${tfile}-0 failed"
26105
26106         # retest
26107         check_lfs_df blocks $dir
26108         check_lfs_df inodes $dir
26109
26110         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26111                 error "unlinking $numfiles files in $dir failed"
26112 }
26113 run_test 418 "df and lfs df outputs match"
26114
26115 test_419()
26116 {
26117         local dir=$DIR/$tdir
26118
26119         mkdir -p $dir
26120         touch $dir/file
26121
26122         cancel_lru_locks mdc
26123
26124         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26125         $LCTL set_param fail_loc=0x1410
26126         cat $dir/file
26127         $LCTL set_param fail_loc=0
26128         rm -rf $dir
26129 }
26130 run_test 419 "Verify open file by name doesn't crash kernel"
26131
26132 test_420()
26133 {
26134         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26135                 skip "Need MDS version at least 2.12.53"
26136
26137         local SAVE_UMASK=$(umask)
26138         local dir=$DIR/$tdir
26139         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26140
26141         mkdir -p $dir
26142         umask 0000
26143         mkdir -m03777 $dir/testdir
26144         ls -dn $dir/testdir
26145         # Need to remove trailing '.' when SELinux is enabled
26146         local dirperms=$(ls -dn $dir/testdir |
26147                          awk '{ sub(/\.$/, "", $1); print $1}')
26148         [ $dirperms == "drwxrwsrwt" ] ||
26149                 error "incorrect perms on $dir/testdir"
26150
26151         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26152                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26153         ls -n $dir/testdir/testfile
26154         local fileperms=$(ls -n $dir/testdir/testfile |
26155                           awk '{ sub(/\.$/, "", $1); print $1}')
26156         [ $fileperms == "-rwxr-xr-x" ] ||
26157                 error "incorrect perms on $dir/testdir/testfile"
26158
26159         umask $SAVE_UMASK
26160 }
26161 run_test 420 "clear SGID bit on non-directories for non-members"
26162
26163 test_421a() {
26164         local cnt
26165         local fid1
26166         local fid2
26167
26168         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26169                 skip "Need MDS version at least 2.12.54"
26170
26171         test_mkdir $DIR/$tdir
26172         createmany -o $DIR/$tdir/f 3
26173         cnt=$(ls -1 $DIR/$tdir | wc -l)
26174         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26175
26176         fid1=$(lfs path2fid $DIR/$tdir/f1)
26177         fid2=$(lfs path2fid $DIR/$tdir/f2)
26178         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26179
26180         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26181         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26182
26183         cnt=$(ls -1 $DIR/$tdir | wc -l)
26184         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26185
26186         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26187         createmany -o $DIR/$tdir/f 3
26188         cnt=$(ls -1 $DIR/$tdir | wc -l)
26189         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26190
26191         fid1=$(lfs path2fid $DIR/$tdir/f1)
26192         fid2=$(lfs path2fid $DIR/$tdir/f2)
26193         echo "remove using fsname $FSNAME"
26194         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26195
26196         cnt=$(ls -1 $DIR/$tdir | wc -l)
26197         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26198 }
26199 run_test 421a "simple rm by fid"
26200
26201 test_421b() {
26202         local cnt
26203         local FID1
26204         local FID2
26205
26206         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26207                 skip "Need MDS version at least 2.12.54"
26208
26209         test_mkdir $DIR/$tdir
26210         createmany -o $DIR/$tdir/f 3
26211         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26212         MULTIPID=$!
26213
26214         FID1=$(lfs path2fid $DIR/$tdir/f1)
26215         FID2=$(lfs path2fid $DIR/$tdir/f2)
26216         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26217
26218         kill -USR1 $MULTIPID
26219         wait
26220
26221         cnt=$(ls $DIR/$tdir | wc -l)
26222         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26223 }
26224 run_test 421b "rm by fid on open file"
26225
26226 test_421c() {
26227         local cnt
26228         local FIDS
26229
26230         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26231                 skip "Need MDS version at least 2.12.54"
26232
26233         test_mkdir $DIR/$tdir
26234         createmany -o $DIR/$tdir/f 3
26235         touch $DIR/$tdir/$tfile
26236         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26237         cnt=$(ls -1 $DIR/$tdir | wc -l)
26238         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26239
26240         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26241         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26242
26243         cnt=$(ls $DIR/$tdir | wc -l)
26244         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26245 }
26246 run_test 421c "rm by fid against hardlinked files"
26247
26248 test_421d() {
26249         local cnt
26250         local FIDS
26251
26252         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26253                 skip "Need MDS version at least 2.12.54"
26254
26255         test_mkdir $DIR/$tdir
26256         createmany -o $DIR/$tdir/f 4097
26257         cnt=$(ls -1 $DIR/$tdir | wc -l)
26258         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26259
26260         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26261         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26262
26263         cnt=$(ls $DIR/$tdir | wc -l)
26264         rm -rf $DIR/$tdir
26265         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26266 }
26267 run_test 421d "rmfid en masse"
26268
26269 test_421e() {
26270         local cnt
26271         local FID
26272
26273         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26274         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26275                 skip "Need MDS version at least 2.12.54"
26276
26277         mkdir -p $DIR/$tdir
26278         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26279         createmany -o $DIR/$tdir/striped_dir/f 512
26280         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26281         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26282
26283         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26284                 sed "s/[/][^:]*://g")
26285         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26286
26287         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26288         rm -rf $DIR/$tdir
26289         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26290 }
26291 run_test 421e "rmfid in DNE"
26292
26293 test_421f() {
26294         local cnt
26295         local FID
26296
26297         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26298                 skip "Need MDS version at least 2.12.54"
26299
26300         test_mkdir $DIR/$tdir
26301         touch $DIR/$tdir/f
26302         cnt=$(ls -1 $DIR/$tdir | wc -l)
26303         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26304
26305         FID=$(lfs path2fid $DIR/$tdir/f)
26306         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26307         # rmfid should fail
26308         cnt=$(ls -1 $DIR/$tdir | wc -l)
26309         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26310
26311         chmod a+rw $DIR/$tdir
26312         ls -la $DIR/$tdir
26313         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26314         # rmfid should fail
26315         cnt=$(ls -1 $DIR/$tdir | wc -l)
26316         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26317
26318         rm -f $DIR/$tdir/f
26319         $RUNAS touch $DIR/$tdir/f
26320         FID=$(lfs path2fid $DIR/$tdir/f)
26321         echo "rmfid as root"
26322         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26323         cnt=$(ls -1 $DIR/$tdir | wc -l)
26324         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26325
26326         rm -f $DIR/$tdir/f
26327         $RUNAS touch $DIR/$tdir/f
26328         cnt=$(ls -1 $DIR/$tdir | wc -l)
26329         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26330         FID=$(lfs path2fid $DIR/$tdir/f)
26331         # rmfid w/o user_fid2path mount option should fail
26332         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26333         cnt=$(ls -1 $DIR/$tdir | wc -l)
26334         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26335
26336         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26337         stack_trap "rmdir $tmpdir"
26338         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26339                 error "failed to mount client'"
26340         stack_trap "umount_client $tmpdir"
26341
26342         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26343         # rmfid should succeed
26344         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26345         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26346
26347         # rmfid shouldn't allow to remove files due to dir's permission
26348         chmod a+rwx $tmpdir/$tdir
26349         touch $tmpdir/$tdir/f
26350         ls -la $tmpdir/$tdir
26351         FID=$(lfs path2fid $tmpdir/$tdir/f)
26352         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26353         return 0
26354 }
26355 run_test 421f "rmfid checks permissions"
26356
26357 test_421g() {
26358         local cnt
26359         local FIDS
26360
26361         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26362         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26363                 skip "Need MDS version at least 2.12.54"
26364
26365         mkdir -p $DIR/$tdir
26366         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26367         createmany -o $DIR/$tdir/striped_dir/f 512
26368         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26369         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26370
26371         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26372                 sed "s/[/][^:]*://g")
26373
26374         rm -f $DIR/$tdir/striped_dir/f1*
26375         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26376         removed=$((512 - cnt))
26377
26378         # few files have been just removed, so we expect
26379         # rmfid to fail on their fids
26380         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26381         [ $removed != $errors ] && error "$errors != $removed"
26382
26383         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26384         rm -rf $DIR/$tdir
26385         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26386 }
26387 run_test 421g "rmfid to return errors properly"
26388
26389 test_422() {
26390         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26391         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26392         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26393         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26394         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26395
26396         local amc=$(at_max_get client)
26397         local amo=$(at_max_get mds1)
26398         local timeout=`lctl get_param -n timeout`
26399
26400         at_max_set 0 client
26401         at_max_set 0 mds1
26402
26403 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26404         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26405                         fail_val=$(((2*timeout + 10)*1000))
26406         touch $DIR/$tdir/d3/file &
26407         sleep 2
26408 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26409         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26410                         fail_val=$((2*timeout + 5))
26411         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26412         local pid=$!
26413         sleep 1
26414         kill -9 $pid
26415         sleep $((2 * timeout))
26416         echo kill $pid
26417         kill -9 $pid
26418         lctl mark touch
26419         touch $DIR/$tdir/d2/file3
26420         touch $DIR/$tdir/d2/file4
26421         touch $DIR/$tdir/d2/file5
26422
26423         wait
26424         at_max_set $amc client
26425         at_max_set $amo mds1
26426
26427         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26428         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26429                 error "Watchdog is always throttled"
26430 }
26431 run_test 422 "kill a process with RPC in progress"
26432
26433 stat_test() {
26434     df -h $MOUNT &
26435     df -h $MOUNT &
26436     df -h $MOUNT &
26437     df -h $MOUNT &
26438     df -h $MOUNT &
26439     df -h $MOUNT &
26440 }
26441
26442 test_423() {
26443     local _stats
26444     # ensure statfs cache is expired
26445     sleep 2;
26446
26447     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26448     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26449
26450     return 0
26451 }
26452 run_test 423 "statfs should return a right data"
26453
26454 test_424() {
26455 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26456         $LCTL set_param fail_loc=0x80000522
26457         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26458         rm -f $DIR/$tfile
26459 }
26460 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26461
26462 test_425() {
26463         test_mkdir -c -1 $DIR/$tdir
26464         $LFS setstripe -c -1 $DIR/$tdir
26465
26466         lru_resize_disable "" 100
26467         stack_trap "lru_resize_enable" EXIT
26468
26469         sleep 5
26470
26471         for i in $(seq $((MDSCOUNT * 125))); do
26472                 local t=$DIR/$tdir/$tfile_$i
26473
26474                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26475                         error_noexit "Create file $t"
26476         done
26477         stack_trap "rm -rf $DIR/$tdir" EXIT
26478
26479         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26480                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26481                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26482
26483                 [ $lock_count -le $lru_size ] ||
26484                         error "osc lock count $lock_count > lru size $lru_size"
26485         done
26486
26487         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26488                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26489                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26490
26491                 [ $lock_count -le $lru_size ] ||
26492                         error "mdc lock count $lock_count > lru size $lru_size"
26493         done
26494 }
26495 run_test 425 "lock count should not exceed lru size"
26496
26497 test_426() {
26498         splice-test -r $DIR/$tfile
26499         splice-test -rd $DIR/$tfile
26500         splice-test $DIR/$tfile
26501         splice-test -d $DIR/$tfile
26502 }
26503 run_test 426 "splice test on Lustre"
26504
26505 test_427() {
26506         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26507         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26508                 skip "Need MDS version at least 2.12.4"
26509         local log
26510
26511         mkdir $DIR/$tdir
26512         mkdir $DIR/$tdir/1
26513         mkdir $DIR/$tdir/2
26514         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26515         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26516
26517         $LFS getdirstripe $DIR/$tdir/1/dir
26518
26519         #first setfattr for creating updatelog
26520         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26521
26522 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26523         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26524         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26525         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26526
26527         sleep 2
26528         fail mds2
26529         wait_recovery_complete mds2 $((2*TIMEOUT))
26530
26531         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26532         echo $log | grep "get update log failed" &&
26533                 error "update log corruption is detected" || true
26534 }
26535 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26536
26537 test_428() {
26538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26539         local cache_limit=$CACHE_MAX
26540
26541         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26542         $LCTL set_param -n llite.*.max_cached_mb=64
26543
26544         mkdir $DIR/$tdir
26545         $LFS setstripe -c 1 $DIR/$tdir
26546         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26547         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26548         #test write
26549         for f in $(seq 4); do
26550                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26551         done
26552         wait
26553
26554         cancel_lru_locks osc
26555         # Test read
26556         for f in $(seq 4); do
26557                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26558         done
26559         wait
26560 }
26561 run_test 428 "large block size IO should not hang"
26562
26563 test_429() { # LU-7915 / LU-10948
26564         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26565         local testfile=$DIR/$tfile
26566         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26567         local new_flag=1
26568         local first_rpc
26569         local second_rpc
26570         local third_rpc
26571
26572         $LCTL get_param $ll_opencache_threshold_count ||
26573                 skip "client does not have opencache parameter"
26574
26575         set_opencache $new_flag
26576         stack_trap "restore_opencache"
26577         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26578                 error "enable opencache failed"
26579         touch $testfile
26580         # drop MDC DLM locks
26581         cancel_lru_locks mdc
26582         # clear MDC RPC stats counters
26583         $LCTL set_param $mdc_rpcstats=clear
26584
26585         # According to the current implementation, we need to run 3 times
26586         # open & close file to verify if opencache is enabled correctly.
26587         # 1st, RPCs are sent for lookup/open and open handle is released on
26588         #      close finally.
26589         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26590         #      so open handle won't be released thereafter.
26591         # 3rd, No RPC is sent out.
26592         $MULTIOP $testfile oc || error "multiop failed"
26593         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26594         echo "1st: $first_rpc RPCs in flight"
26595
26596         $MULTIOP $testfile oc || error "multiop failed"
26597         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26598         echo "2nd: $second_rpc RPCs in flight"
26599
26600         $MULTIOP $testfile oc || error "multiop failed"
26601         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26602         echo "3rd: $third_rpc RPCs in flight"
26603
26604         #verify no MDC RPC is sent
26605         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26606 }
26607 run_test 429 "verify if opencache flag on client side does work"
26608
26609 lseek_test_430() {
26610         local offset
26611         local file=$1
26612
26613         # data at [200K, 400K)
26614         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26615                 error "256K->512K dd fails"
26616         # data at [2M, 3M)
26617         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26618                 error "2M->3M dd fails"
26619         # data at [4M, 5M)
26620         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26621                 error "4M->5M dd fails"
26622         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26623         # start at first component hole #1
26624         printf "Seeking hole from 1000 ... "
26625         offset=$(lseek_test -l 1000 $file)
26626         echo $offset
26627         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26628         printf "Seeking data from 1000 ... "
26629         offset=$(lseek_test -d 1000 $file)
26630         echo $offset
26631         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26632
26633         # start at first component data block
26634         printf "Seeking hole from 300000 ... "
26635         offset=$(lseek_test -l 300000 $file)
26636         echo $offset
26637         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26638         printf "Seeking data from 300000 ... "
26639         offset=$(lseek_test -d 300000 $file)
26640         echo $offset
26641         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26642
26643         # start at the first component but beyond end of object size
26644         printf "Seeking hole from 1000000 ... "
26645         offset=$(lseek_test -l 1000000 $file)
26646         echo $offset
26647         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26648         printf "Seeking data from 1000000 ... "
26649         offset=$(lseek_test -d 1000000 $file)
26650         echo $offset
26651         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26652
26653         # start at second component stripe 2 (empty file)
26654         printf "Seeking hole from 1500000 ... "
26655         offset=$(lseek_test -l 1500000 $file)
26656         echo $offset
26657         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26658         printf "Seeking data from 1500000 ... "
26659         offset=$(lseek_test -d 1500000 $file)
26660         echo $offset
26661         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26662
26663         # start at second component stripe 1 (all data)
26664         printf "Seeking hole from 3000000 ... "
26665         offset=$(lseek_test -l 3000000 $file)
26666         echo $offset
26667         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26668         printf "Seeking data from 3000000 ... "
26669         offset=$(lseek_test -d 3000000 $file)
26670         echo $offset
26671         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26672
26673         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26674                 error "2nd dd fails"
26675         echo "Add data block at 640K...1280K"
26676
26677         # start at before new data block, in hole
26678         printf "Seeking hole from 600000 ... "
26679         offset=$(lseek_test -l 600000 $file)
26680         echo $offset
26681         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26682         printf "Seeking data from 600000 ... "
26683         offset=$(lseek_test -d 600000 $file)
26684         echo $offset
26685         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26686
26687         # start at the first component new data block
26688         printf "Seeking hole from 1000000 ... "
26689         offset=$(lseek_test -l 1000000 $file)
26690         echo $offset
26691         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26692         printf "Seeking data from 1000000 ... "
26693         offset=$(lseek_test -d 1000000 $file)
26694         echo $offset
26695         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26696
26697         # start at second component stripe 2, new data
26698         printf "Seeking hole from 1200000 ... "
26699         offset=$(lseek_test -l 1200000 $file)
26700         echo $offset
26701         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26702         printf "Seeking data from 1200000 ... "
26703         offset=$(lseek_test -d 1200000 $file)
26704         echo $offset
26705         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26706
26707         # start beyond file end
26708         printf "Using offset > filesize ... "
26709         lseek_test -l 4000000 $file && error "lseek should fail"
26710         printf "Using offset > filesize ... "
26711         lseek_test -d 4000000 $file && error "lseek should fail"
26712
26713         printf "Done\n\n"
26714 }
26715
26716 test_430a() {
26717         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26718                 skip "MDT does not support SEEK_HOLE"
26719
26720         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26721                 skip "OST does not support SEEK_HOLE"
26722
26723         local file=$DIR/$tdir/$tfile
26724
26725         mkdir -p $DIR/$tdir
26726
26727         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26728         # OST stripe #1 will have continuous data at [1M, 3M)
26729         # OST stripe #2 is empty
26730         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26731         lseek_test_430 $file
26732         rm $file
26733         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26734         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26735         lseek_test_430 $file
26736         rm $file
26737         $LFS setstripe -c2 -S 512K $file
26738         echo "Two stripes, stripe size 512K"
26739         lseek_test_430 $file
26740         rm $file
26741         # FLR with stale mirror
26742         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26743                        -N -c2 -S 1M $file
26744         echo "Mirrored file:"
26745         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26746         echo "Plain 2 stripes 1M"
26747         lseek_test_430 $file
26748         rm $file
26749 }
26750 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26751
26752 test_430b() {
26753         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26754                 skip "OST does not support SEEK_HOLE"
26755
26756         local offset
26757         local file=$DIR/$tdir/$tfile
26758
26759         mkdir -p $DIR/$tdir
26760         # Empty layout lseek should fail
26761         $MCREATE $file
26762         # seek from 0
26763         printf "Seeking hole from 0 ... "
26764         lseek_test -l 0 $file && error "lseek should fail"
26765         printf "Seeking data from 0 ... "
26766         lseek_test -d 0 $file && error "lseek should fail"
26767         rm $file
26768
26769         # 1M-hole file
26770         $LFS setstripe -E 1M -c2 -E eof $file
26771         $TRUNCATE $file 1048576
26772         printf "Seeking hole from 1000000 ... "
26773         offset=$(lseek_test -l 1000000 $file)
26774         echo $offset
26775         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26776         printf "Seeking data from 1000000 ... "
26777         lseek_test -d 1000000 $file && error "lseek should fail"
26778         rm $file
26779
26780         # full component followed by non-inited one
26781         $LFS setstripe -E 1M -c2 -E eof $file
26782         dd if=/dev/urandom of=$file bs=1M count=1
26783         printf "Seeking hole from 1000000 ... "
26784         offset=$(lseek_test -l 1000000 $file)
26785         echo $offset
26786         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26787         printf "Seeking hole from 1048576 ... "
26788         lseek_test -l 1048576 $file && error "lseek should fail"
26789         # init second component and truncate back
26790         echo "123" >> $file
26791         $TRUNCATE $file 1048576
26792         printf "Seeking hole from 1000000 ... "
26793         offset=$(lseek_test -l 1000000 $file)
26794         echo $offset
26795         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26796         printf "Seeking hole from 1048576 ... "
26797         lseek_test -l 1048576 $file && error "lseek should fail"
26798         # boundary checks for big values
26799         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26800         offset=$(lseek_test -d 0 $file.10g)
26801         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26802         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26803         offset=$(lseek_test -d 0 $file.100g)
26804         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26805         return 0
26806 }
26807 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26808
26809 test_430c() {
26810         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26811                 skip "OST does not support SEEK_HOLE"
26812
26813         local file=$DIR/$tdir/$tfile
26814         local start
26815
26816         mkdir -p $DIR/$tdir
26817         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26818
26819         # cp version 8.33+ prefers lseek over fiemap
26820         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26821                 start=$SECONDS
26822                 time cp $file /dev/null
26823                 (( SECONDS - start < 5 )) ||
26824                         error "cp: too long runtime $((SECONDS - start))"
26825
26826         fi
26827         # tar version 1.29+ supports SEEK_HOLE/DATA
26828         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26829                 start=$SECONDS
26830                 time tar cS $file - | cat > /dev/null
26831                 (( SECONDS - start < 5 )) ||
26832                         error "tar: too long runtime $((SECONDS - start))"
26833         fi
26834 }
26835 run_test 430c "lseek: external tools check"
26836
26837 test_431() { # LU-14187
26838         local file=$DIR/$tdir/$tfile
26839
26840         mkdir -p $DIR/$tdir
26841         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26842         dd if=/dev/urandom of=$file bs=4k count=1
26843         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26844         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26845         #define OBD_FAIL_OST_RESTART_IO 0x251
26846         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26847         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26848         cp $file $file.0
26849         cancel_lru_locks
26850         sync_all_data
26851         echo 3 > /proc/sys/vm/drop_caches
26852         diff  $file $file.0 || error "data diff"
26853 }
26854 run_test 431 "Restart transaction for IO"
26855
26856 cleanup_test_432() {
26857         do_facet mgs $LCTL nodemap_activate 0
26858         wait_nm_sync active
26859 }
26860
26861 test_432() {
26862         local tmpdir=$TMP/dir432
26863
26864         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26865                 skip "Need MDS version at least 2.14.52"
26866
26867         stack_trap cleanup_test_432 EXIT
26868         mkdir $DIR/$tdir
26869         mkdir $tmpdir
26870
26871         do_facet mgs $LCTL nodemap_activate 1
26872         wait_nm_sync active
26873         do_facet mgs $LCTL nodemap_modify --name default \
26874                 --property admin --value 1
26875         do_facet mgs $LCTL nodemap_modify --name default \
26876                 --property trusted --value 1
26877         cancel_lru_locks mdc
26878         wait_nm_sync default admin_nodemap
26879         wait_nm_sync default trusted_nodemap
26880
26881         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26882                grep -ci "Operation not permitted") -ne 0 ]; then
26883                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26884         fi
26885 }
26886 run_test 432 "mv dir from outside Lustre"
26887
26888 test_433() {
26889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26890
26891         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
26892                 skip "inode cache not supported"
26893
26894         $LCTL set_param llite.*.inode_cache=0
26895         stack_trap "$LCTL set_param llite.*.inode_cache=1"
26896
26897         local count=256
26898         local before
26899         local after
26900
26901         cancel_lru_locks mdc
26902         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26903         createmany -m $DIR/$tdir/f $count
26904         createmany -d $DIR/$tdir/d $count
26905         ls -l $DIR/$tdir > /dev/null
26906         stack_trap "rm -rf $DIR/$tdir"
26907
26908         before=$(num_objects)
26909         cancel_lru_locks mdc
26910         after=$(num_objects)
26911
26912         # sometimes even @before is less than 2 * count
26913         while (( before - after < count )); do
26914                 sleep 1
26915                 after=$(num_objects)
26916                 wait=$((wait + 1))
26917                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
26918                 if (( wait > 60 )); then
26919                         error "inode slab grew from $before to $after"
26920                 fi
26921         done
26922
26923         echo "lustre_inode_cache $before objs before lock cancel, $after after"
26924 }
26925 run_test 433 "ldlm lock cancel releases dentries and inodes"
26926
26927 prep_801() {
26928         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26929         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26930                 skip "Need server version at least 2.9.55"
26931
26932         start_full_debug_logging
26933 }
26934
26935 post_801() {
26936         stop_full_debug_logging
26937 }
26938
26939 barrier_stat() {
26940         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26941                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26942                            awk '/The barrier for/ { print $7 }')
26943                 echo $st
26944         else
26945                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26946                 echo \'$st\'
26947         fi
26948 }
26949
26950 barrier_expired() {
26951         local expired
26952
26953         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26954                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26955                           awk '/will be expired/ { print $7 }')
26956         else
26957                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26958         fi
26959
26960         echo $expired
26961 }
26962
26963 test_801a() {
26964         prep_801
26965
26966         echo "Start barrier_freeze at: $(date)"
26967         #define OBD_FAIL_BARRIER_DELAY          0x2202
26968         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26969         # Do not reduce barrier time - See LU-11873
26970         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26971
26972         sleep 2
26973         local b_status=$(barrier_stat)
26974         echo "Got barrier status at: $(date)"
26975         [ "$b_status" = "'freezing_p1'" ] ||
26976                 error "(1) unexpected barrier status $b_status"
26977
26978         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26979         wait
26980         b_status=$(barrier_stat)
26981         [ "$b_status" = "'frozen'" ] ||
26982                 error "(2) unexpected barrier status $b_status"
26983
26984         local expired=$(barrier_expired)
26985         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26986         sleep $((expired + 3))
26987
26988         b_status=$(barrier_stat)
26989         [ "$b_status" = "'expired'" ] ||
26990                 error "(3) unexpected barrier status $b_status"
26991
26992         # Do not reduce barrier time - See LU-11873
26993         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26994                 error "(4) fail to freeze barrier"
26995
26996         b_status=$(barrier_stat)
26997         [ "$b_status" = "'frozen'" ] ||
26998                 error "(5) unexpected barrier status $b_status"
26999
27000         echo "Start barrier_thaw at: $(date)"
27001         #define OBD_FAIL_BARRIER_DELAY          0x2202
27002         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27003         do_facet mgs $LCTL barrier_thaw $FSNAME &
27004
27005         sleep 2
27006         b_status=$(barrier_stat)
27007         echo "Got barrier status at: $(date)"
27008         [ "$b_status" = "'thawing'" ] ||
27009                 error "(6) unexpected barrier status $b_status"
27010
27011         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27012         wait
27013         b_status=$(barrier_stat)
27014         [ "$b_status" = "'thawed'" ] ||
27015                 error "(7) unexpected barrier status $b_status"
27016
27017         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27018         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27019         do_facet mgs $LCTL barrier_freeze $FSNAME
27020
27021         b_status=$(barrier_stat)
27022         [ "$b_status" = "'failed'" ] ||
27023                 error "(8) unexpected barrier status $b_status"
27024
27025         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27026         do_facet mgs $LCTL barrier_thaw $FSNAME
27027
27028         post_801
27029 }
27030 run_test 801a "write barrier user interfaces and stat machine"
27031
27032 test_801b() {
27033         prep_801
27034
27035         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27036         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27037         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27038         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27039         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27040
27041         cancel_lru_locks mdc
27042
27043         # 180 seconds should be long enough
27044         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27045
27046         local b_status=$(barrier_stat)
27047         [ "$b_status" = "'frozen'" ] ||
27048                 error "(6) unexpected barrier status $b_status"
27049
27050         mkdir $DIR/$tdir/d0/d10 &
27051         mkdir_pid=$!
27052
27053         touch $DIR/$tdir/d1/f13 &
27054         touch_pid=$!
27055
27056         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27057         ln_pid=$!
27058
27059         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27060         mv_pid=$!
27061
27062         rm -f $DIR/$tdir/d4/f12 &
27063         rm_pid=$!
27064
27065         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27066
27067         # To guarantee taht the 'stat' is not blocked
27068         b_status=$(barrier_stat)
27069         [ "$b_status" = "'frozen'" ] ||
27070                 error "(8) unexpected barrier status $b_status"
27071
27072         # let above commands to run at background
27073         sleep 5
27074
27075         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27076         ps -p $touch_pid || error "(10) touch should be blocked"
27077         ps -p $ln_pid || error "(11) link should be blocked"
27078         ps -p $mv_pid || error "(12) rename should be blocked"
27079         ps -p $rm_pid || error "(13) unlink should be blocked"
27080
27081         b_status=$(barrier_stat)
27082         [ "$b_status" = "'frozen'" ] ||
27083                 error "(14) unexpected barrier status $b_status"
27084
27085         do_facet mgs $LCTL barrier_thaw $FSNAME
27086         b_status=$(barrier_stat)
27087         [ "$b_status" = "'thawed'" ] ||
27088                 error "(15) unexpected barrier status $b_status"
27089
27090         wait $mkdir_pid || error "(16) mkdir should succeed"
27091         wait $touch_pid || error "(17) touch should succeed"
27092         wait $ln_pid || error "(18) link should succeed"
27093         wait $mv_pid || error "(19) rename should succeed"
27094         wait $rm_pid || error "(20) unlink should succeed"
27095
27096         post_801
27097 }
27098 run_test 801b "modification will be blocked by write barrier"
27099
27100 test_801c() {
27101         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27102
27103         prep_801
27104
27105         stop mds2 || error "(1) Fail to stop mds2"
27106
27107         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27108
27109         local b_status=$(barrier_stat)
27110         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27111                 do_facet mgs $LCTL barrier_thaw $FSNAME
27112                 error "(2) unexpected barrier status $b_status"
27113         }
27114
27115         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27116                 error "(3) Fail to rescan barrier bitmap"
27117
27118         # Do not reduce barrier time - See LU-11873
27119         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27120
27121         b_status=$(barrier_stat)
27122         [ "$b_status" = "'frozen'" ] ||
27123                 error "(4) unexpected barrier status $b_status"
27124
27125         do_facet mgs $LCTL barrier_thaw $FSNAME
27126         b_status=$(barrier_stat)
27127         [ "$b_status" = "'thawed'" ] ||
27128                 error "(5) unexpected barrier status $b_status"
27129
27130         local devname=$(mdsdevname 2)
27131
27132         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27133
27134         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27135                 error "(7) Fail to rescan barrier bitmap"
27136
27137         post_801
27138 }
27139 run_test 801c "rescan barrier bitmap"
27140
27141 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27142 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27143 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27144 saved_MOUNT_OPTS=$MOUNT_OPTS
27145
27146 cleanup_802a() {
27147         trap 0
27148
27149         stopall
27150         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27151         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27152         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27153         MOUNT_OPTS=$saved_MOUNT_OPTS
27154         setupall
27155 }
27156
27157 test_802a() {
27158         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27159         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27160         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27161                 skip "Need server version at least 2.9.55"
27162
27163         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27164
27165         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27166
27167         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27168                 error "(2) Fail to copy"
27169
27170         trap cleanup_802a EXIT
27171
27172         # sync by force before remount as readonly
27173         sync; sync_all_data; sleep 3; sync_all_data
27174
27175         stopall
27176
27177         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27178         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27179         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27180
27181         echo "Mount the server as read only"
27182         setupall server_only || error "(3) Fail to start servers"
27183
27184         echo "Mount client without ro should fail"
27185         mount_client $MOUNT &&
27186                 error "(4) Mount client without 'ro' should fail"
27187
27188         echo "Mount client with ro should succeed"
27189         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27190         mount_client $MOUNT ||
27191                 error "(5) Mount client with 'ro' should succeed"
27192
27193         echo "Modify should be refused"
27194         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27195
27196         echo "Read should be allowed"
27197         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27198                 error "(7) Read should succeed under ro mode"
27199
27200         cleanup_802a
27201 }
27202 run_test 802a "simulate readonly device"
27203
27204 test_802b() {
27205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27206         remote_mds_nodsh && skip "remote MDS with nodsh"
27207
27208         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27209                 skip "readonly option not available"
27210
27211         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27212
27213         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27214                 error "(2) Fail to copy"
27215
27216         # write back all cached data before setting MDT to readonly
27217         cancel_lru_locks
27218         sync_all_data
27219
27220         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27221         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27222
27223         echo "Modify should be refused"
27224         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27225
27226         echo "Read should be allowed"
27227         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27228                 error "(7) Read should succeed under ro mode"
27229
27230         # disable readonly
27231         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27232 }
27233 run_test 802b "be able to set MDTs to readonly"
27234
27235 test_803a() {
27236         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27237         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27238                 skip "MDS needs to be newer than 2.10.54"
27239
27240         mkdir_on_mdt0 $DIR/$tdir
27241         # Create some objects on all MDTs to trigger related logs objects
27242         for idx in $(seq $MDSCOUNT); do
27243                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27244                         $DIR/$tdir/dir${idx} ||
27245                         error "Fail to create $DIR/$tdir/dir${idx}"
27246         done
27247
27248         sync; sleep 3
27249         wait_delete_completed # ensure old test cleanups are finished
27250         echo "before create:"
27251         $LFS df -i $MOUNT
27252         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27253
27254         for i in {1..10}; do
27255                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27256                         error "Fail to create $DIR/$tdir/foo$i"
27257         done
27258
27259         sync; sleep 3
27260         echo "after create:"
27261         $LFS df -i $MOUNT
27262         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27263
27264         # allow for an llog to be cleaned up during the test
27265         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27266                 error "before ($before_used) + 10 > after ($after_used)"
27267
27268         for i in {1..10}; do
27269                 rm -rf $DIR/$tdir/foo$i ||
27270                         error "Fail to remove $DIR/$tdir/foo$i"
27271         done
27272
27273         sleep 3 # avoid MDT return cached statfs
27274         wait_delete_completed
27275         echo "after unlink:"
27276         $LFS df -i $MOUNT
27277         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27278
27279         # allow for an llog to be created during the test
27280         [ $after_used -le $((before_used + 1)) ] ||
27281                 error "after ($after_used) > before ($before_used) + 1"
27282 }
27283 run_test 803a "verify agent object for remote object"
27284
27285 test_803b() {
27286         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27287         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27288                 skip "MDS needs to be newer than 2.13.56"
27289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27290
27291         for i in $(seq 0 $((MDSCOUNT - 1))); do
27292                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27293         done
27294
27295         local before=0
27296         local after=0
27297
27298         local tmp
27299
27300         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27301         for i in $(seq 0 $((MDSCOUNT - 1))); do
27302                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27303                         awk '/getattr/ { print $2 }')
27304                 before=$((before + tmp))
27305         done
27306         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27307         for i in $(seq 0 $((MDSCOUNT - 1))); do
27308                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27309                         awk '/getattr/ { print $2 }')
27310                 after=$((after + tmp))
27311         done
27312
27313         [ $before -eq $after ] || error "getattr count $before != $after"
27314 }
27315 run_test 803b "remote object can getattr from cache"
27316
27317 test_804() {
27318         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27319         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27320                 skip "MDS needs to be newer than 2.10.54"
27321         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27322
27323         mkdir -p $DIR/$tdir
27324         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27325                 error "Fail to create $DIR/$tdir/dir0"
27326
27327         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27328         local dev=$(mdsdevname 2)
27329
27330         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27331                 grep ${fid} || error "NOT found agent entry for dir0"
27332
27333         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27334                 error "Fail to create $DIR/$tdir/dir1"
27335
27336         touch $DIR/$tdir/dir1/foo0 ||
27337                 error "Fail to create $DIR/$tdir/dir1/foo0"
27338         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27339         local rc=0
27340
27341         for idx in $(seq $MDSCOUNT); do
27342                 dev=$(mdsdevname $idx)
27343                 do_facet mds${idx} \
27344                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27345                         grep ${fid} && rc=$idx
27346         done
27347
27348         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27349                 error "Fail to rename foo0 to foo1"
27350         if [ $rc -eq 0 ]; then
27351                 for idx in $(seq $MDSCOUNT); do
27352                         dev=$(mdsdevname $idx)
27353                         do_facet mds${idx} \
27354                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27355                         grep ${fid} && rc=$idx
27356                 done
27357         fi
27358
27359         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27360                 error "Fail to rename foo1 to foo2"
27361         if [ $rc -eq 0 ]; then
27362                 for idx in $(seq $MDSCOUNT); do
27363                         dev=$(mdsdevname $idx)
27364                         do_facet mds${idx} \
27365                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27366                         grep ${fid} && rc=$idx
27367                 done
27368         fi
27369
27370         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27371
27372         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27373                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27374         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27375                 error "Fail to rename foo2 to foo0"
27376         unlink $DIR/$tdir/dir1/foo0 ||
27377                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27378         rm -rf $DIR/$tdir/dir0 ||
27379                 error "Fail to rm $DIR/$tdir/dir0"
27380
27381         for idx in $(seq $MDSCOUNT); do
27382                 rc=0
27383
27384                 stop mds${idx}
27385                 dev=$(mdsdevname $idx)
27386                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27387                         rc=$?
27388                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27389                         error "mount mds$idx failed"
27390                 df $MOUNT > /dev/null 2>&1
27391
27392                 # e2fsck should not return error
27393                 [ $rc -eq 0 ] ||
27394                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27395         done
27396 }
27397 run_test 804 "verify agent entry for remote entry"
27398
27399 cleanup_805() {
27400         do_facet $SINGLEMDS zfs set quota=$old $fsset
27401         unlinkmany $DIR/$tdir/f- 1000000
27402         trap 0
27403 }
27404
27405 test_805() {
27406         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27407         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27408         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27409                 skip "netfree not implemented before 0.7"
27410         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27411                 skip "Need MDS version at least 2.10.57"
27412
27413         local fsset
27414         local freekb
27415         local usedkb
27416         local old
27417         local quota
27418         local pref="osd-zfs.$FSNAME-MDT0000."
27419
27420         # limit available space on MDS dataset to meet nospace issue
27421         # quickly. then ZFS 0.7.2 can use reserved space if asked
27422         # properly (using netfree flag in osd_declare_destroy()
27423         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27424         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27425                 gawk '{print $3}')
27426         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27427         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27428         let "usedkb=usedkb-freekb"
27429         let "freekb=freekb/2"
27430         if let "freekb > 5000"; then
27431                 let "freekb=5000"
27432         fi
27433         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27434         trap cleanup_805 EXIT
27435         mkdir_on_mdt0 $DIR/$tdir
27436         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27437                 error "Can't set PFL layout"
27438         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27439         rm -rf $DIR/$tdir || error "not able to remove"
27440         do_facet $SINGLEMDS zfs set quota=$old $fsset
27441         trap 0
27442 }
27443 run_test 805 "ZFS can remove from full fs"
27444
27445 # Size-on-MDS test
27446 check_lsom_data()
27447 {
27448         local file=$1
27449         local expect=$(stat -c %s $file)
27450
27451         check_lsom_size $1 $expect
27452
27453         local blocks=$($LFS getsom -b $file)
27454         expect=$(stat -c %b $file)
27455         [[ $blocks == $expect ]] ||
27456                 error "$file expected blocks: $expect, got: $blocks"
27457 }
27458
27459 check_lsom_size()
27460 {
27461         local size
27462         local expect=$2
27463
27464         cancel_lru_locks mdc
27465
27466         size=$($LFS getsom -s $1)
27467         [[ $size == $expect ]] ||
27468                 error "$file expected size: $expect, got: $size"
27469 }
27470
27471 test_806() {
27472         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27473                 skip "Need MDS version at least 2.11.52"
27474
27475         local bs=1048576
27476
27477         touch $DIR/$tfile || error "touch $tfile failed"
27478
27479         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27480         save_lustre_params client "llite.*.xattr_cache" > $save
27481         lctl set_param llite.*.xattr_cache=0
27482         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27483
27484         # single-threaded write
27485         echo "Test SOM for single-threaded write"
27486         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27487                 error "write $tfile failed"
27488         check_lsom_size $DIR/$tfile $bs
27489
27490         local num=32
27491         local size=$(($num * $bs))
27492         local offset=0
27493         local i
27494
27495         echo "Test SOM for single client multi-threaded($num) write"
27496         $TRUNCATE $DIR/$tfile 0
27497         for ((i = 0; i < $num; i++)); do
27498                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27499                 local pids[$i]=$!
27500                 offset=$((offset + $bs))
27501         done
27502         for (( i=0; i < $num; i++ )); do
27503                 wait ${pids[$i]}
27504         done
27505         check_lsom_size $DIR/$tfile $size
27506
27507         $TRUNCATE $DIR/$tfile 0
27508         for ((i = 0; i < $num; i++)); do
27509                 offset=$((offset - $bs))
27510                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27511                 local pids[$i]=$!
27512         done
27513         for (( i=0; i < $num; i++ )); do
27514                 wait ${pids[$i]}
27515         done
27516         check_lsom_size $DIR/$tfile $size
27517
27518         # multi-client writes
27519         num=$(get_node_count ${CLIENTS//,/ })
27520         size=$(($num * $bs))
27521         offset=0
27522         i=0
27523
27524         echo "Test SOM for multi-client ($num) writes"
27525         $TRUNCATE $DIR/$tfile 0
27526         for client in ${CLIENTS//,/ }; do
27527                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27528                 local pids[$i]=$!
27529                 i=$((i + 1))
27530                 offset=$((offset + $bs))
27531         done
27532         for (( i=0; i < $num; i++ )); do
27533                 wait ${pids[$i]}
27534         done
27535         check_lsom_size $DIR/$tfile $offset
27536
27537         i=0
27538         $TRUNCATE $DIR/$tfile 0
27539         for client in ${CLIENTS//,/ }; do
27540                 offset=$((offset - $bs))
27541                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27542                 local pids[$i]=$!
27543                 i=$((i + 1))
27544         done
27545         for (( i=0; i < $num; i++ )); do
27546                 wait ${pids[$i]}
27547         done
27548         check_lsom_size $DIR/$tfile $size
27549
27550         # verify truncate
27551         echo "Test SOM for truncate"
27552         $TRUNCATE $DIR/$tfile 1048576
27553         check_lsom_size $DIR/$tfile 1048576
27554         $TRUNCATE $DIR/$tfile 1234
27555         check_lsom_size $DIR/$tfile 1234
27556
27557         # verify SOM blocks count
27558         echo "Verify SOM block count"
27559         $TRUNCATE $DIR/$tfile 0
27560         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27561                 error "failed to write file $tfile"
27562         check_lsom_data $DIR/$tfile
27563 }
27564 run_test 806 "Verify Lazy Size on MDS"
27565
27566 test_807() {
27567         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27568         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27569                 skip "Need MDS version at least 2.11.52"
27570
27571         # Registration step
27572         changelog_register || error "changelog_register failed"
27573         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27574         changelog_users $SINGLEMDS | grep -q $cl_user ||
27575                 error "User $cl_user not found in changelog_users"
27576
27577         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27578         save_lustre_params client "llite.*.xattr_cache" > $save
27579         lctl set_param llite.*.xattr_cache=0
27580         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27581
27582         rm -rf $DIR/$tdir || error "rm $tdir failed"
27583         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27584         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27585         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27586         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27587                 error "truncate $tdir/trunc failed"
27588
27589         local bs=1048576
27590         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27591                 error "write $tfile failed"
27592
27593         # multi-client wirtes
27594         local num=$(get_node_count ${CLIENTS//,/ })
27595         local offset=0
27596         local i=0
27597
27598         echo "Test SOM for multi-client ($num) writes"
27599         touch $DIR/$tfile || error "touch $tfile failed"
27600         $TRUNCATE $DIR/$tfile 0
27601         for client in ${CLIENTS//,/ }; do
27602                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27603                 local pids[$i]=$!
27604                 i=$((i + 1))
27605                 offset=$((offset + $bs))
27606         done
27607         for (( i=0; i < $num; i++ )); do
27608                 wait ${pids[$i]}
27609         done
27610
27611         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27612         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27613         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27614         check_lsom_data $DIR/$tdir/trunc
27615         check_lsom_data $DIR/$tdir/single_dd
27616         check_lsom_data $DIR/$tfile
27617
27618         rm -rf $DIR/$tdir
27619         # Deregistration step
27620         changelog_deregister || error "changelog_deregister failed"
27621 }
27622 run_test 807 "verify LSOM syncing tool"
27623
27624 check_som_nologged()
27625 {
27626         local lines=$($LFS changelog $FSNAME-MDT0000 |
27627                 grep 'x=trusted.som' | wc -l)
27628         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27629 }
27630
27631 test_808() {
27632         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27633                 skip "Need MDS version at least 2.11.55"
27634
27635         # Registration step
27636         changelog_register || error "changelog_register failed"
27637
27638         touch $DIR/$tfile || error "touch $tfile failed"
27639         check_som_nologged
27640
27641         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27642                 error "write $tfile failed"
27643         check_som_nologged
27644
27645         $TRUNCATE $DIR/$tfile 1234
27646         check_som_nologged
27647
27648         $TRUNCATE $DIR/$tfile 1048576
27649         check_som_nologged
27650
27651         # Deregistration step
27652         changelog_deregister || error "changelog_deregister failed"
27653 }
27654 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27655
27656 check_som_nodata()
27657 {
27658         $LFS getsom $1
27659         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27660 }
27661
27662 test_809() {
27663         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27664                 skip "Need MDS version at least 2.11.56"
27665
27666         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27667                 error "failed to create DoM-only file $DIR/$tfile"
27668         touch $DIR/$tfile || error "touch $tfile failed"
27669         check_som_nodata $DIR/$tfile
27670
27671         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27672                 error "write $tfile failed"
27673         check_som_nodata $DIR/$tfile
27674
27675         $TRUNCATE $DIR/$tfile 1234
27676         check_som_nodata $DIR/$tfile
27677
27678         $TRUNCATE $DIR/$tfile 4097
27679         check_som_nodata $DIR/$file
27680 }
27681 run_test 809 "Verify no SOM xattr store for DoM-only files"
27682
27683 test_810() {
27684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27685         $GSS && skip_env "could not run with gss"
27686         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27687                 skip "OST < 2.12.58 doesn't align checksum"
27688
27689         set_checksums 1
27690         stack_trap "set_checksums $ORIG_CSUM" EXIT
27691         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27692
27693         local csum
27694         local before
27695         local after
27696         for csum in $CKSUM_TYPES; do
27697                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27698                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27699                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27700                         eval set -- $i
27701                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27702                         before=$(md5sum $DIR/$tfile)
27703                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27704                         after=$(md5sum $DIR/$tfile)
27705                         [ "$before" == "$after" ] ||
27706                                 error "$csum: $before != $after bs=$1 seek=$2"
27707                 done
27708         done
27709 }
27710 run_test 810 "partial page writes on ZFS (LU-11663)"
27711
27712 test_812a() {
27713         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27714                 skip "OST < 2.12.51 doesn't support this fail_loc"
27715
27716         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27717         # ensure ost1 is connected
27718         stat $DIR/$tfile >/dev/null || error "can't stat"
27719         wait_osc_import_state client ost1 FULL
27720         # no locks, no reqs to let the connection idle
27721         cancel_lru_locks osc
27722
27723         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27724 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27725         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27726         wait_osc_import_state client ost1 CONNECTING
27727         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27728
27729         stat $DIR/$tfile >/dev/null || error "can't stat file"
27730 }
27731 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27732
27733 test_812b() { # LU-12378
27734         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27735                 skip "OST < 2.12.51 doesn't support this fail_loc"
27736
27737         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27738         # ensure ost1 is connected
27739         stat $DIR/$tfile >/dev/null || error "can't stat"
27740         wait_osc_import_state client ost1 FULL
27741         # no locks, no reqs to let the connection idle
27742         cancel_lru_locks osc
27743
27744         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27745 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27746         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27747         wait_osc_import_state client ost1 CONNECTING
27748         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27749
27750         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27751         wait_osc_import_state client ost1 IDLE
27752 }
27753 run_test 812b "do not drop no resend request for idle connect"
27754
27755 test_812c() {
27756         local old
27757
27758         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27759
27760         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27761         $LFS getstripe $DIR/$tfile
27762         $LCTL set_param osc.*.idle_timeout=10
27763         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27764         # ensure ost1 is connected
27765         stat $DIR/$tfile >/dev/null || error "can't stat"
27766         wait_osc_import_state client ost1 FULL
27767         # no locks, no reqs to let the connection idle
27768         cancel_lru_locks osc
27769
27770 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27771         $LCTL set_param fail_loc=0x80000533
27772         sleep 15
27773         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27774 }
27775 run_test 812c "idle import vs lock enqueue race"
27776
27777 test_813() {
27778         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27779         [ -z "$file_heat_sav" ] && skip "no file heat support"
27780
27781         local readsample
27782         local writesample
27783         local readbyte
27784         local writebyte
27785         local readsample1
27786         local writesample1
27787         local readbyte1
27788         local writebyte1
27789
27790         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27791         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27792
27793         $LCTL set_param -n llite.*.file_heat=1
27794         echo "Turn on file heat"
27795         echo "Period second: $period_second, Decay percentage: $decay_pct"
27796
27797         echo "QQQQ" > $DIR/$tfile
27798         echo "QQQQ" > $DIR/$tfile
27799         echo "QQQQ" > $DIR/$tfile
27800         cat $DIR/$tfile > /dev/null
27801         cat $DIR/$tfile > /dev/null
27802         cat $DIR/$tfile > /dev/null
27803         cat $DIR/$tfile > /dev/null
27804
27805         local out=$($LFS heat_get $DIR/$tfile)
27806
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 -le 4 ] || error "read sample ($readsample) is wrong"
27814         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27815         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27816         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27817
27818         sleep $((period_second + 3))
27819         echo "Sleep $((period_second + 3)) seconds..."
27820         # The recursion formula to calculate the heat of the file f is as
27821         # follow:
27822         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27823         # Where Hi is the heat value in the period between time points i*I and
27824         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27825         # to the weight of Ci.
27826         out=$($LFS heat_get $DIR/$tfile)
27827         $LFS heat_get $DIR/$tfile
27828         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27829         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27830         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27831         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27832
27833         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27834                 error "read sample ($readsample) is wrong"
27835         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27836                 error "write sample ($writesample) is wrong"
27837         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27838                 error "read bytes ($readbyte) is wrong"
27839         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27840                 error "write bytes ($writebyte) is wrong"
27841
27842         echo "QQQQ" > $DIR/$tfile
27843         echo "QQQQ" > $DIR/$tfile
27844         echo "QQQQ" > $DIR/$tfile
27845         cat $DIR/$tfile > /dev/null
27846         cat $DIR/$tfile > /dev/null
27847         cat $DIR/$tfile > /dev/null
27848         cat $DIR/$tfile > /dev/null
27849
27850         sleep $((period_second + 3))
27851         echo "Sleep $((period_second + 3)) seconds..."
27852
27853         out=$($LFS heat_get $DIR/$tfile)
27854         $LFS heat_get $DIR/$tfile
27855         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27856         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27857         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27858         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27859
27860         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27861                 4 * $decay_pct) / 100") -eq 1 ] ||
27862                 error "read sample ($readsample1) is wrong"
27863         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27864                 3 * $decay_pct) / 100") -eq 1 ] ||
27865                 error "write sample ($writesample1) is wrong"
27866         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27867                 20 * $decay_pct) / 100") -eq 1 ] ||
27868                 error "read bytes ($readbyte1) is wrong"
27869         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27870                 15 * $decay_pct) / 100") -eq 1 ] ||
27871                 error "write bytes ($writebyte1) is wrong"
27872
27873         echo "Turn off file heat for the file $DIR/$tfile"
27874         $LFS heat_set -o $DIR/$tfile
27875
27876         echo "QQQQ" > $DIR/$tfile
27877         echo "QQQQ" > $DIR/$tfile
27878         echo "QQQQ" > $DIR/$tfile
27879         cat $DIR/$tfile > /dev/null
27880         cat $DIR/$tfile > /dev/null
27881         cat $DIR/$tfile > /dev/null
27882         cat $DIR/$tfile > /dev/null
27883
27884         out=$($LFS heat_get $DIR/$tfile)
27885         $LFS heat_get $DIR/$tfile
27886         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27887         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27888         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27889         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27890
27891         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27892         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27893         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27894         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27895
27896         echo "Trun on file heat for the file $DIR/$tfile"
27897         $LFS heat_set -O $DIR/$tfile
27898
27899         echo "QQQQ" > $DIR/$tfile
27900         echo "QQQQ" > $DIR/$tfile
27901         echo "QQQQ" > $DIR/$tfile
27902         cat $DIR/$tfile > /dev/null
27903         cat $DIR/$tfile > /dev/null
27904         cat $DIR/$tfile > /dev/null
27905         cat $DIR/$tfile > /dev/null
27906
27907         out=$($LFS heat_get $DIR/$tfile)
27908         $LFS heat_get $DIR/$tfile
27909         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27910         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27911         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27912         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27913
27914         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27915         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27916         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27917         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27918
27919         $LFS heat_set -c $DIR/$tfile
27920         $LCTL set_param -n llite.*.file_heat=0
27921         echo "Turn off file heat support for the Lustre filesystem"
27922
27923         echo "QQQQ" > $DIR/$tfile
27924         echo "QQQQ" > $DIR/$tfile
27925         echo "QQQQ" > $DIR/$tfile
27926         cat $DIR/$tfile > /dev/null
27927         cat $DIR/$tfile > /dev/null
27928         cat $DIR/$tfile > /dev/null
27929         cat $DIR/$tfile > /dev/null
27930
27931         out=$($LFS heat_get $DIR/$tfile)
27932         $LFS heat_get $DIR/$tfile
27933         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27934         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27935         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27936         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27937
27938         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27939         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27940         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27941         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27942
27943         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27944         rm -f $DIR/$tfile
27945 }
27946 run_test 813 "File heat verfication"
27947
27948 test_814()
27949 {
27950         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27951         echo -n y >> $DIR/$tfile
27952         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27953         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27954 }
27955 run_test 814 "sparse cp works as expected (LU-12361)"
27956
27957 test_815()
27958 {
27959         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27960         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27961 }
27962 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27963
27964 test_816() {
27965         local ost1_imp=$(get_osc_import_name client ost1)
27966         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27967                          cut -d'.' -f2)
27968
27969         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27970         # ensure ost1 is connected
27971
27972         stat $DIR/$tfile >/dev/null || error "can't stat"
27973         wait_osc_import_state client ost1 FULL
27974         # no locks, no reqs to let the connection idle
27975         cancel_lru_locks osc
27976         lru_resize_disable osc
27977         local before
27978         local now
27979         before=$($LCTL get_param -n \
27980                  ldlm.namespaces.$imp_name.lru_size)
27981
27982         wait_osc_import_state client ost1 IDLE
27983         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27984         now=$($LCTL get_param -n \
27985               ldlm.namespaces.$imp_name.lru_size)
27986         [ $before == $now ] || error "lru_size changed $before != $now"
27987 }
27988 run_test 816 "do not reset lru_resize on idle reconnect"
27989
27990 cleanup_817() {
27991         umount $tmpdir
27992         exportfs -u localhost:$DIR/nfsexp
27993         rm -rf $DIR/nfsexp
27994 }
27995
27996 test_817() {
27997         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27998
27999         mkdir -p $DIR/nfsexp
28000         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28001                 error "failed to export nfs"
28002
28003         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28004         stack_trap cleanup_817 EXIT
28005
28006         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28007                 error "failed to mount nfs to $tmpdir"
28008
28009         cp /bin/true $tmpdir
28010         $DIR/nfsexp/true || error "failed to execute 'true' command"
28011 }
28012 run_test 817 "nfsd won't cache write lock for exec file"
28013
28014 test_818() {
28015         test_mkdir -i0 -c1 $DIR/$tdir
28016         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28017         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28018         stop $SINGLEMDS
28019
28020         # restore osp-syn threads
28021         stack_trap "fail $SINGLEMDS"
28022
28023         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28024         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28025         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28026                 error "start $SINGLEMDS failed"
28027         rm -rf $DIR/$tdir
28028
28029         local testid=$(echo $TESTNAME | tr '_' ' ')
28030
28031         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28032                 grep "run LFSCK" || error "run LFSCK is not suggested"
28033 }
28034 run_test 818 "unlink with failed llog"
28035
28036 test_819a() {
28037         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28038         cancel_lru_locks osc
28039         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28040         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28041         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28042         rm -f $TDIR/$tfile
28043 }
28044 run_test 819a "too big niobuf in read"
28045
28046 test_819b() {
28047         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28048         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28049         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28050         cancel_lru_locks osc
28051         sleep 1
28052         rm -f $TDIR/$tfile
28053 }
28054 run_test 819b "too big niobuf in write"
28055
28056
28057 function test_820_start_ost() {
28058         sleep 5
28059
28060         for num in $(seq $OSTCOUNT); do
28061                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28062         done
28063 }
28064
28065 test_820() {
28066         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28067
28068         mkdir $DIR/$tdir
28069         umount_client $MOUNT || error "umount failed"
28070         for num in $(seq $OSTCOUNT); do
28071                 stop ost$num
28072         done
28073
28074         # mount client with no active OSTs
28075         # so that the client can't initialize max LOV EA size
28076         # from OSC notifications
28077         mount_client $MOUNT || error "mount failed"
28078         # delay OST starting to keep this 0 max EA size for a while
28079         test_820_start_ost &
28080
28081         # create a directory on MDS2
28082         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28083                 error "Failed to create directory"
28084         # open intent should update default EA size
28085         # see mdc_update_max_ea_from_body()
28086         # notice this is the very first RPC to MDS2
28087         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28088         ret=$?
28089         echo $out
28090         # With SSK, this situation can lead to -EPERM being returned.
28091         # In that case, simply retry.
28092         if [ $ret -ne 0 ] && $SHARED_KEY; then
28093                 if echo "$out" | grep -q "not permitted"; then
28094                         cp /etc/services $DIR/$tdir/mds2
28095                         ret=$?
28096                 fi
28097         fi
28098         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28099 }
28100 run_test 820 "update max EA from open intent"
28101
28102 test_822() {
28103         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28104
28105         save_lustre_params mds1 \
28106                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28107         do_facet $SINGLEMDS "$LCTL set_param -n \
28108                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
28109         do_facet $SINGLEMDS "$LCTL set_param -n \
28110                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
28111
28112         # wait for statfs update to clear OS_STATFS_NOPRECREATE
28113         local maxage=$(do_facet mds1 $LCTL get_param -n \
28114                        osp.$FSNAME-OST0000*MDT0000.maxage)
28115         sleep $((maxage + 1))
28116
28117         #define OBD_FAIL_NET_ERROR_RPC          0x532
28118         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
28119
28120         stack_trap "restore_lustre_params < $p; rm $p"
28121
28122         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
28123                       osp.$FSNAME-OST0000*MDT0000.create_count")
28124         for i in $(seq 1 $count); do
28125                 touch $DIR/$tfile.${i} || error "touch failed"
28126         done
28127 }
28128 run_test 822 "test precreate failure"
28129
28130 test_823() {
28131         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28132         local OST_MAX_PRECREATE=20000
28133
28134         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28135                 skip "Need MDS version at least 2.14.56"
28136
28137         save_lustre_params mds1 \
28138                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28139         do_facet $SINGLEMDS "$LCTL set_param -n \
28140                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28141         do_facet $SINGLEMDS "$LCTL set_param -n \
28142                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28143
28144         stack_trap "restore_lustre_params < $p; rm $p"
28145
28146         do_facet $SINGLEMDS "$LCTL set_param -n \
28147                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28148
28149         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28150                       osp.$FSNAME-OST0000*MDT0000.create_count")
28151         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28152                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28153         local expect_count=$(((($max/2)/256) * 256))
28154
28155         log "setting create_count to 100200:"
28156         log " -result- count: $count with max: $max, expecting: $expect_count"
28157
28158         [[ $count -eq expect_count ]] ||
28159                 error "Create count not set to max precreate."
28160 }
28161 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28162
28163 test_831() {
28164         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28165                 skip "Need MDS version 2.14.56"
28166
28167         local sync_changes=$(do_facet $SINGLEMDS \
28168                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28169
28170         [ "$sync_changes" -gt 100 ] &&
28171                 skip "Sync changes $sync_changes > 100 already"
28172
28173         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28174
28175         $LFS mkdir -i 0 $DIR/$tdir
28176         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28177
28178         save_lustre_params mds1 \
28179                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28180         save_lustre_params mds1 \
28181                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28182
28183         do_facet mds1 "$LCTL set_param -n \
28184                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28185                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28186         stack_trap "restore_lustre_params < $p" EXIT
28187
28188         createmany -o $DIR/$tdir/f- 1000
28189         unlinkmany $DIR/$tdir/f- 1000 &
28190         local UNLINK_PID=$!
28191
28192         while sleep 1; do
28193                 sync_changes=$(do_facet mds1 \
28194                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28195                 # the check in the code is racy, fail the test
28196                 # if the value above the limit by 10.
28197                 [ $sync_changes -gt 110 ] && {
28198                         kill -2 $UNLINK_PID
28199                         wait
28200                         error "osp changes throttling failed, $sync_changes>110"
28201                 }
28202                 kill -0 $UNLINK_PID 2> /dev/null || break
28203         done
28204         wait
28205 }
28206 run_test 831 "throttling unlink/setattr queuing on OSP"
28207
28208 #
28209 # tests that do cleanup/setup should be run at the end
28210 #
28211
28212 test_900() {
28213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28214         local ls
28215
28216         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28217         $LCTL set_param fail_loc=0x903
28218
28219         cancel_lru_locks MGC
28220
28221         FAIL_ON_ERROR=true cleanup
28222         FAIL_ON_ERROR=true setup
28223 }
28224 run_test 900 "umount should not race with any mgc requeue thread"
28225
28226 # LUS-6253/LU-11185
28227 test_901() {
28228         local old
28229         local count
28230         local oldc
28231         local newc
28232         local olds
28233         local news
28234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28235
28236         # some get_param have a bug to handle dot in param name
28237         cancel_lru_locks MGC
28238         old=$(mount -t lustre | wc -l)
28239         # 1 config+sptlrpc
28240         # 2 params
28241         # 3 nodemap
28242         # 4 IR
28243         old=$((old * 4))
28244         oldc=0
28245         count=0
28246         while [ $old -ne $oldc ]; do
28247                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28248                 sleep 1
28249                 ((count++))
28250                 if [ $count -ge $TIMEOUT ]; then
28251                         error "too large timeout"
28252                 fi
28253         done
28254         umount_client $MOUNT || error "umount failed"
28255         mount_client $MOUNT || error "mount failed"
28256         cancel_lru_locks MGC
28257         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28258
28259         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28260
28261         return 0
28262 }
28263 run_test 901 "don't leak a mgc lock on client umount"
28264
28265 # LU-13377
28266 test_902() {
28267         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28268                 skip "client does not have LU-13377 fix"
28269         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28270         $LCTL set_param fail_loc=0x1415
28271         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28272         cancel_lru_locks osc
28273         rm -f $DIR/$tfile
28274 }
28275 run_test 902 "test short write doesn't hang lustre"
28276
28277 # LU-14711
28278 test_903() {
28279         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28280         echo "blah" > $DIR/${tfile}-2
28281         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28282         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28283         $LCTL set_param fail_loc=0x417 fail_val=20
28284
28285         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28286         sleep 1 # To start the destroy
28287         wait_destroy_complete 150 || error "Destroy taking too long"
28288         cat $DIR/$tfile > /dev/null || error "Evicted"
28289 }
28290 run_test 903 "Test long page discard does not cause evictions"
28291
28292 test_904() {
28293         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28294         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28295                 grep -q project || skip "skip project quota not supported"
28296
28297         local testfile="$DIR/$tdir/$tfile"
28298         local xattr="trusted.projid"
28299         local projid
28300         local mdts=$(comma_list $(mdts_nodes))
28301         local saved=$(do_facet mds1 $LCTL get_param -n \
28302                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28303
28304         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28305         stack_trap "do_nodes $mdts $LCTL set_param \
28306                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28307
28308         mkdir -p $DIR/$tdir
28309         touch $testfile
28310         #hide projid xattr on server
28311         $LFS project -p 1 $testfile ||
28312                 error "set $testfile project id failed"
28313         getfattr -m - $testfile | grep $xattr &&
28314                 error "do not show trusted.projid when disabled on server"
28315         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28316         #should be hidden when projid is 0
28317         $LFS project -p 0 $testfile ||
28318                 error "set $testfile project id failed"
28319         getfattr -m - $testfile | grep $xattr &&
28320                 error "do not show trusted.projid with project ID 0"
28321
28322         #still can getxattr explicitly
28323         projid=$(getfattr -n $xattr $testfile |
28324                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28325         [ $projid == "0" ] ||
28326                 error "projid expected 0 not $projid"
28327
28328         #set the projid via setxattr
28329         setfattr -n $xattr -v "1000" $testfile ||
28330                 error "setattr failed with $?"
28331         projid=($($LFS project $testfile))
28332         [ ${projid[0]} == "1000" ] ||
28333                 error "projid expected 1000 not $projid"
28334
28335         #check the new projid via getxattr
28336         $LFS project -p 1001 $testfile ||
28337                 error "set $testfile project id failed"
28338         getfattr -m - $testfile | grep $xattr ||
28339                 error "should show trusted.projid when project ID != 0"
28340         projid=$(getfattr -n $xattr $testfile |
28341                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28342         [ $projid == "1001" ] ||
28343                 error "projid expected 1001 not $projid"
28344
28345         #try to set invalid projid
28346         setfattr -n $xattr -v "4294967295" $testfile &&
28347                 error "set invalid projid should fail"
28348
28349         #remove the xattr means setting projid to 0
28350         setfattr -x $xattr $testfile ||
28351                 error "setfattr failed with $?"
28352         projid=($($LFS project $testfile))
28353         [ ${projid[0]} == "0" ] ||
28354                 error "projid expected 0 not $projid"
28355
28356         #should be hidden when parent has inherit flag and same projid
28357         $LFS project -srp 1002 $DIR/$tdir ||
28358                 error "set $tdir project id failed"
28359         getfattr -m - $testfile | grep $xattr &&
28360                 error "do not show trusted.projid with inherit flag"
28361
28362         #still can getxattr explicitly
28363         projid=$(getfattr -n $xattr $testfile |
28364                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28365         [ $projid == "1002" ] ||
28366                 error "projid expected 1002 not $projid"
28367 }
28368 run_test 904 "virtual project ID xattr"
28369
28370 complete $SECONDS
28371 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28372 check_and_cleanup_lustre
28373 if [ "$I_MOUNTED" != "yes" ]; then
28374         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28375 fi
28376 exit_status